diff --git a/dotnet/src/webdriver/BiDi/BiDi.cs b/dotnet/src/webdriver/BiDi/BiDi.cs index 448e0ea85bf48..d88105b7ca9a2 100644 --- a/dotnet/src/webdriver/BiDi/BiDi.cs +++ b/dotnet/src/webdriver/BiDi/BiDi.cs @@ -30,15 +30,13 @@ namespace OpenQA.Selenium.BiDi; public sealed class BiDi : IAsyncDisposable { - private readonly Broker _broker; - private readonly JsonSerializerOptions _jsonOptions; + internal Broker Broker { get; } + internal JsonSerializerOptions JsonOptions { get; } private readonly BiDiJsonSerializerContext _jsonContext; - private BiDi(string url) + public JsonSerializerOptions DefaultBiDiOptions() { - var uri = new Uri(url); - - _jsonOptions = new JsonSerializerOptions + return new JsonSerializerOptions { PropertyNameCaseInsensitive = true, PropertyNamingPolicy = JsonNamingPolicy.CamelCase, @@ -61,20 +59,27 @@ private BiDi(string url) new WebExtensionConverter(this), } }; + } + + private BiDi(string url) + { + var uri = new Uri(url); - _jsonContext = new BiDiJsonSerializerContext(_jsonOptions); - - _broker = new Broker(this, uri, _jsonOptions); - SessionModule = Module.Create(this, _broker, _jsonOptions, _jsonContext); - BrowsingContext = Module.Create(this, _broker, _jsonOptions, _jsonContext); - Browser = Module.Create(this, _broker, _jsonOptions, _jsonContext); - Network = Module.Create(this, _broker, _jsonOptions, _jsonContext); - InputModule = Module.Create(this, _broker, _jsonOptions, _jsonContext); - Script = Module.Create(this, _broker, _jsonOptions, _jsonContext); - Log = Module.Create(this, _broker, _jsonOptions, _jsonContext); - Storage = Module.Create(this, _broker, _jsonOptions, _jsonContext); - WebExtension = Module.Create(this, _broker, _jsonOptions, _jsonContext); - Emulation = Module.Create(this, _broker, _jsonOptions, _jsonContext); + JsonOptions = DefaultBiDiOptions(); + + _jsonContext = new BiDiJsonSerializerContext(JsonOptions); + + Broker = new Broker(this, uri, JsonOptions); + SessionModule = Module.Create(this, JsonOptions, _jsonContext); + BrowsingContext = Module.Create(this, JsonOptions, _jsonContext); + Browser = Module.Create(this, JsonOptions, _jsonContext); + Network = Module.Create(this, JsonOptions, _jsonContext); + InputModule = Module.Create(this, JsonOptions, _jsonContext); + Script = Module.Create(this, JsonOptions, _jsonContext); + Log = Module.Create(this, JsonOptions, _jsonContext); + Storage = Module.Create(this, JsonOptions, _jsonContext); + WebExtension = Module.Create(this, JsonOptions, _jsonContext); + Emulation = Module.Create(this, JsonOptions, _jsonContext); } internal Session.SessionModule SessionModule { get; } @@ -106,7 +111,7 @@ public static async Task ConnectAsync(string url, BiDiOptions? options = n { var bidi = new BiDi(url); - await bidi._broker.ConnectAsync(CancellationToken.None).ConfigureAwait(false); + await bidi.Broker.ConnectAsync(CancellationToken.None).ConfigureAwait(false); return bidi; } @@ -118,7 +123,7 @@ public Task EndAsync(Session.EndOptions? options = null) public async ValueTask DisposeAsync() { - await _broker.DisposeAsync().ConfigureAwait(false); + await Broker.DisposeAsync().ConfigureAwait(false); GC.SuppressFinalize(this); } } diff --git a/dotnet/src/webdriver/BiDi/Browser/BrowserModule.cs b/dotnet/src/webdriver/BiDi/Browser/BrowserModule.cs index 61c5ce4008f05..c41ab1426dd7e 100644 --- a/dotnet/src/webdriver/BiDi/Browser/BrowserModule.cs +++ b/dotnet/src/webdriver/BiDi/Browser/BrowserModule.cs @@ -18,12 +18,17 @@ // using OpenQA.Selenium.BiDi.Communication; +using OpenQA.Selenium.BiDi.Communication.Json; +using System.Text.Json; +using System.Text.Json.Serialization; using System.Threading.Tasks; namespace OpenQA.Selenium.BiDi.Browser; public sealed class BrowserModule : Module { + internal new BiDiJsonSerializerContext JsonContext => (BiDiJsonSerializerContext)base.JsonContext; + public async Task CloseAsync(CloseOptions? options = null) { return await Broker.ExecuteCommandAsync(new CloseCommand(), options, JsonContext.Browser_CloseCommand, JsonContext.Browser_CloseResult).ConfigureAwait(false); @@ -74,4 +79,8 @@ public async Task SetDownloadBehaviorDeniedAsync(SetD return await Broker.ExecuteCommandAsync(new SetDownloadBehaviorCommand(@params), options, JsonContext.SetDownloadBehaviorCommand, JsonContext.SetDownloadBehaviorResult).ConfigureAwait(false); } + protected override JsonSerializerContext Initialize(JsonSerializerOptions options) + { + return new BiDiJsonSerializerContext(options); + } } diff --git a/dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContextModule.cs b/dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContextModule.cs index f50d23085da40..c2c609738061e 100644 --- a/dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContextModule.cs +++ b/dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContextModule.cs @@ -17,14 +17,19 @@ // under the License. // +using OpenQA.Selenium.BiDi.Communication; +using OpenQA.Selenium.BiDi.Communication.Json; using System; +using System.Text.Json; +using System.Text.Json.Serialization; using System.Threading.Tasks; -using OpenQA.Selenium.BiDi.Communication; namespace OpenQA.Selenium.BiDi.BrowsingContext; public sealed class BrowsingContextModule : Module { + internal new BiDiJsonSerializerContext JsonContext => (BiDiJsonSerializerContext)base.JsonContext; + public async Task CreateAsync(ContextType type, CreateOptions? options = null) { var @params = new CreateParameters(type, options?.ReferenceContext, options?.Background, options?.UserContext); @@ -248,4 +253,8 @@ public async Task OnUserPromptClosedAsync(Action -using System.Threading.Tasks; using OpenQA.Selenium.BiDi.Communication; +using OpenQA.Selenium.BiDi.Communication.Json; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.Threading.Tasks; namespace OpenQA.Selenium.BiDi.Emulation; public sealed class EmulationModule : Module { + internal new BiDiJsonSerializerContext JsonContext => (BiDiJsonSerializerContext)base.JsonContext; + public async Task SetTimezoneOverrideAsync(string? timezone, SetTimezoneOverrideOptions? options = null) { var @params = new SetTimezoneOverrideParameters(timezone, options?.Contexts, options?.UserContexts); @@ -88,4 +93,8 @@ public async Task SetGeolocationPositionErrorOverr return await Broker.ExecuteCommandAsync(new SetGeolocationOverrideCommand(@params), options, JsonContext.SetGeolocationOverrideCommand, JsonContext.SetGeolocationOverrideResult).ConfigureAwait(false); } + protected override JsonSerializerContext Initialize(JsonSerializerOptions options) + { + return new BiDiJsonSerializerContext(options); + } } diff --git a/dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionDescriptor.cs b/dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionDescriptor.cs new file mode 100644 index 0000000000000..8523515a8a748 --- /dev/null +++ b/dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionDescriptor.cs @@ -0,0 +1,22 @@ +// +// 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. +// + +namespace OpenQA.Selenium.BiDi.Extensions.Permissions; + +internal record PermissionDescriptor(string Name); diff --git a/dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionState.cs b/dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionState.cs new file mode 100644 index 0000000000000..3707011bdec22 --- /dev/null +++ b/dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionState.cs @@ -0,0 +1,31 @@ +// +// 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. +// + +using OpenQA.Selenium.BiDi.Communication.Json.Converters; +using System.Text.Json.Serialization; + +namespace OpenQA.Selenium.BiDi.Extensions.Permissions; + +[JsonConverter(typeof(CamelCaseEnumConverter))] +public enum PermissionState +{ + Granted, + Denied, + Prompt +} diff --git a/dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionsModule.cs b/dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionsModule.cs new file mode 100644 index 0000000000000..2bcea8262d379 --- /dev/null +++ b/dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionsModule.cs @@ -0,0 +1,29 @@ +using OpenQA.Selenium.BiDi.Browser; +using OpenQA.Selenium.BiDi.Communication; +using OpenQA.Selenium.BiDi.Communication.Json.Converters; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace OpenQA.Selenium.BiDi.Extensions.Permissions; + +public class PermissionsModule : Module +{ + private PermissionsJsonSerializerContext JsonContext => (PermissionsJsonSerializerContext)base.JsonContext; + + public async Task SetPermissionAsync(string permissionName, PermissionState state, string origin, UserContext? userContext, SetPermissionOptions? options = null) + { + var @params = new SetPermissionCommandParameters(new PermissionDescriptor(permissionName), state, origin, userContext); + + await Broker.ExecuteCommandAsync(new SetPermissionCommand(@params), options, JsonContext.Permissions_SetPermissionCommand, JsonContext.Permissions_SetPermissionResult).ConfigureAwait(false); + } + + protected override JsonSerializerContext Initialize(JsonSerializerOptions options) + { + return new PermissionsJsonSerializerContext(options); + } +} + +[JsonSerializable(typeof(SetPermissionCommand), TypeInfoPropertyName = "Permissions_SetPermissionCommand")] +[JsonSerializable(typeof(SetPermissionResult), TypeInfoPropertyName = "Permissions_SetPermissionResult")] +internal partial class PermissionsJsonSerializerContext : JsonSerializerContext; diff --git a/dotnet/src/webdriver/BiDi/Extensions/Permissions/SetPermissionCommand.cs b/dotnet/src/webdriver/BiDi/Extensions/Permissions/SetPermissionCommand.cs new file mode 100644 index 0000000000000..dac45688cc8c5 --- /dev/null +++ b/dotnet/src/webdriver/BiDi/Extensions/Permissions/SetPermissionCommand.cs @@ -0,0 +1,17 @@ +using OpenQA.Selenium.BiDi.Browser; +using OpenQA.Selenium.BiDi.Communication; +using OpenQA.Selenium.BiDi.Communication.Json.Converters; +using System; +using System.Collections.Generic; +using System.Text; +using System.Text.Json.Serialization; + +namespace OpenQA.Selenium.BiDi.Extensions.Permissions; + +internal class SetPermissionCommand(SetPermissionCommandParameters @params) + : Command(@params, "permissions.setPermission"); + +public class SetPermissionOptions : CommandOptions; +public sealed record SetPermissionResult : EmptyResult; + +internal record SetPermissionCommandParameters(PermissionDescriptor Descriptor, PermissionState State, string Origin, UserContext? UserContext) : Parameters; diff --git a/dotnet/src/webdriver/BiDi/Input/InputModule.cs b/dotnet/src/webdriver/BiDi/Input/InputModule.cs index 8d2662caa035a..73fe2e124bc97 100644 --- a/dotnet/src/webdriver/BiDi/Input/InputModule.cs +++ b/dotnet/src/webdriver/BiDi/Input/InputModule.cs @@ -18,13 +18,18 @@ // using OpenQA.Selenium.BiDi.Communication; +using OpenQA.Selenium.BiDi.Communication.Json; using System.Collections.Generic; +using System.Text.Json; +using System.Text.Json.Serialization; using System.Threading.Tasks; namespace OpenQA.Selenium.BiDi.Input; public sealed class InputModule : Module { + internal new BiDiJsonSerializerContext JsonContext => (BiDiJsonSerializerContext)base.JsonContext; + public async Task PerformActionsAsync(BrowsingContext.BrowsingContext context, IEnumerable actions, PerformActionsOptions? options = null) { var @params = new PerformActionsParameters(context, actions); @@ -45,4 +50,8 @@ public async Task SetFilesAsync(BrowsingContext.BrowsingContext return await Broker.ExecuteCommandAsync(new SetFilesCommand(@params), options, JsonContext.SetFilesCommand, JsonContext.SetFilesResult).ConfigureAwait(false); } + protected override JsonSerializerContext Initialize(JsonSerializerOptions options) + { + return new BiDiJsonSerializerContext(options); + } } diff --git a/dotnet/src/webdriver/BiDi/Log/LogModule.cs b/dotnet/src/webdriver/BiDi/Log/LogModule.cs index a3887d7f052cf..90c6868b60a82 100644 --- a/dotnet/src/webdriver/BiDi/Log/LogModule.cs +++ b/dotnet/src/webdriver/BiDi/Log/LogModule.cs @@ -17,14 +17,19 @@ // under the License. // -using System.Threading.Tasks; -using System; using OpenQA.Selenium.BiDi.Communication; +using OpenQA.Selenium.BiDi.Communication.Json; +using System; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.Threading.Tasks; namespace OpenQA.Selenium.BiDi.Log; public sealed class LogModule : Module { + internal new BiDiJsonSerializerContext JsonContext => (BiDiJsonSerializerContext)base.JsonContext; + public async Task OnEntryAddedAsync(Func handler, SubscriptionOptions? options = null) { return await Broker.SubscribeAsync("log.entryAdded", handler, options, JsonContext.LogEntry).ConfigureAwait(false); @@ -34,4 +39,8 @@ public async Task OnEntryAddedAsync(Action handler, Subs { return await Broker.SubscribeAsync("log.entryAdded", handler, options, JsonContext.LogEntry).ConfigureAwait(false); } + protected override JsonSerializerContext Initialize(JsonSerializerOptions options) + { + return new BiDiJsonSerializerContext(options); + } } diff --git a/dotnet/src/webdriver/BiDi/Module.cs b/dotnet/src/webdriver/BiDi/Module.cs index 202bc30bbcd75..70a2b829d5019 100644 --- a/dotnet/src/webdriver/BiDi/Module.cs +++ b/dotnet/src/webdriver/BiDi/Module.cs @@ -18,8 +18,8 @@ // using OpenQA.Selenium.BiDi.Communication; -using OpenQA.Selenium.BiDi.Communication.Json; using System.Text.Json; +using System.Text.Json.Serialization; namespace OpenQA.Selenium.BiDi; @@ -27,20 +27,19 @@ public abstract class Module { protected Broker Broker { get; private set; } - internal BiDiJsonSerializerContext JsonContext { get; private set; } + internal JsonSerializerContext JsonContext { get; private set; } - protected virtual void Initialize(JsonSerializerOptions options) { } + protected abstract JsonSerializerContext Initialize(JsonSerializerOptions options); - internal static TModule Create(BiDi bidi, Broker broker, JsonSerializerOptions jsonOptions, BiDiJsonSerializerContext context) + public static TModule Create(BiDi bidi, JsonSerializerOptions jsonOptions, JsonSerializerContext? cachedContext = null) where TModule : Module, new() { TModule module = new() { - Broker = broker, - JsonContext = context + Broker = bidi.Broker, }; - module.Initialize(jsonOptions); + module.JsonContext = cachedContext ?? module.Initialize(jsonOptions); return module; } diff --git a/dotnet/src/webdriver/BiDi/Network/NetworkModule.cs b/dotnet/src/webdriver/BiDi/Network/NetworkModule.cs index 4242f8515bab9..599c4e6b8e2d4 100644 --- a/dotnet/src/webdriver/BiDi/Network/NetworkModule.cs +++ b/dotnet/src/webdriver/BiDi/Network/NetworkModule.cs @@ -17,15 +17,20 @@ // under the License. // +using OpenQA.Selenium.BiDi.Communication; +using OpenQA.Selenium.BiDi.Communication.Json; using System; using System.Collections.Generic; +using System.Text.Json; +using System.Text.Json.Serialization; using System.Threading.Tasks; -using OpenQA.Selenium.BiDi.Communication; namespace OpenQA.Selenium.BiDi.Network; public sealed partial class NetworkModule : Module { + internal new BiDiJsonSerializerContext JsonContext => (BiDiJsonSerializerContext)base.JsonContext; + public async Task AddDataCollectorAsync(IEnumerable DataTypes, int MaxEncodedDataSize, AddDataCollectorOptions? options = null) { var @params = new AddDataCollectorParameters(DataTypes, MaxEncodedDataSize, options?.CollectorType, options?.Contexts, options?.UserContexts); @@ -173,4 +178,8 @@ public async Task OnAuthRequiredAsync(Action using OpenQA.Selenium.BiDi.Communication; +using OpenQA.Selenium.BiDi.Communication.Json; using System; using System.Collections.Generic; +using System.Text.Json; +using System.Text.Json.Serialization; using System.Threading.Tasks; namespace OpenQA.Selenium.BiDi.Script; public sealed class ScriptModule : Module { + internal new BiDiJsonSerializerContext JsonContext => (BiDiJsonSerializerContext)base.JsonContext; + public async Task EvaluateAsync(string expression, bool awaitPromise, Target target, EvaluateOptions? options = null) { var @params = new EvaluateParameters(expression, target, awaitPromise, options?.ResultOwnership, options?.SerializationOptions, options?.UserActivation); @@ -111,4 +116,8 @@ public async Task OnRealmDestroyedAsync(Action using OpenQA.Selenium.BiDi.Communication; +using OpenQA.Selenium.BiDi.Communication.Json; using System.Collections.Generic; +using System.Text.Json; +using System.Text.Json.Serialization; using System.Threading.Tasks; namespace OpenQA.Selenium.BiDi.Session; internal sealed class SessionModule : Module { + internal new BiDiJsonSerializerContext JsonContext => (BiDiJsonSerializerContext)base.JsonContext; + public async Task StatusAsync(StatusOptions? options = null) { return await Broker.ExecuteCommandAsync(new StatusCommand(), options, JsonContext.StatusCommand, JsonContext.StatusResult).ConfigureAwait(false); @@ -55,4 +60,8 @@ public async Task EndAsync(EndOptions? options = null) { return await Broker.ExecuteCommandAsync(new EndCommand(), options, JsonContext.EndCommand, JsonContext.EndResult).ConfigureAwait(false); } + protected override JsonSerializerContext Initialize(JsonSerializerOptions options) + { + return new BiDiJsonSerializerContext(options); + } } diff --git a/dotnet/src/webdriver/BiDi/Storage/StorageModule.cs b/dotnet/src/webdriver/BiDi/Storage/StorageModule.cs index 3e71db576c760..29410895ce187 100644 --- a/dotnet/src/webdriver/BiDi/Storage/StorageModule.cs +++ b/dotnet/src/webdriver/BiDi/Storage/StorageModule.cs @@ -18,12 +18,17 @@ // using OpenQA.Selenium.BiDi.Communication; +using OpenQA.Selenium.BiDi.Communication.Json; +using System.Text.Json; +using System.Text.Json.Serialization; using System.Threading.Tasks; namespace OpenQA.Selenium.BiDi.Storage; public sealed class StorageModule : Module { + internal new BiDiJsonSerializerContext JsonContext => (BiDiJsonSerializerContext)base.JsonContext; + public async Task GetCookiesAsync(GetCookiesOptions? options = null) { var @params = new GetCookiesParameters(options?.Filter, options?.Partition); @@ -44,4 +49,8 @@ public async Task SetCookieAsync(PartialCookie cookie, SetCooki return await Broker.ExecuteCommandAsync(new SetCookieCommand(@params), options, JsonContext.SetCookieCommand, JsonContext.SetCookieResult).ConfigureAwait(false); } + protected override JsonSerializerContext Initialize(JsonSerializerOptions options) + { + return new BiDiJsonSerializerContext(options); + } } diff --git a/dotnet/src/webdriver/BiDi/WebDriver.Extensions.cs b/dotnet/src/webdriver/BiDi/WebDriver.Extensions.cs index 2aedc80a2c092..fc270b7b58839 100644 --- a/dotnet/src/webdriver/BiDi/WebDriver.Extensions.cs +++ b/dotnet/src/webdriver/BiDi/WebDriver.Extensions.cs @@ -17,6 +17,7 @@ // under the License. // +using OpenQA.Selenium.BiDi.Extensions.Permissions; using System; using System.Threading.Tasks; @@ -41,4 +42,9 @@ public static async Task AsBiDiAsync(this IWebDriver webDriver, BiDiOption return bidi; } + + public static PermissionsModule AsPermissions(this BiDi bidi) + { + return Module.Create(bidi, bidi.DefaultBiDiOptions()); + } } diff --git a/dotnet/src/webdriver/BiDi/WebExtension/WebExtensionModule.cs b/dotnet/src/webdriver/BiDi/WebExtension/WebExtensionModule.cs index 8432ccc36bd01..2a3d13e9e9064 100644 --- a/dotnet/src/webdriver/BiDi/WebExtension/WebExtensionModule.cs +++ b/dotnet/src/webdriver/BiDi/WebExtension/WebExtensionModule.cs @@ -18,12 +18,17 @@ // using OpenQA.Selenium.BiDi.Communication; +using OpenQA.Selenium.BiDi.Communication.Json; +using System.Text.Json; +using System.Text.Json.Serialization; using System.Threading.Tasks; namespace OpenQA.Selenium.BiDi.WebExtension; public sealed class WebExtensionModule : Module { + internal new BiDiJsonSerializerContext JsonContext => (BiDiJsonSerializerContext)base.JsonContext; + public async Task InstallAsync(ExtensionData extensionData, InstallOptions? options = null) { var @params = new InstallParameters(extensionData); @@ -37,4 +42,8 @@ public async Task UninstallAsync(Extension extension, Uninstall return await Broker.ExecuteCommandAsync(new UninstallCommand(@params), options, JsonContext.UninstallCommand, JsonContext.UninstallResult).ConfigureAwait(false); } + protected override JsonSerializerContext Initialize(JsonSerializerOptions options) + { + return new BiDiJsonSerializerContext(options); + } } diff --git a/dotnet/test/common/BiDi/Extensions/Permissions/PermissionsTests.cs b/dotnet/test/common/BiDi/Extensions/Permissions/PermissionsTests.cs new file mode 100644 index 0000000000000..26cf1648680bc --- /dev/null +++ b/dotnet/test/common/BiDi/Extensions/Permissions/PermissionsTests.cs @@ -0,0 +1,42 @@ +using NUnit.Framework; +using OpenQA.Selenium.BiDi.BrowsingContext; +using OpenQA.Selenium.BiDi.Script; +using OpenQA.Selenium.Environment; +using System.Threading.Tasks; + +namespace OpenQA.Selenium.BiDi.Extensions.Permissions; + +internal class PermissionsTests : BiDiTestFixture +{ + [Test] + public async Task SettingPermissionsTest() + { + var userContext = await bidi.Browser.CreateUserContextAsync(); + var window = (await bidi.BrowsingContext.CreateAsync(ContextType.Window, new() + { + ReferenceContext = context, + UserContext = userContext.UserContext, + Background = true + })).Context; + + var newPage = EnvironmentManager.Instance.UrlBuilder.CreateInlinePage(new InlinePage() + .WithBody("
new page
")); + + await window.NavigateAsync(newPage); + + var before = await window.Script.CallFunctionAsync(""" + async () => (await navigator.permissions.query({ name: "geolocation" })).state + """, awaitPromise: true, new() { UserActivation = true, }); + + Assert.That(before.AsSuccessResult(), Is.EqualTo(new StringRemoteValue("prompt"))); + + var permissions = bidi.AsPermissions(); + await permissions.SetPermissionAsync("geolocation", PermissionState.Denied, newPage, userContext.UserContext); + + var after = await window.Script.CallFunctionAsync(""" + async () => (await navigator.permissions.query({ name: "geolocation" })).state + """, awaitPromise: true, new() { UserActivation = true }); + + Assert.That(after.AsSuccessResult(), Is.EqualTo(new StringRemoteValue("denied"))); + } +}