Skip to content

Commit ec60717

Browse files
committed
Merge branch 'trunk' of https://github.com/SeleniumHQ/selenium into py-bidi-input
2 parents 6aff3c9 + e12da0d commit ec60717

File tree

19 files changed

+570
-70
lines changed

19 files changed

+570
-70
lines changed

.skipped-tests

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
-//dotnet/test/common:NetworkInterceptionTests-chrome
22
-//dotnet/test/common:NetworkInterceptionTests-edge
3+
-//dotnet/test/firefox:FirefoxDriverTest-firefox
34
-//java/test/org/openqa/selenium/chrome:ChromeDriverFunctionalTest
45
-//java/test/org/openqa/selenium/chrome:ChromeDriverFunctionalTest-remote
56
-//java/test/org/openqa/selenium/edge:EdgeDriverFunctionalTest

common/selenium_manager.bzl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,22 @@ def selenium_manager():
66
http_file(
77
name = "download_sm_linux",
88
executable = True,
9-
sha256 = "50099355b0e74b8bb231a5b152fc3de498dcde1cdebcefb1e501713e9b124b9d",
10-
url = "https://github.com/SeleniumHQ/selenium_manager_artifacts/releases/download/selenium-manager-0ab9b6d/selenium-manager-linux",
9+
sha256 = "f615ae2eea714a54e322f8945c7abb19e03e0f5d651b464bd5cd9e9ecf9e7c90",
10+
url = "https://github.com/SeleniumHQ/selenium_manager_artifacts/releases/download/selenium-manager-9d09338/selenium-manager-linux",
1111
)
1212

1313
http_file(
1414
name = "download_sm_macos",
1515
executable = True,
16-
sha256 = "eb98ce344acfaee3a7d58038331a8b49985ac724d2a9ec02258008c076979846",
17-
url = "https://github.com/SeleniumHQ/selenium_manager_artifacts/releases/download/selenium-manager-0ab9b6d/selenium-manager-macos",
16+
sha256 = "88fede46d14991930aab3176f6938ddb7549ab244f6d75a9745050d625274852",
17+
url = "https://github.com/SeleniumHQ/selenium_manager_artifacts/releases/download/selenium-manager-9d09338/selenium-manager-macos",
1818
)
1919

2020
http_file(
2121
name = "download_sm_windows",
2222
executable = True,
23-
sha256 = "7090d5737aebabb9daad49022b070d3456b8e43ae7f3ac5bcb780af67c371b3f",
24-
url = "https://github.com/SeleniumHQ/selenium_manager_artifacts/releases/download/selenium-manager-0ab9b6d/selenium-manager-windows.exe",
23+
sha256 = "a7e8a7e0f561e7d8238f8aa884ef2dd6235884d3b0e97f25061747dbf4ec5037",
24+
url = "https://github.com/SeleniumHQ/selenium_manager_artifacts/releases/download/selenium-manager-9d09338/selenium-manager-windows.exe",
2525
)
2626

2727
def _selenium_manager_artifacts_impl(_ctx):

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

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -91,16 +91,6 @@ public Task TraverseHistoryAsync(int delta, TraverseHistoryOptions? options = nu
9191
return BiDi.BrowsingContext.TraverseHistoryAsync(this, delta, options);
9292
}
9393

