Skip to content

Commit e19d069

Browse files
authored
[dotnet] [bidi] Support getting of client windows in browser module (#15241)
1 parent 0721800 commit e19d069

14 files changed

+228
-5
lines changed

dotnet/src/webdriver/BiDi/Communication/Broker.cs

+2
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ internal Broker(BiDi bidi, ITransport transport)
7070
{
7171
new BrowsingContextConverter(_bidi),
7272
new BrowserUserContextConverter(bidi),
73+
new BrowserClientWindowConverter(),
7374
new NavigationConverter(),
7475
new InterceptConverter(_bidi),
7576
new RequestConverter(_bidi),
@@ -97,6 +98,7 @@ internal Broker(BiDi bidi, ITransport transport)
9798
new Json.Converters.Enumerable.LocateNodesResultConverter(),
9899
new Json.Converters.Enumerable.InputSourceActionsConverter(),
99100
new Json.Converters.Enumerable.GetUserContextsResultConverter(),
101+
new Json.Converters.Enumerable.GetClientWindowsResultConverter(),
100102
new Json.Converters.Enumerable.GetRealmsResultConverter(),
101103
}
102104
};

dotnet/src/webdriver/BiDi/Communication/Json/BiDiJsonSerializerContext.cs

+3
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,11 @@ namespace OpenQA.Selenium.BiDi.Communication.Json;
8686
[JsonSerializable(typeof(Modules.Browser.GetUserContextsCommand))]
8787
[JsonSerializable(typeof(Modules.Browser.GetUserContextsResult))]
8888
[JsonSerializable(typeof(Modules.Browser.RemoveUserContextCommand))]
89+
[JsonSerializable(typeof(Modules.Browser.GetClientWindowsCommand))]
90+
[JsonSerializable(typeof(Modules.Browser.GetClientWindowsResult))]
8991
[JsonSerializable(typeof(Modules.Browser.UserContextInfo))]
9092
[JsonSerializable(typeof(IReadOnlyList<Modules.Browser.UserContextInfo>))]
93+
[JsonSerializable(typeof(IReadOnlyList<Modules.Browser.ClientWindowInfo>))]
9194

9295

