Skip to content
Draft
4 changes: 2 additions & 2 deletions dotnet/src/webdriver/BiDi/Communication/Broker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ internal Broker(BiDi bidi, Uri url)
Converters =
{
new BrowsingContextConverter(_bidi),
new BrowserUserContextConverter(bidi),
new BrowserClientWindowConverter(),
new BrowserUserContextConverter(_bidi),
new BrowserClientWindowConverter(_bidi),
new NavigationConverter(),
new InterceptConverter(_bidi),
new RequestConverter(_bidi),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ namespace OpenQA.Selenium.BiDi.Communication.Json;
[JsonSerializable(typeof(Modules.Browser.RemoveUserContextCommand))]
[JsonSerializable(typeof(Modules.Browser.GetClientWindowsCommand))]
[JsonSerializable(typeof(Modules.Browser.GetClientWindowsResult))]
[JsonSerializable(typeof(Modules.Browser.SetClientWindowStateCommand))]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure I have to add ClientWindowInfo type explicitly here, since it is already added by the code 3 lines below. @RenderMichael do you know? I cannot verify, the tests are ignored.

We can leave this PR opened until we verify how it works with real browser. At this moment I verified serialization only.

[JsonSerializable(typeof(Modules.Browser.UserContextInfo))]
[JsonSerializable(typeof(IReadOnlyList<Modules.Browser.UserContextInfo>))]
[JsonSerializable(typeof(IReadOnlyList<Modules.Browser.ClientWindowInfo>))]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,18 @@ namespace OpenQA.Selenium.BiDi.Communication.Json.Converters;

internal class BrowserClientWindowConverter : JsonConverter<ClientWindow>
{
private readonly BiDi _bidi;

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

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

return new ClientWindow(id!);
return new ClientWindow(_bidi, id!);
}

public override void Write(Utf8JsonWriter writer, ClientWindow value, JsonSerializerOptions options)
Expand Down
15 changes: 14 additions & 1 deletion dotnet/src/webdriver/BiDi/Modules/Browser/BrowserModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
// under the License.
// </copyright>

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

Expand Down Expand Up @@ -51,4 +50,18 @@ public async Task<GetClientWindowsResult> GetClientWindowsAsync(GetClientWindows
{
return await Broker.ExecuteCommandAsync<GetClientWindowsCommand, GetClientWindowsResult>(new(), options).ConfigureAwait(false);
}

internal async Task<ClientWindowInfo> SetClientWindowStateAsync(ClientWindow clientWindow, ClientWindowNamedState state, SetClientWindowNamedStateOptions? options = null)
{
var @params = new SetClientWindowNamedStateCommandParameters(clientWindow, state);

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

internal async Task<ClientWindowInfo> SetClientWindowStateAsync(ClientWindow clientWindow, SetClientWindowRectStateOptions? options = null)
{
var @params = new SetClientWindowRectStateCommandParameters(clientWindow, options);

return await Broker.ExecuteCommandAsync<SetClientWindowStateCommand, ClientWindowInfo>(new SetClientWindowStateCommand(@params), options).ConfigureAwait(false);
}
}
17 changes: 16 additions & 1 deletion dotnet/src/webdriver/BiDi/Modules/Browser/ClientWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,29 @@
// under the License.
// </copyright>

using System.Threading.Tasks;

namespace OpenQA.Selenium.BiDi.Modules.Browser;

public record ClientWindow
{
internal ClientWindow(string id)
internal ClientWindow(BiDi bidi, string id)
{
BiDi = bidi;
Id = id;
}

internal BiDi BiDi { get; }

internal string Id { get; }

public Task<ClientWindowInfo> SetStateAsync(ClientWindowNamedState state, SetClientWindowNamedStateOptions? options = null)
{
return BiDi.Browser.SetClientWindowStateAsync(this, state, options);
}

public Task<ClientWindowInfo> SetStateAsync(SetClientWindowRectStateOptions? options = null)
{
return BiDi.Browser.SetClientWindowStateAsync(this, options);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// <copyright file="SetClientWindowStateCommand.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.Modules.Browser;

internal class SetClientWindowStateCommand(SetClientWindowStateCommandParameters @params)
: Command<SetClientWindowStateCommandParameters>(@params, "browser.setClientWindowState");

[JsonDerivedType(typeof(SetClientWindowNamedStateCommandParameters))]
[JsonDerivedType(typeof(SetClientWindowRectStateCommandParameters))]
internal abstract record SetClientWindowStateCommandParameters(ClientWindow ClientWindow) : CommandParameters;

internal record SetClientWindowNamedStateCommandParameters(ClientWindow ClientWindow, ClientWindowNamedState State) : SetClientWindowStateCommandParameters(ClientWindow);

internal record SetClientWindowRectStateCommandParameters(ClientWindow ClientWindow, [property: JsonIgnore] SetClientWindowRectStateOptions? Options) : SetClientWindowStateCommandParameters(ClientWindow)
{
[JsonInclude]
internal string State { get; } = "normal";

public int? Width { get; set; } = Options?.Width;

public int? Height { get; set; } = Options?.Height;

public int? X { get; set; } = Options?.X;

public int? Y { get; set; } = Options?.Y;
}

public record SetClientWindowNamedStateOptions : CommandOptions;

public record SetClientWindowRectStateOptions : CommandOptions
{
public int? Width { get; set; }

public int? Height { get; set; }

public int? X { get; set; }

public int? Y { get; set; }
}

public enum ClientWindowNamedState
{
Fullscreen,
Maximized,
Minimized
}
24 changes: 24 additions & 0 deletions dotnet/test/common/BiDi/Browser/BrowserTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,28 @@ public async Task CanGetClientWindows()
Assert.That(clientWindows, Has.Count.GreaterThanOrEqualTo(1));
Assert.That(clientWindows[0].ClientWindow, Is.Not.Null);
}

[Test]
[Ignore("Not yet implemented by all vendors")]
public async Task CanSetClientWindowNamedState()
{
var clientWindows = await bidi.Browser.GetClientWindowsAsync();

var clientWindowInfo = await clientWindows[0].ClientWindow.SetStateAsync(Modules.Browser.ClientWindowNamedState.Fullscreen);

// TODO: Make assertion meaningfull
Assert.That(clientWindowInfo, Is.Not.Null);
}

[Test]
[Ignore("Not yet implemented by all vendors")]
public async Task CanSetClientWindowRectState()
{
var clientWindows = await bidi.Browser.GetClientWindowsAsync();

var clientWindowInfo = await clientWindows[0].ClientWindow.SetStateAsync(new() { Width = 500, Height = 300, X = 10, Y = 10 });

// TODO: Make assertion meaningfull
Assert.That(clientWindowInfo, Is.Not.Null);
}
}
Loading