94-
public Task NavigateBackAsync(TraverseHistoryOptions? options = null)
95-
{
96-
return TraverseHistoryAsync(-1, options);
97-
}
98-
99-
public Task NavigateForwardAsync(TraverseHistoryOptions? options = null)
100-
{
101-
return TraverseHistoryAsync(1, options);
102-
}
103-
10494
public Task SetViewportAsync(SetViewportOptions? options = null)
10595
{
10696
return BiDi.BrowsingContext.SetViewportAsync(this, options);

dotnet/src/webdriver/DriverService.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ protected virtual void Dispose(bool disposing)
284284
/// Raises the <see cref="DriverProcessStarting"/> event.
285285
/// </summary>
286286
/// <param name="eventArgs">A <see cref="DriverProcessStartingEventArgs"/> that contains the event data.</param>
287-
protected void OnDriverProcessStarting(DriverProcessStartingEventArgs eventArgs)
287+
protected virtual void OnDriverProcessStarting(DriverProcessStartingEventArgs eventArgs)
288288
{
289289
if (eventArgs == null)
290290
{
@@ -298,7 +298,7 @@ protected void OnDriverProcessStarting(DriverProcessStartingEventArgs eventArgs)
298298
/// Raises the <see cref="DriverProcessStarted"/> event.
299299
/// </summary>
300300
/// <param name="eventArgs">A <see cref="DriverProcessStartedEventArgs"/> that contains the event data.</param>
301-
protected void OnDriverProcessStarted(DriverProcessStartedEventArgs eventArgs)
301+
protected virtual void OnDriverProcessStarted(DriverProcessStartedEventArgs eventArgs)
302302
{
303303
if (eventArgs == null)
304304
{

dotnet/src/webdriver/Firefox/FirefoxDriver.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ public override IFileDetector FileDetector
252252
}
253253

254254
/// <summary>
255-
/// Sets the command context used when issuing commands to <c>geckodriver</c>.
255+
/// Gets the command context used when issuing commands to <c>geckodriver</c>.
256256
/// </summary>
257257
/// <exception cref="WebDriverException">If response is not recognized</exception>
258258
/// <returns>The context of commands.</returns>
@@ -263,7 +263,7 @@ public FirefoxCommandContext GetContext()
263263
if (commandResponse.Value is not string response
264264
|| !Enum.TryParse(response, ignoreCase: true, out FirefoxCommandContext output))
265265
{
266-
throw new WebDriverException(string.Format(CultureInfo.InvariantCulture, "Do not recognize response: {0}; expected Context or Chrome", commandResponse.Value));
266+
throw new WebDriverException(string.Format(CultureInfo.InvariantCulture, "Could not recognize the response: {0}; expected 'Content' or 'Chrome'", commandResponse.Value));
267267
}
268268

269269
return output;

dotnet/src/webdriver/Firefox/FirefoxDriverService.cs

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
using System.Globalization;
2323
using System.IO;
2424
using System.Text;
25+
using System.Threading.Tasks;
2526

2627
namespace OpenQA.Selenium.Firefox;
2728

@@ -32,6 +33,11 @@ public sealed class FirefoxDriverService : DriverService
3233
{
3334
private const string DefaultFirefoxDriverServiceFileName = "geckodriver";
3435

36+
/// <summary>
37+
/// Process management fields for the log writer.
38+
/// </summary>
39+
private StreamWriter? logWriter;
40+
3541
/// <summary>
3642
/// Initializes a new instance of the <see cref="FirefoxDriverService"/> class.
3743
/// </summary>
@@ -87,6 +93,16 @@ protected override DriverOptions GetDefaultDriverOptions()
8793
/// </summary>
8894
public bool OpenBrowserToolbox { get; set; }
8995

96+
/// <summary>
97+
/// Gets or sets the file path where log output should be written.
98+
/// </summary>
99+
/// <remarks>
100+
/// A <see langword="null"/> or <see cref="string.Empty"/> value indicates no log file to specify.
101+
/// This approach takes the process output and redirects it to a file because GeckoDriver does not
102+
/// offer a way to specify a log file path directly.
103+
/// </remarks>
104+
public string? LogPath { get; set; }
105+
90106
/// <summary>
91107
/// Gets or sets the level at which log output is displayed.
92108
/// </summary>
@@ -177,6 +193,75 @@ protected override string CommandLineArguments
177193
}
178194
}
179195

196+
/// <summary>
197+
/// Handles the event when the driver service process is starting.
198+
/// </summary>
199+
/// <param name="eventArgs">The event arguments containing information about the driver service process.</param>
200+
/// <remarks>
201+
/// This method initializes a log writer if a log path is specified and redirects output streams to capture logs.
202+
/// </remarks>
203+
protected override void OnDriverProcessStarting(DriverProcessStartingEventArgs eventArgs)
204+
{
205+
if (!string.IsNullOrEmpty(this.LogPath))
206+
{
207+
string? directory = Path.GetDirectoryName(this.LogPath);
208+
if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
209+
{
210+
Directory.CreateDirectory(directory);
211+
}
212+
213+
// Initialize the log writer
214+
logWriter = new StreamWriter(this.LogPath, append: true) { AutoFlush = true };
215+
216+
// Configure process to redirect output
217+
eventArgs.DriverServiceProcessStartInfo.RedirectStandardOutput = true;
218+
eventArgs.DriverServiceProcessStartInfo.RedirectStandardError = true;
219+
}
220+
221+
base.OnDriverProcessStarting(eventArgs);
222+
}
223+
224+
/// <summary>
225+
/// Handles the event when the driver process has started.
226+
/// </summary>
227+
/// <param name="eventArgs">The event arguments containing information about the started driver process.</param>
228+
/// <remarks>
229+
/// This method reads the output and error streams asynchronously and writes them to the log file if available.
230+
/// </remarks>
231+
protected override void OnDriverProcessStarted(DriverProcessStartedEventArgs eventArgs)
232+
{
233+
if (logWriter == null) return;
234+
if (eventArgs.StandardOutputStreamReader != null)
235+
{
236+
_ = Task.Run(() => ReadStreamAsync(eventArgs.StandardOutputStreamReader));
237+
}
238+
239+
if (eventArgs.StandardErrorStreamReader != null)
240+
{
241+
_ = Task.Run(() => ReadStreamAsync(eventArgs.StandardErrorStreamReader));
242+
}
243+
244+
base.OnDriverProcessStarted(eventArgs);
245+
}
246+
247+
/// <summary>
248+
/// Disposes of the resources used by the <see cref="FirefoxDriverService"/> instance.
249+
/// </summary>
250+
/// <param name="disposing">A value indicating whether the method is being called from Dispose.</param>
251+
/// <remarks>
252+
/// If disposing is true, it disposes of the log writer if it exists.
253+
/// </remarks>
254+
protected override void Dispose(bool disposing)
255+
{
256+
if (logWriter != null && disposing)
257+
{
258+
logWriter.Dispose();
259+
logWriter = null;
260+
}
261+
262+
base.Dispose(disposing);
263+
}
264+
180265
/// <summary>
181266
/// Creates a default instance of the FirefoxDriverService.
182267
/// </summary>
@@ -258,4 +343,24 @@ private static string FirefoxDriverServiceFileName()
258343

259344
return fileName;
260345
}
346+
347+
private async Task ReadStreamAsync(StreamReader reader)
348+
{
349+
try
350+
{
351+
string? line;
352+
while ((line = await reader.ReadLineAsync()) != null)
353+
{
354+
if (logWriter != null)
355+
{
356+
logWriter.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff} {line}");
357+
}
358+
}
359+
}
360+
catch (Exception ex)
361+
{
362+
// Log or handle the exception appropriately
363+
System.Diagnostics.Debug.WriteLine($"Error reading stream: {ex.Message}");
364+
}
365+
}
261366
}

