Skip to content
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions common/extensions/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ filegroup(
"**/*",
]),
visibility = [
"//dotnet/test/common:__pkg__",
"//java/test/org/openqa/selenium/chrome:__pkg__",
"//java/test/org/openqa/selenium/edge:__pkg__",
"//java/test/org/openqa/selenium/environment:__pkg__",
Expand Down
3 changes: 3 additions & 0 deletions dotnet/src/webdriver/BiDi/BiDi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public class BiDi : IAsyncDisposable
private readonly Lazy<Script.ScriptModule> _scriptModule;
private readonly Lazy<Log.LogModule> _logModule;
private readonly Lazy<Storage.StorageModule> _storageModule;
private readonly Lazy<WebExtension.WebExtensionModule> _webExtensionModule;

internal BiDi(string url)
{
Expand All @@ -50,6 +51,7 @@ internal BiDi(string url)
_scriptModule = new Lazy<Script.ScriptModule>(() => new Script.ScriptModule(_broker));
_logModule = new Lazy<Log.LogModule>(() => new Log.LogModule(_broker));
_storageModule = new Lazy<Storage.StorageModule>(() => new Storage.StorageModule(_broker));
_webExtensionModule = new Lazy<WebExtension.WebExtensionModule>(() => new WebExtension.WebExtensionModule(_broker));
}

internal Session.SessionModule SessionModule => _sessionModule.Value;
Expand All @@ -60,6 +62,7 @@ internal BiDi(string url)
public Script.ScriptModule Script => _scriptModule.Value;
public Log.LogModule Log => _logModule.Value;
public Storage.StorageModule Storage => _storageModule.Value;
public WebExtension.WebExtensionModule WebExtension => _webExtensionModule.Value;

public Task<Session.StatusResult> StatusAsync()
{
Expand Down
1 change: 1 addition & 0 deletions dotnet/src/webdriver/BiDi/Communication/Broker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ internal Broker(BiDi bidi, Uri url)
new DateTimeOffsetConverter(),
new PrintPageRangeConverter(),
new InputOriginConverter(),
new WebExtensionConverter(_bidi),
new SubscriptionConverter(),
new JsonStringEnumConverter(JsonNamingPolicy.CamelCase),

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,4 +165,8 @@ namespace OpenQA.Selenium.BiDi.Communication.Json;
[JsonSerializable(typeof(IEnumerable<Input.INoneSourceAction>))]
[JsonSerializable(typeof(IEnumerable<Input.IWheelSourceAction>))]

[JsonSerializable(typeof(WebExtension.InstallCommand))]
[JsonSerializable(typeof(WebExtension.InstallResult))]
[JsonSerializable(typeof(WebExtension.UninstallCommand))]

internal partial class BiDiJsonSerializerContext : JsonSerializerContext;
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// <copyright file="WebExtensionConverter.cs" company="Selenium Committers">
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
// </copyright>

using OpenQA.Selenium.BiDi.WebExtension;
using System;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace OpenQA.Selenium.BiDi.Communication.Json.Converters;

internal class WebExtensionConverter : JsonConverter<Extension>
{
private readonly BiDi _bidi;

public WebExtensionConverter(BiDi bidi)
{
_bidi = bidi;
}

public override Extension? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var id = reader.GetString();

return new Extension(_bidi, id!);
}

public override void Write(Utf8JsonWriter writer, Extension value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.Id);
}
}
40 changes: 40 additions & 0 deletions dotnet/src/webdriver/BiDi/WebExtension/Extension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// <copyright file="Extension.cs" company="Selenium Committers">
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
// </copyright>

using System.Threading.Tasks;

namespace OpenQA.Selenium.BiDi.WebExtension;

public sealed class Extension
{
private readonly BiDi _bidi;

public Extension(BiDi bidi, string id)
{
_bidi = bidi;
Id = id;
}

internal string Id { get; }

public Task UninstallAsync(UninstallOptions? options = null)
{
return _bidi.WebExtension.UninstallAsync(this, options);
}
}
44 changes: 44 additions & 0 deletions dotnet/src/webdriver/BiDi/WebExtension/InstallCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// <copyright file="InstallCommand.cs" company="Selenium Committers">
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
// </copyright>

using OpenQA.Selenium.BiDi.Communication;
using System.Text.Json.Serialization;

namespace OpenQA.Selenium.BiDi.WebExtension;

internal sealed class InstallCommand(InstallCommandParameters @params)
: Command<InstallCommandParameters, InstallResult>(@params, "webExtension.install");

internal sealed record InstallCommandParameters(ExtensionData ExtensionData) : CommandParameters;

[JsonPolymorphic(TypeDiscriminatorPropertyName = "type")]
[JsonDerivedType(typeof(ExtensionArchivePath), "archivePath")]
[JsonDerivedType(typeof(ExtensionBase64Encoded), "base64")]
[JsonDerivedType(typeof(ExtensionPath), "path")]
public abstract record ExtensionData;

public sealed record ExtensionArchivePath(string Path) : ExtensionData;

public sealed record ExtensionBase64Encoded(string Value) : ExtensionData;

public sealed record ExtensionPath(string Path) : ExtensionData;

public sealed record InstallOptions : CommandOptions;

public sealed record InstallResult(Extension Extension) : EmptyResult;
29 changes: 29 additions & 0 deletions dotnet/src/webdriver/BiDi/WebExtension/UninstallCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// <copyright file="UninstallCommand.cs" company="Selenium Committers">
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
// </copyright>

using OpenQA.Selenium.BiDi.Communication;

namespace OpenQA.Selenium.BiDi.WebExtension;