9396
[JsonSerializable(typeof(Modules.BrowsingContext.ActivateCommand))]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// <copyright file="BrowserClientWindowConverter.cs" company="Selenium Committers">
2+
// Licensed to the Software Freedom Conservancy (SFC) under one
3+
// or more contributor license agreements. See the NOTICE file
4+
// distributed with this work for additional information
5+
// regarding copyright ownership. The SFC licenses this file
6+
// to you under the Apache License, Version 2.0 (the
7+
// "License"); you may not use this file except in compliance
8+
// with the License. You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing,
13+
// software distributed under the License is distributed on an
14+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
// KIND, either express or implied. See the License for the
16+
// specific language governing permissions and limitations
17+
// under the License.
18+
// </copyright>
19+
20+
using OpenQA.Selenium.BiDi.Modules.Browser;
21+
using System;
22+
using System.Text.Json;
23+
using System.Text.Json.Serialization;
24+
25+
#nullable enable
26+
27+
namespace OpenQA.Selenium.BiDi.Communication.Json.Converters;
28+
29+
internal class BrowserClientWindowConverter : JsonConverter<ClientWindow>
30+
{
31+
public override ClientWindow? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
32+
{
33+
var id = reader.GetString();
34+
35+
return new ClientWindow(id!);
36+
}
37+
38+
public override void Write(Utf8JsonWriter writer, ClientWindow value, JsonSerializerOptions options)
39+
{
40+
writer.WriteStringValue(value.Id);
41+
}
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// <copyright file="GetClientWindowsResultConverter.cs" company="Selenium Committers">
2+
// Licensed to the Software Freedom Conservancy (SFC) under one
3+
// or more contributor license agreements. See the NOTICE file
4+
// distributed with this work for additional information
5+
// regarding copyright ownership. The SFC licenses this file
6+
// to you under the Apache License, Version 2.0 (the
7+
// "License"); you may not use this file except in compliance
8+
// with the License. You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing,
13+
// software distributed under the License is distributed on an
14+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
// KIND, either express or implied. See the License for the
16+
// specific language governing permissions and limitations
17+
// under the License.
18+
// </copyright>
19+
20+
using OpenQA.Selenium.BiDi.Modules.Browser;
21+
using System;
22+
using System.Collections.Generic;
23+
using System.Text.Json;
24+
using System.Text.Json.Serialization;
25+
26+
#nullable enable
27+
28+
namespace OpenQA.Selenium.BiDi.Communication.Json.Converters.Enumerable;
29+
30+
internal class GetClientWindowsResultConverter : JsonConverter<GetClientWindowsResult>
31+
{
32+
public override GetClientWindowsResult Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
33+
{
34+
using var doc = JsonDocument.ParseValue(ref reader);
35+
var clientWindows = doc.RootElement.GetProperty("clientWindows").Deserialize<IReadOnlyList<ClientWindowInfo>>(options);
36+
37+
return new GetClientWindowsResult(clientWindows!);
38+
}
39+
40+
public override void Write(Utf8JsonWriter writer, GetClientWindowsResult value, JsonSerializerOptions options)
41+
{
42+
throw new NotImplementedException();
43+
}
44+
}

dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/GetCookiesResultConverter.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ internal class GetCookiesResultConverter : JsonConverter<GetCookiesResult>
3131
{
3232
public override GetCookiesResult Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
3333
{
34-
var doc = JsonDocument.ParseValue(ref reader);
34+
using var doc = JsonDocument.ParseValue(ref reader);
3535
var cookies = doc.RootElement.GetProperty("cookies").Deserialize<IReadOnlyList<Modules.Network.Cookie>>(options);
3636
var partitionKey = doc.RootElement.GetProperty("partitionKey").Deserialize<PartitionKey>(options);
3737

dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/GetRealmsResultConverter.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ internal class GetRealmsResultConverter : JsonConverter<GetRealmsResult>
3131
{
3232
public override GetRealmsResult Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
3333
{
34-
var doc = JsonDocument.ParseValue(ref reader);
34+
using var doc = JsonDocument.ParseValue(ref reader);
3535
var realms = doc.RootElement.GetProperty("realms").Deserialize<IReadOnlyList<RealmInfo>>(options);
3636

3737
return new GetRealmsResult(realms!);

dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/GetUserContextsResultConverter.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ internal class GetUserContextsResultConverter : JsonConverter<GetUserContextsRes
3131
{
3232
public override GetUserContextsResult Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
3333
{
34-
var doc = JsonDocument.ParseValue(ref reader);
34+
using var doc = JsonDocument.ParseValue(ref reader);
3535
var userContexts = doc.RootElement.GetProperty("userContexts").Deserialize<IReadOnlyList<UserContextInfo>>(options);
3636

3737
return new GetUserContextsResult(userContexts!);

dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/LocateNodesResultConverter.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ internal class LocateNodesResultConverter : JsonConverter<LocateNodesResult>
3232
{
3333
public override LocateNodesResult Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
3434
{
35-
var doc = JsonDocument.ParseValue(ref reader);
35+
using var doc = JsonDocument.ParseValue(ref reader);
3636
var nodes = doc.RootElement.GetProperty("nodes").Deserialize<IReadOnlyList<RemoteValue.Node>>(options);
3737

3838
return new LocateNodesResult(nodes!);

dotnet/src/webdriver/BiDi/Modules/Browser/BrowserModule.cs

+5
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,9 @@ public async Task RemoveUserContextAsync(UserContext userContext, RemoveUserCont
4848

4949
await Broker.ExecuteCommandAsync(new RemoveUserContextCommand(@params), options).ConfigureAwait(false);
5050
}
51+
52+
public async Task<GetClientWindowsResult> GetClientWindowsAsync(GetClientWindowsOptions? options = null)
53+
{
54+
return await Broker.ExecuteCommandAsync<GetClientWindowsCommand, GetClientWindowsResult>(new(), options).ConfigureAwait(false);
55+
}
5156
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// <copyright file="ClientWindow.cs" company="Selenium Committers">
2+
// Licensed to the Software Freedom Conservancy (SFC) under one
3+
// or more contributor license agreements. See the NOTICE file
4+
// distributed with this work for additional information
5+
// regarding copyright ownership. The SFC licenses this file
6+
// to you under the Apache License, Version 2.0 (the
7+
// "License"); you may not use this file except in compliance
8+
// with the License. You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing,
13+
// software distributed under the License is distributed on an
14+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
// KIND, either express or implied. See the License for the
16+
// specific language governing permissions and limitations
17+
// under the License.
18+
// </copyright>
19+
20+
#nullable enable
21+
22+
namespace OpenQA.Selenium.BiDi.Modules.Browser;
23+
24+
public record ClientWindow
25+
{
26+
internal ClientWindow(string id)
27+
{
28+
Id = id;
29+
}
30+
31+
internal string Id { get; }
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// <copyright file="ClientWindowInfo.cs" company="Selenium Committers">
2+
// Licensed to the Software Freedom Conservancy (SFC) under one
3+
// or more contributor license agreements. See the NOTICE file
4+
// distributed with this work for additional information
5+
// regarding copyright ownership. The SFC licenses this file
6+
// to you under the Apache License, Version 2.0 (the
7+
// "License"); you may not use this file except in compliance
8+
// with the License. You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing,
13+
// software distributed under the License is distributed on an
14+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
// KIND, either express or implied. See the License for the
16+
// specific language governing permissions and limitations
17+
// under the License.
18+
// </copyright>
19+
20+
#nullable enable
21+
22+
using System.Text.Json.Serialization;
23+
24+
namespace OpenQA.Selenium.BiDi.Modules.Browser;
25+
26+
public record ClientWindowInfo([property: JsonPropertyName("active")] bool IsActive, ClientWindow ClientWindow, ClientWindowState State, int Height, int Width, int X, int Y);
27+
28+
public enum ClientWindowState
29+
{
30+
Fullscreen,
31+
Maximized,
32+
Minimized,
33+
Normal
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// <copyright file="GetClientWindowsCommand.cs" company="Selenium Committers">
2+
// Licensed to the Software Freedom Conservancy (SFC) under one
3+
// or more contributor license agreements. See the NOTICE file
4+
// distributed with this work for additional information
5+
// regarding copyright ownership. The SFC licenses this file
6+
// to you under the Apache License, Version 2.0 (the
7+
// "License"); you may not use this file except in compliance
8+
// with the License. You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing,
13+
// software distributed under the License is distributed on an
14+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
// KIND, either express or implied. See the License for the
16+
// specific language governing permissions and limitations
17+
// under the License.
18+
// </copyright>
19+
20+
using OpenQA.Selenium.BiDi.Communication;
21+
using System.Collections;
22+
using System.Collections.Generic;
23+
24+
#nullable enable
25+
26+
namespace OpenQA.Selenium.BiDi.Modules.Browser;
27+
28+
internal class GetClientWindowsCommand()
29+
: Command<CommandParameters>(CommandParameters.Empty, "browser.getClientWindows");
30+
31+
public record GetClientWindowsOptions : CommandOptions;
32+
33+
public record GetClientWindowsResult : IReadOnlyList<ClientWindowInfo>
34+
{
35+
private readonly IReadOnlyList<ClientWindowInfo> _clientWindows;
36+
37+
internal GetClientWindowsResult(IReadOnlyList<ClientWindowInfo> clientWindows)
38+
{
39+
_clientWindows = clientWindows;
40+
}
41+
42+
public ClientWindowInfo this[int index] => _clientWindows[index];
43+
44+
public int Count => _clientWindows.Count;
45+
46+
public IEnumerator<ClientWindowInfo> GetEnumerator() => _clientWindows.GetEnumerator();
47+
48+
IEnumerator IEnumerable.GetEnumerator() => (_clientWindows as IEnumerable).GetEnumerator();
49+
}

dotnet/src/webdriver/BiDi/Modules/BrowsingContext/BrowsingContextInfo.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
namespace OpenQA.Selenium.BiDi.Modules.BrowsingContext;
2626

2727
// TODO: Split it to separate class with just info and event args
28-
public record BrowsingContextInfo(BiDi BiDi, IReadOnlyList<BrowsingContextInfo> Children, BrowsingContext Context, BrowsingContext OriginalOpener, string Url, Browser.UserContext UserContext)
28+
public record BrowsingContextInfo(BiDi BiDi, IReadOnlyList<BrowsingContextInfo> Children, Browser.ClientWindow ClientWindow, BrowsingContext Context, BrowsingContext OriginalOpener, string Url, Browser.UserContext UserContext)
2929
: BrowsingContextEventArgs(BiDi, Context)
3030
{
3131
[JsonInclude]

dotnet/test/common/BiDi/Browser/BrowserTest.cs

+12
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,16 @@ public async Task CanRemoveUserContext()
5959
Assert.That(userContexts, Does.Contain(userContext1));
6060
Assert.That(userContexts, Does.Not.Contain(userContext2));
6161
}
62+
63+
[Test]
64+
[IgnoreBrowser(Selenium.Browser.Chrome, "BiDi GetClientWindows command not yet supported by Chrome 133")]
65+
[IgnoreBrowser(Selenium.Browser.Edge, "BiDi GetClientWindows command not yet supported by Edge 133")]
66+
public async Task CanGetClientWindows()
67+
{
68+
var clientWindows = await bidi.Browser.GetClientWindowsAsync();
69+
70+
Assert.That(clientWindows, Is.Not.Null);
71+
Assert.That(clientWindows, Has.Count.GreaterThanOrEqualTo(1));
72+
Assert.That(clientWindows[0].ClientWindow, Is.Not.Null);
73+
}
6274
}

0 commit comments

Comments
 (0)