dotnet/src/webdriver/Internal/PortUtilities.cs

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -33,23 +33,10 @@ public static class PortUtilities
3333
/// <returns>A random, free port to be listened on.</returns>
3434
public static int FindFreePort()
3535
{
36-
// Locate a free port on the local machine by binding a socket to
37-
// an IPEndPoint using IPAddress.Any and port 0. The socket will
38-
// select a free port.
39-
int listeningPort = 0;
40-
Socket portSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
41-
try
42-
{
43-
IPEndPoint socketEndPoint = new IPEndPoint(IPAddress.Any, 0);
44-
portSocket.Bind(socketEndPoint);
45-
socketEndPoint = (IPEndPoint)portSocket.LocalEndPoint!;
46-
listeningPort = socketEndPoint.Port;
47-
}
48-
finally
49-
{
50-
portSocket.Close();
51-
}
36+
using var socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
37+
socket.DualMode = true;
38+
socket.Bind(new IPEndPoint(IPAddress.IPv6Loopback, 0));
39+
return (socket.LocalEndPoint as IPEndPoint)!.Port;
5240

53-
return listeningPort;
5441
}
5542
}

dotnet/test/firefox/BUILD.bazel

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
load("//dotnet:defs.bzl", "dotnet_nunit_test_suite", "framework")
2+
3+
dotnet_nunit_test_suite(
4+
name = "LargeTests",
5+
size = "large",
6+
srcs = glob(
7+
[
8+
"**/*Test.cs",
9+
"**/*Tests.cs",
10+
],
11+
) + [
12+
"//dotnet/test/common:assembly-fixtures",
13+
],
14+
browsers = [
15+
"firefox",
16+
],
17+
data = [
18+
"//dotnet/test/common:test-data",
19+
],
20+
target_frameworks = ["net8.0"],
21+
deps = [
22+
"//dotnet/src/support",
23+
"//dotnet/src/webdriver:webdriver-net8.0",
24+
"//dotnet/test/common:fixtures",
25+
framework("nuget", "NUnit"),
26+
],
27+
)
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// <copyright file="FirefoxDriverServiceTest.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 NUnit.Framework;
21+
using System.IO;
22+
23+
namespace OpenQA.Selenium.Firefox;
24+
25+
[TestFixture]
26+
public class FirefoxDriverServiceTest : DriverTestFixture
27+
{
28+
[Test]
29+
public void ShouldRedirectGeckoDriverLogsToFile()
30+
{
31+
FirefoxOptions options = new FirefoxOptions();
32+
string logPath = Path.GetTempFileName();
33+
options.LogLevel = FirefoxDriverLogLevel.Trace;
34+
35+
FirefoxDriverService service = FirefoxDriverService.CreateDefaultService();
36+
service.LogPath = logPath;
37+
38+
IWebDriver driver2 = new FirefoxDriver(service, options);
39+
40+
try
41+
{
42+
Assert.That(File.Exists(logPath), Is.True);
43+
string logContent = File.ReadAllText(logPath);
44+
Assert.That(logContent, Does.Contain("geckodriver"));
45+
}
46+
finally
47+
{
48+
driver2.Quit();
49+
File.Delete(logPath);
50+
}
51+
}
52+
53+
}