internal sealed class UninstallCommand(UninstallCommandParameters @params)
: Command<UninstallCommandParameters, EmptyResult>(@params, "webExtension.uninstall");

internal sealed record UninstallCommandParameters(Extension Extension) : CommandParameters;

public sealed record UninstallOptions : CommandOptions;
40 changes: 40 additions & 0 deletions dotnet/src/webdriver/BiDi/WebExtension/WebExtensionModule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// <copyright file="WebExtensionModule.cs" company="Selenium Committers">
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
// </copyright>

using OpenQA.Selenium.BiDi.Communication;
using System.Threading.Tasks;

namespace OpenQA.Selenium.BiDi.WebExtension;

public sealed class WebExtensionModule(Broker broker) : Module(broker)
{
public async Task<InstallResult> InstallAsync(ExtensionData extensionData, InstallOptions? options = null)
{
var @params = new InstallCommandParameters(extensionData);

return await Broker.ExecuteCommandAsync<InstallCommand, InstallResult>(new InstallCommand(@params), options).ConfigureAwait(false);
}

internal async Task UninstallAsync(Extension extension, UninstallOptions? options = null)
{
var @params = new UninstallCommandParameters(extension);

await Broker.ExecuteCommandAsync(new UninstallCommand(@params), options).ConfigureAwait(false);
}
}
1 change: 1 addition & 0 deletions dotnet/test/common/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ filegroup(
srcs = [],
data = [
"appconfig.json",
"//common/extensions",
"//common/src/web",
"//dotnet/src/webdriver:manager-linux",
"//dotnet/src/webdriver:manager-macos",
Expand Down
89 changes: 89 additions & 0 deletions dotnet/test/common/BiDi/WebExtension/WebExtensionTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// <copyright file="WebExtensionTest.cs" company="Selenium Committers">
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
// </copyright>

using NUnit.Framework;
using System;
using System.IO;
using System.Threading.Tasks;

namespace OpenQA.Selenium.BiDi.WebExtension;

class WebExtensionTest : BiDiTestFixture
{
[Test]
public async Task CanInstallPathWebExtension()
{
string path = Path.GetFullPath("common/extensions/webextensions-selenium-example");

var result = await bidi.WebExtension.InstallAsync(new ExtensionPath(path));

Assert.That(result, Is.Not.Null);
Assert.That(result.Extension, Is.Not.Null);
}

[Test]
[IgnoreBrowser(Selenium.Browser.Chrome, "Archived and Base64 extensions are not supported?")]
[IgnoreBrowser(Selenium.Browser.Edge, "Archived and Base64 extensions are not supported?")]
public async Task CanInstallArchiveWebExtension()
{
string path = LocateRelativePath("common/extensions/webextensions-selenium-example.zip");

var result = await bidi.WebExtension.InstallAsync(new ExtensionArchivePath(path));

Assert.That(result, Is.Not.Null);
Assert.That(result.Extension, Is.Not.Null);
}

[Test]
[IgnoreBrowser(Selenium.Browser.Chrome, "Archived and Base64 extensions are not supported?")]
[IgnoreBrowser(Selenium.Browser.Edge, "Archived and Base64 extensions are not supported?")]
public async Task CanInstallBase64WebExtension()
{
var path = LocateRelativePath("common/extensions/webextensions-selenium-example.zip");

string base64 = Convert.ToBase64String(File.ReadAllBytes(path));

var result = await bidi.WebExtension.InstallAsync(new ExtensionBase64Encoded(base64));

Assert.That(result, Is.Not.Null);
Assert.That(result.Extension, Is.Not.Null);
}

[Test]
public async Task CanUninstallExtension()
{
string path = LocateRelativePath("common/extensions/webextensions-selenium-example");

var result = await bidi.WebExtension.InstallAsync(new ExtensionPath(path));

await result.Extension.UninstallAsync();
}

private static string LocateRelativePath(string path)
{
try
{
return Bazel.Runfiles.Create().Rlocation($"_main/{path}");
}
catch (FileNotFoundException)
{
return Path.GetFullPath(path);
}
}
}
4 changes: 2 additions & 2 deletions dotnet/test/common/Environment/DriverFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public IWebDriver CreateDriverWithOptions(Type driverType, DriverOptions driverO
options = GetDriverOptions<ChromeOptions>(driverType, driverOptions);

var chromeOptions = (ChromeOptions)options;
chromeOptions.AddArguments("--no-sandbox", "--disable-dev-shm-usage");
chromeOptions.AddArguments("--no-sandbox", "--disable-dev-shm-usage", "--remote-debugging-pipe", "--enable-unsafe-extension-debugging");

service = CreateService<ChromeDriverService>();
if (!string.IsNullOrEmpty(this.browserBinaryLocation))
Expand All @@ -104,7 +104,7 @@ public IWebDriver CreateDriverWithOptions(Type driverType, DriverOptions driverO
options = GetDriverOptions<EdgeOptions>(driverType, driverOptions);

var edgeOptions = (EdgeOptions)options;
edgeOptions.AddArguments("--no-sandbox", "--disable-dev-shm-usage");
edgeOptions.AddArguments("--no-sandbox", "--disable-dev-shm-usage", "--remote-debugging-pipe", "--enable-unsafe-extension-debugging");

service = CreateService<EdgeDriverService>();
if (!string.IsNullOrEmpty(this.browserBinaryLocation))
Expand Down
4 changes: 4 additions & 0 deletions dotnet/test/common/Selenium.WebDriver.Common.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@
<None Update="appconfig.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\..\common\extensions\**">
<Link>common\extensions\%(RecursiveDir)%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

<Target Name="BuildTestWebServer" AfterTargets="AfterBuild">
Expand Down
Loading