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

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
14 changes: 14 additions & 0 deletions dotnet/src/webdriver/BiDi/BiDi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public sealed class BiDi : IAsyncDisposable
private Script.ScriptModule? _scriptModule;
private Log.LogModule? _logModule;
private Storage.StorageModule? _storageModule;
private WebExtension.WebExtensionModule? _webExtensionModule;

private readonly object _moduleLock = new();

Expand Down Expand Up @@ -150,6 +151,19 @@ public Storage.StorageModule Storage
}
}

public WebExtension.WebExtensionModule WebExtension
{
get
{
if (_webExtensionModule is not null) return _webExtensionModule;
lock (_moduleLock)
{
_webExtensionModule ??= new WebExtension.WebExtensionModule(_broker);
}
return _webExtensionModule;
}
}

public Task<Session.StatusResult> StatusAsync()
{
return SessionModule.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(InstallParameters @params)
: Command<InstallParameters, InstallResult>(@params, "webExtension.install");

internal sealed record InstallParameters(ExtensionData ExtensionData) : Parameters;

[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 class 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(UninstallParameters @params)
: Command<UninstallParameters, EmptyResult>(@params, "webExtension.uninstall");

internal sealed record UninstallParameters(Extension Extension) : Parameters;

public sealed class 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 InstallParameters(extensionData);

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

public async Task<EmptyResult> UninstallAsync(Extension extension, UninstallOptions? options = null)
{
var @params = new UninstallParameters(extension);

return await Broker.ExecuteCommandAsync<UninstallCommand, EmptyResult>(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
96 changes: 96 additions & 0 deletions dotnet/test/common/BiDi/WebExtension/WebExtensionTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// <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;

[Ignore("""
The following test suite wants to set driver arguments via Options, but it breaks CDP/DevTools tests.
The desired arguments (for Chromium only?):
--enable-unsafe-extension-debugging
--remote-debugging-pipe
Ignoring these tests for now. Hopefully https://github.com/SeleniumHQ/selenium/issues/15536 will be resolved soon.
""")]
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: 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