multitool.lock.json

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,44 +4,44 @@
44
"binaries": [
55
{
66
"kind": "archive",
7-
"url": "https://github.com/astral-sh/ruff/releases/download/0.11.11/ruff-aarch64-unknown-linux-musl.tar.gz",
7+
"url": "https://github.com/astral-sh/ruff/releases/download/0.12.3/ruff-aarch64-unknown-linux-musl.tar.gz",
88
"file": "ruff-aarch64-unknown-linux-musl/ruff",
9-
"sha256": "3ca33d9b68b8b0bc7e3673b7638910ac2f7c5399303b37bec4d13c005481a78a",
9+
"sha256": "7890e49b12c1321688540324a7788457a22711657301598402cba1a9e9be6607",
1010
"os": "linux",
1111
"cpu": "arm64"
1212
},
1313
{
1414
"kind": "archive",
15-
"url": "https://github.com/astral-sh/ruff/releases/download/0.11.11/ruff-x86_64-unknown-linux-musl.tar.gz",
15+
"url": "https://github.com/astral-sh/ruff/releases/download/0.12.3/ruff-x86_64-unknown-linux-musl.tar.gz",
1616
"file": "ruff-x86_64-unknown-linux-musl/ruff",
17-
"sha256": "bb64b083767a5fd0a62e10e9a35614974ad53025e2878cf14a0c698680e6c30c",
17+
"sha256": "6ee9216ba4f7fd761e68bd5c23958e662c67fcff8f49e511660d557431b4bd7c",
1818
"os": "linux",
1919
"cpu": "x86_64"
2020
},
2121
{
2222
"kind": "archive",
23-
"url": "https://github.com/astral-sh/ruff/releases/download/0.11.11/ruff-aarch64-apple-darwin.tar.gz",
23+
"url": "https://github.com/astral-sh/ruff/releases/download/0.12.3/ruff-aarch64-apple-darwin.tar.gz",
2424
"file": "ruff-aarch64-apple-darwin/ruff",
25-
"sha256": "814ccb26bed9c027bfc20ac88d33494ab0be62721757c73be70e26c23efbb3f7",
25+
"sha256": "5769e4841870d1f7c17f12a7d1437222e8035eded52f93c54c035c770dbffebb",
2626
"os": "macos",
2727
"cpu": "arm64"
2828
},
2929
{
3030
"kind": "archive",
31-
"url": "https://github.com/astral-sh/ruff/releases/download/0.11.11/ruff-x86_64-apple-darwin.tar.gz",
31+
"url": "https://github.com/astral-sh/ruff/releases/download/0.12.3/ruff-x86_64-apple-darwin.tar.gz",
3232
"file": "ruff-x86_64-apple-darwin/ruff",
33-
"sha256": "8bef00e82bc07ea26b45adcffc3d55b2d0821f3a3e4d5f441f4dd4ad608fc1be",
33+
"sha256": "472a4790db11a8bcd79cf7b731fb1c036c376f9cc4e6532099f8f39a6f86b9bb",
3434
"os": "macos",
3535
"cpu": "x86_64"
3636
},
3737
{
3838
"kind": "archive",
39-
"url": "https://github.com/astral-sh/ruff/releases/download/0.11.11/ruff-x86_64-pc-windows-msvc.zip",
39+
"url": "https://github.com/astral-sh/ruff/releases/download/0.12.3/ruff-x86_64-pc-windows-msvc.zip",
4040
"file": "ruff-x86_64-pc-windows-msvc/ruff.exe",
41-
"sha256": "b7619ff27098a4d7f37c52fb8fc61ccfe677aaade7722a385b40f8d5273ebddd",
41+
"sha256": "37dc6f2f5756421fc59fe5f841ecaa92beee38a39751dfe5a42bdc13992da3d5",
4242
"os": "windows",
4343
"cpu": "x86_64"
4444
}
4545
]
4646
}
47-
}
47+
}

0 commit comments

Comments
 (0)