diff --git a/.github/workflows/ci-python.yml b/.github/workflows/ci-python.yml index cebe68597d063..e826cab4a91f0 100644 --- a/.github/workflows/ci-python.yml +++ b/.github/workflows/ci-python.yml @@ -96,5 +96,4 @@ jobs: browser: safari os: macos cache-key: py-safari - run: | - bazel test --local_test_jobs 1 --flaky_test_attempts 3 //py:test-safari-test/selenium/webdriver/safari/launcher_tests.py + run: bazel test --local_test_jobs 1 --flaky_test_attempts 3 //py:test-safari diff --git a/MODULE.bazel b/MODULE.bazel index b52df075394b5..30a276b87f857 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -180,7 +180,7 @@ maven.install( "com.google.googlejavaformat:google-java-format:jar:1.24.0", "com.graphql-java:graphql-java:22.3", "dev.failsafe:failsafe:3.3.2", - "io.grpc:grpc-context:1.68.0", + "io.grpc:grpc-context:1.68.1", "io.lettuce:lettuce-core:6.4.0.RELEASE", "io.netty:netty-buffer:4.1.114.Final", "io.netty:netty-codec-http:4.1.114.Final", @@ -199,9 +199,8 @@ maven.install( "io.opentelemetry:opentelemetry-sdk-testing:1.43.0", "io.opentelemetry:opentelemetry-sdk-trace:1.43.0", "io.opentelemetry.semconv:opentelemetry-semconv:1.25.0-alpha", - "io.ous:jtoml:2.0.0", "it.ozimov:embedded-redis:0.7.3", - "net.bytebuddy:byte-buddy:1.15.7", + "net.bytebuddy:byte-buddy:1.15.10", "org.htmlunit:htmlunit-core-js:4.5.0", "org.apache.commons:commons-exec:1.4.0", "org.apache.logging.log4j:log4j-core:2.24.1", @@ -221,6 +220,7 @@ maven.install( "org.redisson:redisson:3.37.0", "org.slf4j:slf4j-api:2.0.16", "org.slf4j:slf4j-jdk14:2.0.16", + "org.tomlj:tomlj:1.1.1", "org.zeromq:jeromq:0.6.0", ], excluded_artifacts = [ diff --git a/dotnet/docs/api/index.md b/dotnet/docs/api/index.md deleted file mode 100644 index 6103d3ac09e0e..0000000000000 --- a/dotnet/docs/api/index.md +++ /dev/null @@ -1 +0,0 @@ -# Welcome to the Selenium .NET API Docs diff --git a/dotnet/docs/docfx.json b/dotnet/docs/docfx.json index bdb6bffed9a4e..f85667fd6800e 100644 --- a/dotnet/docs/docfx.json +++ b/dotnet/docs/docfx.json @@ -3,29 +3,40 @@ { "src": [ { + "src": "../src/webdriver", "files": [ - "src/webdriver/WebDriver.csproj", - "src/support/WebDriver.Support.csproj", - "bin/**/*.dll" - ], - "src": "../" + "**/*.csproj" + ] } ], - "dest": "api", - "includePrivateMembers": false, - "disableGitFeatures": false, - "disableDefaultFilter": false, - "noRestore": false, - "namespaceLayout": "flattened", - "memberLayout": "samePage", - "allowCompilationErrors": false + "dest": "webdriver", + "namespaceLayout": "nested", + "outputFormat": "apiPage" + }, + { + "src": [ + { + "src": "../src/support", + "files": [ + "**/*.csproj" + ] + } + ], + "dest": "support", + "namespaceLayout": "nested", + "outputFormat": "apiPage" } + ], "build": { "content": [ { - "files": "**/*.{md|yml}", - "src": "api" + "files": [ + "**/*.{md,yml}" + ], + "exclude": [ + "_site/**" + ] } ], "resource": [ @@ -35,15 +46,16 @@ ] } ], - "dest": "../../build/docs/api/dotnet", - "globalMetadataFiles": [], - "fileMetadataFiles": [], + "output": "../../build/docs/api/dotnet", "template": [ "default", "modern" ], - "postProcessors": [], - "keepFileLink": false, - "disableGitFeatures": false + "globalMetadata": { + "_appName": "Selenium .NET API", + "_appLogoPath": "images/logo.svg", + "_appFaviconPath": "images/favicon.ico", + "_enableSearch": true + } } } diff --git a/dotnet/docs/images/favicon.ico b/dotnet/docs/images/favicon.ico new file mode 100644 index 0000000000000..80bf7ae9a9ac5 Binary files /dev/null and b/dotnet/docs/images/favicon.ico differ diff --git a/dotnet/docs/images/logo.svg b/dotnet/docs/images/logo.svg new file mode 100644 index 0000000000000..5c58484a6f7ab --- /dev/null +++ b/dotnet/docs/images/logo.svg @@ -0,0 +1 @@ +Selenium logo mark green \ No newline at end of file diff --git a/dotnet/docs/index.md b/dotnet/docs/index.md new file mode 100644 index 0000000000000..4bf895581a8ed --- /dev/null +++ b/dotnet/docs/index.md @@ -0,0 +1,9 @@ +--- +layout: landingPage +--- + +# Welcome to the Selenium .NET API Docs + +## Modules +- [Selenium.WebDriver](/webdriver/OpenQA.Selenium.html) +- [Selenium.Support](/support/OpenQA.Selenium.Support.html) \ No newline at end of file diff --git a/dotnet/docs/api/.gitignore b/dotnet/docs/support/.gitignore similarity index 100% rename from dotnet/docs/api/.gitignore rename to dotnet/docs/support/.gitignore diff --git a/dotnet/docs/toc.yml b/dotnet/docs/toc.yml new file mode 100644 index 0000000000000..3198b53999c8e --- /dev/null +++ b/dotnet/docs/toc.yml @@ -0,0 +1,9 @@ +- name: Intro + href: index.md + +- name: Modules + items: + - name: WebDriver + href: webdriver/OpenQA.Selenium.yml + - name: Support + href: support/OpenQA.Selenium.Support.yml diff --git a/dotnet/docs/webdriver/.gitignore b/dotnet/docs/webdriver/.gitignore new file mode 100644 index 0000000000000..e8079a3bef9d6 --- /dev/null +++ b/dotnet/docs/webdriver/.gitignore @@ -0,0 +1,5 @@ +############### +# temp file # +############### +*.yml +.manifest diff --git a/dotnet/src/webdriver/Command.cs b/dotnet/src/webdriver/Command.cs index e6d7c422cbc1e..9d86667dea4e8 100644 --- a/dotnet/src/webdriver/Command.cs +++ b/dotnet/src/webdriver/Command.cs @@ -151,18 +151,33 @@ private static Dictionary ConvertParametersFromJson(string value [JsonSerializable(typeof(ulong))] [JsonSerializable(typeof(short))] [JsonSerializable(typeof(ushort))] - [JsonSerializable(typeof(string))] // Selenium WebDriver types [JsonSerializable(typeof(char[]))] [JsonSerializable(typeof(byte[]))] - [JsonSerializable(typeof(Dictionary))] + [JsonSerializable(typeof(Chromium.ChromiumNetworkConditions))] [JsonSerializable(typeof(Cookie))] [JsonSerializable(typeof(ReturnedCookie))] [JsonSerializable(typeof(Proxy))] - internal partial class CommandJsonSerializerContext : JsonSerializerContext - { - } + // Selenium Dictionaries, primarily used in Capabilities + [JsonSerializable(typeof(Dictionary))] + [JsonSerializable(typeof(Dictionary))] + [JsonSerializable(typeof(Dictionary))] + [JsonSerializable(typeof(Dictionary))] + [JsonSerializable(typeof(Dictionary))] + [JsonSerializable(typeof(Dictionary))] + [JsonSerializable(typeof(Dictionary))] + [JsonSerializable(typeof(Dictionary))] + [JsonSerializable(typeof(Dictionary))] + [JsonSerializable(typeof(Dictionary))] + [JsonSerializable(typeof(Dictionary))] + [JsonSerializable(typeof(Dictionary))] + [JsonSerializable(typeof(Dictionary))] + [JsonSerializable(typeof(Dictionary))] + [JsonSerializable(typeof(Dictionary))] + [JsonSerializable(typeof(Dictionary))] + [JsonSerializable(typeof(Dictionary))] + internal partial class CommandJsonSerializerContext : JsonSerializerContext; } diff --git a/dotnet/src/webdriver/Interactions/ActionSequence.cs b/dotnet/src/webdriver/Interactions/ActionSequence.cs index 68eabbea00f2b..7aebebd8a3b35 100644 --- a/dotnet/src/webdriver/Interactions/ActionSequence.cs +++ b/dotnet/src/webdriver/Interactions/ActionSequence.cs @@ -29,7 +29,6 @@ namespace OpenQA.Selenium.Interactions public class ActionSequence { private List interactions = new List(); - private InputDevice device; /// /// Initializes a new instance of the class. @@ -52,7 +51,7 @@ public ActionSequence(InputDevice device, int initialSize) throw new ArgumentNullException(nameof(device), "Input device cannot be null."); } - this.device = device; + this.InputDevice = device; for (int i = 0; i < initialSize; i++) { @@ -71,10 +70,13 @@ public int Count /// /// Gets the input device for this Action sequence. /// - public InputDevice inputDevice - { - get { return this.inputDevice; } - } + [Obsolete("This property has been renamed to InputDevice and will be removed in a future version")] + public InputDevice inputDevice => InputDevice; + + /// + /// Gets the input device for this Action sequence. + /// + public InputDevice InputDevice { get; } /// /// Adds an action to the sequence. @@ -88,9 +90,9 @@ public ActionSequence AddAction(Interaction interactionToAdd) throw new ArgumentNullException(nameof(interactionToAdd), "Interaction to add to sequence must not be null"); } - if (!interactionToAdd.IsValidFor(this.device.DeviceKind)) + if (!interactionToAdd.IsValidFor(this.InputDevice.DeviceKind)) { - throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "Interaction {0} is invalid for device type {1}.", interactionToAdd.GetType(), this.device.DeviceKind), nameof(interactionToAdd)); + throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "Interaction {0} is invalid for device type {1}.", interactionToAdd.GetType(), this.InputDevice.DeviceKind), nameof(interactionToAdd)); } this.interactions.Add(interactionToAdd); @@ -103,7 +105,7 @@ public ActionSequence AddAction(Interaction interactionToAdd) /// A containing the actions in this sequence. public Dictionary ToDictionary() { - Dictionary toReturn = this.device.ToDictionary(); + Dictionary toReturn = this.InputDevice.ToDictionary(); List encodedActions = new List(); foreach (Interaction action in this.interactions) @@ -122,7 +124,7 @@ public Dictionary ToDictionary() /// A string that represents the current . public override string ToString() { - StringBuilder builder = new StringBuilder("Action sequence - ").Append(this.device.ToString()); + StringBuilder builder = new StringBuilder("Action sequence - ").Append(this.InputDevice.ToString()); foreach (Interaction action in this.interactions) { builder.AppendLine(); diff --git a/dotnet/src/webdriver/Interactions/Actions.cs b/dotnet/src/webdriver/Interactions/Actions.cs index dddde06781b7a..36c58a925b78b 100644 --- a/dotnet/src/webdriver/Interactions/Actions.cs +++ b/dotnet/src/webdriver/Interactions/Actions.cs @@ -31,16 +31,15 @@ public class Actions : IAction private PointerInputDevice activePointer; private KeyInputDevice activeKeyboard; private WheelInputDevice activeWheel; - private IActionExecutor actionExecutor; /// /// Initializes a new instance of the class. /// /// The object on which the actions built will be performed. + /// If does not implement . public Actions(IWebDriver driver) : this(driver, TimeSpan.FromMilliseconds(250)) { - } /// @@ -48,6 +47,7 @@ public Actions(IWebDriver driver) /// /// The object on which the actions built will be performed. /// How long durable action is expected to take. + /// If does not implement . public Actions(IWebDriver driver, TimeSpan duration) { IActionExecutor actionExecutor = GetDriverAs(driver); @@ -56,7 +56,7 @@ public Actions(IWebDriver driver, TimeSpan duration) throw new ArgumentException("The IWebDriver object must implement or wrap a driver that implements IActionExecutor.", nameof(driver)); } - this.actionExecutor = actionExecutor; + this.ActionExecutor = actionExecutor; this.duration = duration; } @@ -64,10 +64,7 @@ public Actions(IWebDriver driver, TimeSpan duration) /// /// Returns the for the driver. /// - protected IActionExecutor ActionExecutor - { - get { return this.actionExecutor; } - } + protected IActionExecutor ActionExecutor { get; } /// /// Sets the active pointer device for this Actions class. @@ -75,33 +72,17 @@ protected IActionExecutor ActionExecutor /// The kind of pointer device to set as active. /// The name of the pointer device to set as active. /// A self-reference to this Actions class. + /// If a device with this name exists but is not a pointer. public Actions SetActivePointer(PointerKind kind, string name) { - IList sequences = this.actionBuilder.ToActionSequenceList(); + InputDevice device = FindDeviceById(name); - InputDevice device = null; - - foreach (var sequence in sequences) + this.activePointer = device switch { - Dictionary actions = sequence.ToDictionary(); - - string id = (string)actions["id"]; - - if (id == name) - { - device = sequence.inputDevice; - break; - } - } - - if (device == null) - { - this.activePointer = new PointerInputDevice(kind, name); - } - else - { - this.activePointer = (PointerInputDevice)device; - } + null => new PointerInputDevice(kind, name), + PointerInputDevice pointerDevice => pointerDevice, + _ => throw new InvalidOperationException($"Device under the name \"{name}\" is not a pointer. Actual input type: {device.DeviceKind}"), + }; return this; } @@ -111,33 +92,17 @@ public Actions SetActivePointer(PointerKind kind, string name) /// /// The name of the keyboard device to set as active. /// A self-reference to this Actions class. + /// If a device with this name exists but is not a keyboard. public Actions SetActiveKeyboard(string name) { - IList sequences = this.actionBuilder.ToActionSequenceList(); + InputDevice device = FindDeviceById(name); - InputDevice device = null; - - foreach (var sequence in sequences) + this.activeKeyboard = device switch { - Dictionary actions = sequence.ToDictionary(); - - string id = (string)actions["id"]; - - if (id == name) - { - device = sequence.inputDevice; - break; - } - } - - if (device == null) - { - this.activeKeyboard = new KeyInputDevice(name); - } - else - { - this.activeKeyboard = (KeyInputDevice)device; - } + null => new KeyInputDevice(name), + KeyInputDevice keyDevice => keyDevice, + _ => throw new InvalidOperationException($"Device under the name \"{name}\" is not a keyboard. Actual input type: {device.DeviceKind}"), + }; return this; } @@ -147,13 +112,24 @@ public Actions SetActiveKeyboard(string name) /// /// The name of the wheel device to set as active. /// A self-reference to this Actions class. + /// If a device with this name exists but is not a wheel. public Actions SetActiveWheel(string name) { - IList sequences = this.actionBuilder.ToActionSequenceList(); + InputDevice device = FindDeviceById(name); + + this.activeWheel = device switch + { + null => new WheelInputDevice(name), + WheelInputDevice wheelDevice => wheelDevice, + _ => throw new InvalidOperationException($"Device under the name \"{name}\" is not a wheel. Actual input type: {device.DeviceKind}"), + }; - InputDevice device = null; + return this; + } - foreach (var sequence in sequences) + private InputDevice FindDeviceById(string name) + { + foreach (var sequence in this.actionBuilder.ToActionSequenceList()) { Dictionary actions = sequence.ToDictionary(); @@ -161,21 +137,11 @@ public Actions SetActiveWheel(string name) if (id == name) { - device = sequence.inputDevice; - break; + return sequence.inputDevice; } } - if (device == null) - { - this.activeWheel = new WheelInputDevice(name); - } - else - { - this.activeWheel = (WheelInputDevice)device; - } - - return this; + return null; } /// @@ -619,7 +585,7 @@ public IAction Build() /// public void Perform() { - this.actionExecutor.PerformActions(this.actionBuilder.ToActionSequenceList()); + this.ActionExecutor.PerformActions(this.actionBuilder.ToActionSequenceList()); this.actionBuilder.ClearSequences(); } diff --git a/dotnet/test/common/Interactions/CombinedInputActionsTest.cs b/dotnet/test/common/Interactions/CombinedInputActionsTest.cs index 483f1204b7ca8..711259b785aa5 100644 --- a/dotnet/test/common/Interactions/CombinedInputActionsTest.cs +++ b/dotnet/test/common/Interactions/CombinedInputActionsTest.cs @@ -397,6 +397,37 @@ public void PerformsPause() Assert.IsTrue(DateTime.Now - start > TimeSpan.FromMilliseconds(1200)); } + [Test] + public void ShouldHandleClashingDeviceNamesGracefully() + { + var actionsWithPointer = new Actions(driver) + .SetActivePointer(PointerKind.Mouse, "test") + .Click(); + + Assert.That(() => + { + actionsWithPointer.SetActiveWheel("test"); + }, Throws.InvalidOperationException.With.Message.EqualTo("Device under the name \"test\" is not a wheel. Actual input type: Pointer")); + + var actionsWithKeyboard = new Actions(driver) + .SetActiveKeyboard("test") + .KeyDown(Keys.Shift).KeyUp(Keys.Shift); + + Assert.That(() => + { + actionsWithKeyboard.SetActivePointer(PointerKind.Pen, "test"); + }, Throws.InvalidOperationException.With.Message.EqualTo("Device under the name \"test\" is not a pointer. Actual input type: Key")); + + var actionsWithWheel = new Actions(driver) + .SetActiveWheel("test") + .ScrollByAmount(0, 0); + + Assert.That(() => + { + actionsWithWheel.SetActiveKeyboard("test"); + }, Throws.InvalidOperationException.With.Message.EqualTo("Device under the name \"test\" is not a keyboard. Actual input type: Wheel")); + } + private bool FuzzyPositionMatching(int expectedX, int expectedY, string locationTuple) { string[] splitString = locationTuple.Split(','); diff --git a/java/maven_install.json b/java/maven_install.json index 9034f3dee04b2..ec5875743dc1a 100644 --- a/java/maven_install.json +++ b/java/maven_install.json @@ -1,7 +1,7 @@ { "__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL", - "__INPUT_ARTIFACTS_HASH": 282748108, - "__RESOLVED_ARTIFACTS_HASH": 1016391538, + "__INPUT_ARTIFACTS_HASH": -1685742929, + "__RESOLVED_ARTIFACTS_HASH": -1218025727, "conflict_resolution": { "com.google.code.gson:gson:2.8.9": "com.google.code.gson:gson:2.11.0", "com.google.errorprone:error_prone_annotations:2.3.2": "com.google.errorprone:error_prone_annotations:2.28.0", @@ -243,17 +243,17 @@ }, "io.grpc:grpc-api": { "shasums": { - "jar": "b5120a11da5ce5ddfab019bbb69f5868529c9b5def1ba5b283251cc95fb3ba91", - "sources": "3e4b31496f2c8b7cd51b425af767c72d44b38fdbb56a6e8c247acb8a721c4e8c" + "jar": "d88d815e07fe58a7572dda5d2823485b61706564f289a1e74281705d50ac2d5b", + "sources": "791d817c56f03690df499020479e23494b79ab6ed578f4f50285d83d45a1f35d" }, - "version": "1.68.0" + "version": "1.68.1" }, "io.grpc:grpc-context": { "shasums": { - "jar": "45f85a394466f963f1f7a5c5555e6dda35efd05ce1c687203a217d7048f6f089", - "sources": "31d4fc1054b5c0bc75924e82ca425dcf624f895e7525da900b94cfa87a2bea53" + "jar": "1df4f0310a7e7836bc2948afa95105f5ee27b5d468488aded74e7ff620359076", + "sources": "6f5941f8531f6eea4ff922d2019757d06dc5857327ff9b9858ace45c0cf0ef8b" }, - "version": "1.68.0" + "version": "1.68.1" }, "io.lettuce:lettuce-core": { "shasums": { @@ -444,13 +444,6 @@ }, "version": "1.43.0" }, - "io.ous:jtoml": { - "shasums": { - "jar": "3cabdae2244c999addebb8c31ae452fbdc874b4f26a163539954b8eeb5d6acc6", - "sources": "f479f2acdf7a362dc86a5c9310ddaec7b34a87f0a8a6f46dde41c1069b2a2138" - }, - "version": "2.0.0" - }, "io.projectreactor:reactor-core": { "shasums": { "jar": "44f055fbd033b6c976c53fb2e04b59027e79fb2312c37d2eaa54c77ea1ea80fe", @@ -495,10 +488,10 @@ }, "net.bytebuddy:byte-buddy": { "shasums": { - "jar": "7f77ee7ae0a6f420218546424a92fc6c964ed5788b21a2559d6be177c5e1a718", - "sources": "d19281fa34e46008ff096ec955659f94c81df9a3301109e33503ac15f9e1c44d" + "jar": "d8390d20685a41a2bdca640f958942cd91bcbf21c42470494bdf5752d9a07b14", + "sources": "254ea80bf6f932e785b6f7dcdf3666b6fad4ceea36ef187c064a5346c650cb2c" }, - "version": "1.15.7" + "version": "1.15.10" }, "net.bytebuddy:byte-buddy-agent": { "shasums": { @@ -514,6 +507,13 @@ }, "version": "12.4" }, + "org.antlr:antlr4-runtime": { + "shasums": { + "jar": "e06c6553c1ccc14d36052ec4b0fc6f13b808cf957b5b1dc3f61bf401996ada59", + "sources": "6fa0efb711a152842ecda1d41ceab94fb2049f833e00e360e161ac0e7a3819fe" + }, + "version": "4.11.1" + }, "org.apache.bcel:bcel": { "shasums": { "jar": "a119a4420350dea669acfd84120ecc7e5742dcabcc82b0b9f9755dc692335aa2", @@ -801,6 +801,13 @@ }, "version": "1.7.21" }, + "org.tomlj:tomlj": { + "shasums": { + "jar": "383b7c66966c42ee4913ec977a7b6573631866bddc5318ec4a6215b688dd0d6c", + "sources": "533276104d58ebc92ce049c59a129717ce7daf0e9340969256fdb61f4f06f717" + }, + "version": "1.1.1" + }, "org.xmlresolver:xmlresolver": { "shasums": { "data": "173904bdbd783ba0fac92c5bcc05da5d09f0ce7eed24346666ea0a239461f9b4", @@ -1159,6 +1166,10 @@ "org.slf4j:slf4j-simple": [ "org.slf4j:slf4j-api" ], + "org.tomlj:tomlj": [ + "org.antlr:antlr4-runtime", + "org.checkerframework:checker-qual" + ], "org.xmlresolver:xmlresolver": [ "org.apache.httpcomponents.client5:httpclient5", "org.apache.httpcomponents.core5:httpcore5" @@ -1786,10 +1797,6 @@ "io.opentelemetry.sdk.trace.internal.data", "io.opentelemetry.sdk.trace.samplers" ], - "io.ous:jtoml": [ - "io.ous.jtoml", - "io.ous.jtoml.impl" - ], "io.projectreactor:reactor-core": [ "reactor.adapter", "reactor.core", @@ -2014,6 +2021,15 @@ "net.sf.saxon.xpath", "net.sf.saxon.z" ], + "org.antlr:antlr4-runtime": [ + "org.antlr.v4.runtime", + "org.antlr.v4.runtime.atn", + "org.antlr.v4.runtime.dfa", + "org.antlr.v4.runtime.misc", + "org.antlr.v4.runtime.tree", + "org.antlr.v4.runtime.tree.pattern", + "org.antlr.v4.runtime.tree.xpath" + ], "org.apache.bcel:bcel": [ "org.apache.bcel", "org.apache.bcel.classfile", @@ -2898,6 +2914,10 @@ "org.slf4j:slf4j-simple": [ "org.slf4j.impl" ], + "org.tomlj:tomlj": [ + "org.tomlj", + "org.tomlj.internal" + ], "org.xmlresolver:xmlresolver": [ "org.xmlresolver", "org.xmlresolver.cache", @@ -3095,8 +3115,6 @@ "io.opentelemetry:opentelemetry-sdk-trace", "io.opentelemetry:opentelemetry-sdk-trace:jar:sources", "io.opentelemetry:opentelemetry-sdk:jar:sources", - "io.ous:jtoml", - "io.ous:jtoml:jar:sources", "io.projectreactor:reactor-core", "io.projectreactor:reactor-core:jar:sources", "io.reactivex.rxjava3:rxjava", @@ -3115,6 +3133,8 @@ "net.bytebuddy:byte-buddy:jar:sources", "net.sf.saxon:Saxon-HE", "net.sf.saxon:Saxon-HE:jar:sources", + "org.antlr:antlr4-runtime", + "org.antlr:antlr4-runtime:jar:sources", "org.apache.bcel:bcel", "org.apache.bcel:bcel:jar:sources", "org.apache.commons:commons-exec", @@ -3197,6 +3217,8 @@ "org.slf4j:slf4j-jdk14:jar:sources", "org.slf4j:slf4j-simple", "org.slf4j:slf4j-simple:jar:sources", + "org.tomlj:tomlj", + "org.tomlj:tomlj:jar:sources", "org.xmlresolver:xmlresolver", "org.xmlresolver:xmlresolver:jar:data", "org.xmlresolver:xmlresolver:jar:sources", diff --git a/java/src/org/openqa/selenium/By.java b/java/src/org/openqa/selenium/By.java index 7a03e34bf5b0b..5ed367d994a09 100644 --- a/java/src/org/openqa/selenium/By.java +++ b/java/src/org/openqa/selenium/By.java @@ -121,7 +121,7 @@ public static By cssSelector(String cssSelector) { public WebElement findElement(SearchContext context) { List allElements = findElements(context); if (allElements == null || allElements.isEmpty()) { - throw new NoSuchElementException("Cannot locate an element using " + toString()); + throw new NoSuchElementException("Cannot locate an element using " + this); } return allElements.get(0); } diff --git a/java/src/org/openqa/selenium/JavascriptExecutor.java b/java/src/org/openqa/selenium/JavascriptExecutor.java index a744eb8d8df91..056935aaa4a8b 100644 --- a/java/src/org/openqa/selenium/JavascriptExecutor.java +++ b/java/src/org/openqa/selenium/JavascriptExecutor.java @@ -17,7 +17,6 @@ package org.openqa.selenium; -import java.util.Collections; import java.util.Set; import java.util.stream.Collectors; import org.jspecify.annotations.NullMarked; @@ -177,10 +176,9 @@ default void unpin(ScriptKey key) { * @return The {@link ScriptKey}s of all currently pinned scripts. */ default Set getPinnedScripts() { - return Collections.unmodifiableSet( - UnpinnedScriptKey.getPinnedScripts(this).stream() - .map(key -> (ScriptKey) key) - .collect(Collectors.toSet())); + return UnpinnedScriptKey.getPinnedScripts(this).stream() + .map(key -> (ScriptKey) key) + .collect(Collectors.toUnmodifiableSet()); } /** diff --git a/java/src/org/openqa/selenium/WebElement.java b/java/src/org/openqa/selenium/WebElement.java index 8f9029ec2fd97..05b661d16179b 100644 --- a/java/src/org/openqa/selenium/WebElement.java +++ b/java/src/org/openqa/selenium/WebElement.java @@ -165,7 +165,10 @@ public interface WebElement extends SearchContext, TakesScreenshot { * * @param name The name of the attribute. * @return The attribute/property's current value or null if the value is not set. + * @deprecated This method is deprecated. Use {@link #getDomProperty(String)} or {@link + * #getDomAttribute(String)} for more precise attribute retrieval. */ + @Deprecated @Nullable String getAttribute(String name); /** diff --git a/java/src/org/openqa/selenium/grid/config/BUILD.bazel b/java/src/org/openqa/selenium/grid/config/BUILD.bazel index 65662cda6c5dd..e2be2a4b14de7 100644 --- a/java/src/org/openqa/selenium/grid/config/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/config/BUILD.bazel @@ -21,6 +21,6 @@ java_library( "//java/src/org/openqa/selenium/json", artifact("com.beust:jcommander"), artifact("com.google.guava:guava"), - artifact("io.ous:jtoml"), + artifact("org.tomlj:tomlj"), ], ) diff --git a/java/src/org/openqa/selenium/grid/config/TomlConfig.java b/java/src/org/openqa/selenium/grid/config/TomlConfig.java index cc6f2daa84608..991c6a9f42fa2 100644 --- a/java/src/org/openqa/selenium/grid/config/TomlConfig.java +++ b/java/src/org/openqa/selenium/grid/config/TomlConfig.java @@ -19,10 +19,6 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSortedSet; -import io.ous.jtoml.JToml; -import io.ous.jtoml.ParseException; -import io.ous.jtoml.Toml; -import io.ous.jtoml.TomlTable; import java.io.IOException; import java.io.Reader; import java.nio.file.Files; @@ -31,23 +27,31 @@ import java.util.List; import java.util.Optional; import java.util.Set; -import java.util.logging.Logger; +import java.util.stream.Collectors; import org.openqa.selenium.internal.Require; +import org.tomlj.Toml; +import org.tomlj.TomlArray; +import org.tomlj.TomlParseError; +import org.tomlj.TomlParseResult; +import org.tomlj.TomlTable; public class TomlConfig implements Config { - private final Toml toml; - private static final Logger LOG = Logger.getLogger(TomlConfig.class.getName()); + private final TomlParseResult toml; public TomlConfig(Reader reader) { try { - toml = JToml.parse(reader); - LOG.warning( - "Please use quotes to denote strings. Upcoming TOML parser will require this and unquoted" - + " strings will throw an error in the future"); + toml = Toml.parse(reader); + + if (toml.hasErrors()) { + String error = + toml.errors().stream().map(TomlParseError::toString).collect(Collectors.joining("\n")); + + throw new ConfigException(error); + } } catch (IOException e) { throw new ConfigException("Unable to read TOML.", e); - } catch (ParseException e) { + } catch (TomlParseError e) { throw new ConfigException( e.getCause() + "\n Validate the config using https://www.toml-lint.com/. " @@ -70,7 +74,7 @@ public Optional> getAll(String section, String option) { Require.nonNull("Section to read", section); Require.nonNull("Option to read", option); - if (!toml.containsKey(section)) { + if (!toml.contains(section)) { return Optional.empty(); } @@ -79,21 +83,28 @@ public Optional> getAll(String section, String option) { throw new ConfigException(String.format("Section %s is not a section! %s", section, raw)); } - TomlTable table = toml.getTomlTable(section); + TomlTable table = toml.getTable(section); + Object value = null; + if (table != null) { + value = table.get(option); + } - Object value = table.getOrDefault(option, null); if (value == null) { return Optional.empty(); } + if (value instanceof TomlArray) { + value = ((TomlArray) value).toList(); + } + if (value instanceof Collection) { Collection collection = (Collection) value; // Case when an array of tables is used as config // https://toml.io/en/v1.0.0-rc.3#array-of-tables - if (collection.stream().anyMatch(item -> item instanceof TomlTable)) { + if (collection.stream().anyMatch(TomlTable.class::isInstance)) { return Optional.of( collection.stream() - .map(item -> (TomlTable) item) + .map(TomlTable.class::cast) .map(TomlTable::toMap) .map(this::toEntryList) .flatMap(Collection::stream) @@ -111,7 +122,7 @@ public Optional> getAll(String section, String option) { return Optional.of(toEntryList(((TomlTable) value).toMap())); } - return Optional.of(ImmutableList.of(String.valueOf(value))); + return Optional.of(List.of(String.valueOf(value))); } @Override diff --git a/java/src/org/openqa/selenium/grid/node/ForwardWebDriverCommand.java b/java/src/org/openqa/selenium/grid/node/ForwardWebDriverCommand.java index fadcfff4c80fd..65be23ab4aadc 100644 --- a/java/src/org/openqa/selenium/grid/node/ForwardWebDriverCommand.java +++ b/java/src/org/openqa/selenium/grid/node/ForwardWebDriverCommand.java @@ -17,11 +17,11 @@ package org.openqa.selenium.grid.node; -import static java.net.HttpURLConnection.HTTP_INTERNAL_ERROR; +import static java.net.HttpURLConnection.HTTP_NOT_FOUND; import static org.openqa.selenium.remote.HttpSessionId.getSessionId; import static org.openqa.selenium.remote.http.Contents.asJson; -import com.google.common.collect.ImmutableMap; +import java.util.Map; import org.openqa.selenium.internal.Require; import org.openqa.selenium.remote.SessionId; import org.openqa.selenium.remote.http.HttpHandler; @@ -48,10 +48,16 @@ public HttpResponse execute(HttpRequest req) { return node.executeWebDriverCommand(req); } return new HttpResponse() - .setStatus(HTTP_INTERNAL_ERROR) + .setStatus(HTTP_NOT_FOUND) .setContent( asJson( - ImmutableMap.of( - "error", String.format("Session not found in node %s", node.getId())))); + Map.of( + "value", + Map.of( + "error", "invalid session id", + "message", + "Cannot find session with id: " + + getSessionId(req.getUri()).orElse(null), + "stacktrace", "")))); } } diff --git a/java/src/org/openqa/selenium/grid/node/Node.java b/java/src/org/openqa/selenium/grid/node/Node.java index bc2b5c75b5ab7..68767fa0a26b9 100644 --- a/java/src/org/openqa/selenium/grid/node/Node.java +++ b/java/src/org/openqa/selenium/grid/node/Node.java @@ -154,12 +154,7 @@ protected Node( combine( // "getSessionId" is aggressive about finding session ids, so this needs to be the last // route that is checked. - matching( - req -> - getSessionId(req.getUri()) - .map(SessionId::new) - .map(sessionId -> this.getSession(sessionId) != null) - .orElse(false)) + matching(req -> getSessionId(req.getUri()).map(SessionId::new).isPresent()) .to(() -> new ForwardWebDriverCommand(this)) .with(spanDecorator("node.forward_command")), new CustomLocatorHandler(this, registrationSecret, customLocators), diff --git a/java/src/org/openqa/selenium/netty/server/RequestConverter.java b/java/src/org/openqa/selenium/netty/server/RequestConverter.java index d245530963922..6cb1c91ab3eb5 100644 --- a/java/src/org/openqa/selenium/netty/server/RequestConverter.java +++ b/java/src/org/openqa/selenium/netty/server/RequestConverter.java @@ -96,7 +96,7 @@ protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Ex length = -1; } - if (msg instanceof HttpContent) { + if (request != null && msg instanceof HttpContent) { ByteBuf buf = ((HttpContent) msg).content().retain(); int nBytes = buf.readableBytes(); diff --git a/java/src/org/openqa/selenium/remote/http/FormEncodedData.java b/java/src/org/openqa/selenium/remote/http/FormEncodedData.java deleted file mode 100644 index 7d920e23d4694..0000000000000 --- a/java/src/org/openqa/selenium/remote/http/FormEncodedData.java +++ /dev/null @@ -1,95 +0,0 @@ -// 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. - -package org.openqa.selenium.remote.http; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.UncheckedIOException; -import java.net.URLDecoder; -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.atomic.AtomicBoolean; - -@Deprecated(forRemoval = true) // should be moved to testing -public class FormEncodedData { - - public static Optional>> getData(HttpRequest request) { - try { - String contentType = request.getHeader("Content-Type"); - if (contentType == null - || !contentType.split(";")[0].trim().equals("application/x-www-form-urlencoded")) { - return Optional.empty(); - } - } catch (IllegalArgumentException | NullPointerException e) { - return Optional.empty(); - } - - // Maintain ordering of keys. - Map> data = new LinkedHashMap<>(); - AtomicBoolean eof = new AtomicBoolean(false); - Charset encoding = request.getContentEncoding(); - try (InputStream is = request.getContent().get(); - Reader reader = new InputStreamReader(is, request.getContentEncoding())) { - - while (!eof.get()) { - String key = read(reader, encoding, '=', eof); - String value = read(reader, encoding, '&', eof); - - data.computeIfAbsent(key, (k) -> new ArrayList<>()).add(value == null ? "" : value); - } - } catch (IOException e) { - throw new UncheckedIOException(e); - } - - // We want to return a Map>, not a Map> so, ugh. - Map> toReturn = new LinkedHashMap<>(); - for (Map.Entry> entry : data.entrySet()) { - toReturn.put(entry.getKey(), List.copyOf(entry.getValue())); - } - return Optional.of(Map.copyOf(toReturn)); - } - - private static String read(Reader reader, Charset charSet, char delimiter, AtomicBoolean eof) - throws IOException { - if (eof.get()) { - return null; - } - - StringBuilder builder = new StringBuilder(); - for (; ; ) { - int i = reader.read(); - if (i == -1) { - eof.set(true); - break; - } - char c = (char) i; - if (c == delimiter) { - break; - } - builder.append(c); - } - - return URLDecoder.decode(builder.toString(), charSet); - } -} diff --git a/java/src/org/openqa/selenium/support/pagefactory/ByAll.java b/java/src/org/openqa/selenium/support/pagefactory/ByAll.java index 0a9e0988bc0fc..8ee9e0bee71d5 100644 --- a/java/src/org/openqa/selenium/support/pagefactory/ByAll.java +++ b/java/src/org/openqa/selenium/support/pagefactory/ByAll.java @@ -54,7 +54,7 @@ public WebElement findElement(SearchContext context) { return elements.get(0); } } - throw new NoSuchElementException("Cannot locate an element using " + toString()); + throw new NoSuchElementException("Cannot locate an element using " + this); } @Override diff --git a/java/src/org/openqa/selenium/support/pagefactory/ByChained.java b/java/src/org/openqa/selenium/support/pagefactory/ByChained.java index 5d631cc254c24..2beb51681c1b5 100644 --- a/java/src/org/openqa/selenium/support/pagefactory/ByChained.java +++ b/java/src/org/openqa/selenium/support/pagefactory/ByChained.java @@ -52,7 +52,7 @@ public ByChained(By... bys) { public WebElement findElement(SearchContext context) { List elements = findElements(context); if (elements.isEmpty()) - throw new NoSuchElementException("Cannot locate an element using " + toString()); + throw new NoSuchElementException("Cannot locate an element using " + this); return elements.get(0); } diff --git a/java/test/org/openqa/selenium/CookieImplementationTest.java b/java/test/org/openqa/selenium/CookieImplementationTest.java index 46f3d4b9d7f15..5da0b5f408991 100644 --- a/java/test/org/openqa/selenium/CookieImplementationTest.java +++ b/java/test/org/openqa/selenium/CookieImplementationTest.java @@ -35,10 +35,12 @@ import org.openqa.selenium.environment.DomainHelper; import org.openqa.selenium.testing.Ignore; import org.openqa.selenium.testing.JupiterTestBase; +import org.openqa.selenium.testing.NeedsSecureServer; import org.openqa.selenium.testing.NotWorkingInRemoteBazelBuilds; import org.openqa.selenium.testing.NotYetImplemented; import org.openqa.selenium.testing.SwitchToTopAfterTest; +@NeedsSecureServer class CookieImplementationTest extends JupiterTestBase { private DomainHelper domainHelper; diff --git a/java/test/org/openqa/selenium/PageLoadingTest.java b/java/test/org/openqa/selenium/PageLoadingTest.java index 545d236248f9a..e5a792b8dcc87 100644 --- a/java/test/org/openqa/selenium/PageLoadingTest.java +++ b/java/test/org/openqa/selenium/PageLoadingTest.java @@ -36,10 +36,12 @@ import org.openqa.selenium.testing.Ignore; import org.openqa.selenium.testing.JupiterTestBase; import org.openqa.selenium.testing.NeedsFreshDriver; +import org.openqa.selenium.testing.NeedsSecureServer; import org.openqa.selenium.testing.NoDriverAfterTest; import org.openqa.selenium.testing.NotYetImplemented; import org.openqa.selenium.testing.SwitchToTopAfterTest; +@NeedsSecureServer class PageLoadingTest extends JupiterTestBase { @Test diff --git a/java/test/org/openqa/selenium/WebNetworkTest.java b/java/test/org/openqa/selenium/WebNetworkTest.java index 8036b5edce59b..3ad732b8ff6b2 100644 --- a/java/test/org/openqa/selenium/WebNetworkTest.java +++ b/java/test/org/openqa/selenium/WebNetworkTest.java @@ -22,33 +22,19 @@ import java.net.URI; import java.util.function.Predicate; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.openqa.selenium.environment.webserver.AppServer; -import org.openqa.selenium.environment.webserver.NettyAppServer; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.testing.Ignore; import org.openqa.selenium.testing.JupiterTestBase; +import org.openqa.selenium.testing.NeedsFreshDriver; import org.openqa.selenium.testing.drivers.Browser; class WebNetworkTest extends JupiterTestBase { private String page; - private AppServer server; - - @BeforeEach - public void setUp() { - server = new NettyAppServer(); - server.start(); - } - - @AfterEach - public void cleanUp() { - driver.quit(); - } @Test + @NeedsFreshDriver @Ignore(Browser.CHROME) @Ignore(Browser.EDGE) void canAddAuthenticationHandler() { @@ -56,13 +42,14 @@ void canAddAuthenticationHandler() { .network() .addAuthenticationHandler(new UsernameAndPassword("test", "test")); - page = server.whereIs("basicAuth"); + page = appServer.whereIs("basicAuth"); driver.get(page); assertThat(driver.findElement(By.tagName("h1")).getText()).isEqualTo("authorized"); } @Test + @NeedsFreshDriver @Ignore(Browser.CHROME) @Ignore(Browser.EDGE) void canAddAuthenticationHandlerWithFilter() { @@ -72,13 +59,14 @@ void canAddAuthenticationHandlerWithFilter() { .network() .addAuthenticationHandler(filter, new UsernameAndPassword("test", "test")); - page = server.whereIs("basicAuth"); + page = appServer.whereIs("basicAuth"); driver.get(page); assertThat(driver.findElement(By.tagName("h1")).getText()).isEqualTo("authorized"); } @Test + @NeedsFreshDriver @Ignore(Browser.CHROME) @Ignore(Browser.EDGE) void canAddMultipleAuthenticationHandlersWithFilter() { @@ -92,13 +80,14 @@ void canAddMultipleAuthenticationHandlersWithFilter() { .addAuthenticationHandler( uri -> uri.getPath().contains("test"), new UsernameAndPassword("test1", "test1")); - page = server.whereIs("basicAuth"); + page = appServer.whereIs("basicAuth"); driver.get(page); assertThat(driver.findElement(By.tagName("h1")).getText()).isEqualTo("authorized"); } @Test + @NeedsFreshDriver @Ignore(Browser.CHROME) @Ignore(Browser.EDGE) void canAddMultipleAuthenticationHandlersWithTheSameFilter() { @@ -112,13 +101,14 @@ void canAddMultipleAuthenticationHandlersWithTheSameFilter() { .addAuthenticationHandler( uri -> uri.getPath().contains("basicAuth"), new UsernameAndPassword("test", "test")); - page = server.whereIs("basicAuth"); + page = appServer.whereIs("basicAuth"); driver.get(page); assertThat(driver.findElement(By.tagName("h1")).getText()).isEqualTo("authorized"); } @Test + @NeedsFreshDriver @Ignore(Browser.CHROME) @Ignore(Browser.EDGE) void canRemoveAuthenticationHandler() { @@ -128,7 +118,7 @@ void canRemoveAuthenticationHandler() { .addAuthenticationHandler(new UsernameAndPassword("test", "test")); ((RemoteWebDriver) driver).network().removeAuthenticationHandler(id); - page = server.whereIs("basicAuth"); + page = appServer.whereIs("basicAuth"); driver.get(page); assertThatExceptionOfType(UnhandledAlertException.class) @@ -136,11 +126,12 @@ void canRemoveAuthenticationHandler() { } @Test + @NeedsFreshDriver @Ignore(Browser.CHROME) @Ignore(Browser.EDGE) void canRemoveAuthenticationHandlerThatDoesNotExist() { ((RemoteWebDriver) driver).network().removeAuthenticationHandler(5); - page = server.whereIs("basicAuth"); + page = appServer.whereIs("basicAuth"); driver.get(page); assertThatExceptionOfType(UnhandledAlertException.class) @@ -148,6 +139,7 @@ void canRemoveAuthenticationHandlerThatDoesNotExist() { } @Test + @NeedsFreshDriver @Ignore(Browser.CHROME) @Ignore(Browser.EDGE) void canClearAuthenticationHandlers() { @@ -165,7 +157,7 @@ void canClearAuthenticationHandlers() { .addAuthenticationHandler(new UsernameAndPassword("test1", "test1")); ((RemoteWebDriver) driver).network().clearAuthenticationHandlers(); - page = server.whereIs("basicAuth"); + page = appServer.whereIs("basicAuth"); driver.get(page); assertThatExceptionOfType(UnhandledAlertException.class) diff --git a/java/test/org/openqa/selenium/WebScriptTest.java b/java/test/org/openqa/selenium/WebScriptTest.java index bf7bcae431b66..29522eb060e9c 100644 --- a/java/test/org/openqa/selenium/WebScriptTest.java +++ b/java/test/org/openqa/selenium/WebScriptTest.java @@ -28,43 +28,29 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.openqa.selenium.bidi.log.ConsoleLogEntry; import org.openqa.selenium.bidi.log.JavascriptLogEntry; import org.openqa.selenium.bidi.log.LogLevel; -import org.openqa.selenium.environment.webserver.AppServer; -import org.openqa.selenium.environment.webserver.NettyAppServer; import org.openqa.selenium.remote.DomMutation; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.support.ui.WebDriverWait; import org.openqa.selenium.testing.JupiterTestBase; +import org.openqa.selenium.testing.NeedsFreshDriver; class WebScriptTest extends JupiterTestBase { String page; - private AppServer server; - - @BeforeEach - public void setUp() { - server = new NettyAppServer(); - server.start(); - } - - @AfterEach - public void cleanUp() { - driver.quit(); - } @Test + @NeedsFreshDriver void canAddConsoleMessageHandler() throws ExecutionException, InterruptedException, TimeoutException { CompletableFuture future = new CompletableFuture<>(); long id = ((RemoteWebDriver) driver).script().addConsoleMessageHandler(future::complete); - page = server.whereIs("/bidi/logEntryAdded.html"); + page = appServer.whereIs("/bidi/logEntryAdded.html"); driver.get(page); driver.findElement(By.id("consoleLog")).click(); @@ -81,6 +67,7 @@ void canAddConsoleMessageHandler() } @Test + @NeedsFreshDriver void canRemoveConsoleMessageHandler() throws ExecutionException, InterruptedException, TimeoutException { CompletableFuture future1 = new CompletableFuture<>(); @@ -96,7 +83,7 @@ void canRemoveConsoleMessageHandler() // Removing the second consumer, so it will no longer get the console message. ((RemoteWebDriver) driver).script().removeConsoleMessageHandler(id2); - page = server.whereIs("/bidi/logEntryAdded.html"); + page = appServer.whereIs("/bidi/logEntryAdded.html"); driver.get(page); driver.findElement(By.id("consoleLog")).click(); @@ -113,12 +100,13 @@ void canRemoveConsoleMessageHandler() } @Test + @NeedsFreshDriver void canAddJsErrorHandler() throws ExecutionException, InterruptedException, TimeoutException { CompletableFuture future = new CompletableFuture<>(); long id = ((RemoteWebDriver) driver).script().addJavaScriptErrorHandler(future::complete); - page = server.whereIs("/bidi/logEntryAdded.html"); + page = appServer.whereIs("/bidi/logEntryAdded.html"); driver.get(page); driver.findElement(By.id("jsException")).click(); @@ -132,6 +120,7 @@ void canAddJsErrorHandler() throws ExecutionException, InterruptedException, Tim } @Test + @NeedsFreshDriver void canRemoveJsErrorHandler() throws ExecutionException, InterruptedException, TimeoutException { CompletableFuture future1 = new CompletableFuture<>(); CompletableFuture future2 = new CompletableFuture<>(); @@ -146,7 +135,7 @@ void canRemoveJsErrorHandler() throws ExecutionException, InterruptedException, // Removing the second consumer, so it will no longer get the JS error. ((RemoteWebDriver) driver).script().removeJavaScriptErrorHandler(id2); - page = server.whereIs("/bidi/logEntryAdded.html"); + page = appServer.whereIs("/bidi/logEntryAdded.html"); driver.get(page); driver.findElement(By.id("jsException")).click(); @@ -166,6 +155,7 @@ void canRemoveJsErrorHandler() throws ExecutionException, InterruptedException, } @Test + @NeedsFreshDriver void canAddMultipleHandlers() throws ExecutionException, InterruptedException, TimeoutException { CompletableFuture future1 = new CompletableFuture<>(); CompletableFuture future2 = new CompletableFuture<>(); @@ -177,7 +167,7 @@ void canAddMultipleHandlers() throws ExecutionException, InterruptedException, T long id1 = ((RemoteWebDriver) driver).script().addJavaScriptErrorHandler(consumer1); long id2 = ((RemoteWebDriver) driver).script().addJavaScriptErrorHandler(consumer2); - page = server.whereIs("/bidi/logEntryAdded.html"); + page = appServer.whereIs("/bidi/logEntryAdded.html"); driver.get(page); driver.findElement(By.id("jsException")).click(); @@ -193,6 +183,7 @@ void canAddMultipleHandlers() throws ExecutionException, InterruptedException, T } @Test + @NeedsFreshDriver void canAddDomMutationHandler() throws InterruptedException { AtomicReference seen = new AtomicReference<>(); CountDownLatch latch = new CountDownLatch(1); @@ -220,6 +211,7 @@ void canAddDomMutationHandler() throws InterruptedException { } @Test + @NeedsFreshDriver void canRemoveDomMutationHandler() throws InterruptedException { AtomicReference seen = new AtomicReference<>(); CountDownLatch latch = new CountDownLatch(1); @@ -247,6 +239,7 @@ void canRemoveDomMutationHandler() throws InterruptedException { } @Test + @NeedsFreshDriver void canPinScript() throws ExecutionException, InterruptedException, TimeoutException { CompletableFuture future = new CompletableFuture<>(); @@ -254,7 +247,7 @@ void canPinScript() throws ExecutionException, InterruptedException, TimeoutExce long id = ((RemoteWebDriver) driver).script().addConsoleMessageHandler(future::complete); - page = server.whereIs("/bidi/logEntryAdded.html"); + page = appServer.whereIs("/bidi/logEntryAdded.html"); driver.get(page); ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS); @@ -265,6 +258,7 @@ void canPinScript() throws ExecutionException, InterruptedException, TimeoutExce } @Test + @NeedsFreshDriver void canUnpinScript() throws ExecutionException, InterruptedException, TimeoutException { CountDownLatch latch = new CountDownLatch(2); @@ -276,7 +270,7 @@ void canUnpinScript() throws ExecutionException, InterruptedException, TimeoutEx .script() .addConsoleMessageHandler(consoleLogEntry -> latch.countDown()); - page = server.whereIs("/bidi/logEntryAdded.html"); + page = appServer.whereIs("/bidi/logEntryAdded.html"); driver.get(page); diff --git a/java/test/org/openqa/selenium/bidi/BiDiTest.java b/java/test/org/openqa/selenium/bidi/BiDiTest.java index f2c34b2fc1b85..26212c80eefcd 100644 --- a/java/test/org/openqa/selenium/bidi/BiDiTest.java +++ b/java/test/org/openqa/selenium/bidi/BiDiTest.java @@ -18,15 +18,12 @@ package org.openqa.selenium.bidi; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; -import static org.openqa.selenium.testing.Safely.safelyCall; import static org.openqa.selenium.testing.drivers.Browser.EDGE; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.openqa.selenium.By; import org.openqa.selenium.bidi.browsingcontext.BrowsingContext; @@ -35,24 +32,17 @@ import org.openqa.selenium.bidi.log.JavascriptLogEntry; import org.openqa.selenium.bidi.log.LogLevel; import org.openqa.selenium.bidi.module.LogInspector; -import org.openqa.selenium.environment.webserver.AppServer; -import org.openqa.selenium.environment.webserver.NettyAppServer; import org.openqa.selenium.testing.JupiterTestBase; +import org.openqa.selenium.testing.NeedsFreshDriver; import org.openqa.selenium.testing.NotYetImplemented; class BiDiTest extends JupiterTestBase { String page; - private AppServer server; - - @BeforeEach - public void setUp() { - server = new NettyAppServer(); - server.start(); - } @Test @NotYetImplemented(EDGE) + @NeedsFreshDriver void canNavigateAndListenToErrors() throws ExecutionException, InterruptedException, TimeoutException { try (org.openqa.selenium.bidi.module.LogInspector logInspector = new LogInspector(driver)) { @@ -61,7 +51,7 @@ void canNavigateAndListenToErrors() BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle()); - page = server.whereIs("/bidi/logEntryAdded.html"); + page = appServer.whereIs("/bidi/logEntryAdded.html"); NavigationResult info = browsingContext.navigate(page, ReadinessState.COMPLETE); // If navigation was successful, we expect both the url and navigation id to be set @@ -78,12 +68,4 @@ void canNavigateAndListenToErrors() assertThat(logEntry.getLevel()).isEqualTo(LogLevel.ERROR); } } - - @AfterEach - public void quitDriver() { - if (driver != null) { - driver.quit(); - } - safelyCall(server::stop); - } } diff --git a/java/test/org/openqa/selenium/bidi/browser/BrowserCommandsTest.java b/java/test/org/openqa/selenium/bidi/browser/BrowserCommandsTest.java index f196b3e6c2b18..b35b9d4c14f45 100644 --- a/java/test/org/openqa/selenium/bidi/browser/BrowserCommandsTest.java +++ b/java/test/org/openqa/selenium/bidi/browser/BrowserCommandsTest.java @@ -18,31 +18,25 @@ package org.openqa.selenium.bidi.browser; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; -import static org.openqa.selenium.testing.Safely.safelyCall; -import static org.openqa.selenium.testing.drivers.Browser.*; import java.util.List; -import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.openqa.selenium.bidi.module.Browser; -import org.openqa.selenium.environment.webserver.AppServer; -import org.openqa.selenium.environment.webserver.NettyAppServer; import org.openqa.selenium.testing.JupiterTestBase; +import org.openqa.selenium.testing.NeedsFreshDriver; class BrowserCommandsTest extends JupiterTestBase { - private AppServer server; private Browser browser; @BeforeEach public void setUp() { - server = new NettyAppServer(); - server.start(); browser = new Browser(driver); } @Test + @NeedsFreshDriver void canCreateAUserContext() { String userContext = browser.createUserContext(); @@ -52,6 +46,7 @@ void canCreateAUserContext() { } @Test + @NeedsFreshDriver void canGetUserContexts() { String userContext1 = browser.createUserContext(); String userContext2 = browser.createUserContext(); @@ -64,6 +59,7 @@ void canGetUserContexts() { } @Test + @NeedsFreshDriver void canRemoveUserContext() { String userContext1 = browser.createUserContext(); String userContext2 = browser.createUserContext(); @@ -79,12 +75,4 @@ void canRemoveUserContext() { browser.removeUserContext(userContext1); } - - @AfterEach - public void quitDriver() { - if (driver != null) { - driver.quit(); - } - safelyCall(server::stop); - } } diff --git a/java/test/org/openqa/selenium/bidi/browsingcontext/BrowsingContextInspectorTest.java b/java/test/org/openqa/selenium/bidi/browsingcontext/BrowsingContextInspectorTest.java index a92110c96eb15..adab1e9305c1c 100644 --- a/java/test/org/openqa/selenium/bidi/browsingcontext/BrowsingContextInspectorTest.java +++ b/java/test/org/openqa/selenium/bidi/browsingcontext/BrowsingContextInspectorTest.java @@ -18,34 +18,22 @@ package org.openqa.selenium.bidi.browsingcontext; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; -import static org.openqa.selenium.testing.Safely.safelyCall; -import static org.openqa.selenium.testing.drivers.Browser.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.openqa.selenium.By; import org.openqa.selenium.WindowType; import org.openqa.selenium.bidi.module.BrowsingContextInspector; -import org.openqa.selenium.environment.webserver.AppServer; -import org.openqa.selenium.environment.webserver.NettyAppServer; import org.openqa.selenium.testing.JupiterTestBase; +import org.openqa.selenium.testing.NeedsFreshDriver; class BrowsingContextInspectorTest extends JupiterTestBase { - private AppServer server; - - @BeforeEach - public void setUp() { - server = new NettyAppServer(); - server.start(); - } - @Test + @NeedsFreshDriver void canListenToWindowBrowsingContextCreatedEvent() throws ExecutionException, InterruptedException, TimeoutException { try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) { @@ -66,6 +54,7 @@ void canListenToWindowBrowsingContextCreatedEvent() } @Test + @NeedsFreshDriver void canListenToBrowsingContextDestroyedEvent() throws ExecutionException, InterruptedException, TimeoutException { try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) { @@ -87,6 +76,7 @@ void canListenToBrowsingContextDestroyedEvent() } @Test + @NeedsFreshDriver void canListenToTabBrowsingContextCreatedEvent() throws ExecutionException, InterruptedException, TimeoutException { try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) { @@ -106,6 +96,7 @@ void canListenToTabBrowsingContextCreatedEvent() } @Test + @NeedsFreshDriver void canListenToDomContentLoadedEvent() throws ExecutionException, InterruptedException, TimeoutException { try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) { @@ -113,7 +104,7 @@ void canListenToDomContentLoadedEvent() inspector.onDomContentLoaded(future::complete); BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle()); - context.navigate(server.whereIs("/bidi/logEntryAdded.html"), ReadinessState.COMPLETE); + context.navigate(appServer.whereIs("/bidi/logEntryAdded.html"), ReadinessState.COMPLETE); NavigationInfo navigationInfo = future.get(5, TimeUnit.SECONDS); assertThat(navigationInfo.getBrowsingContextId()).isEqualTo(context.getId()); @@ -122,6 +113,7 @@ void canListenToDomContentLoadedEvent() } @Test + @NeedsFreshDriver void canListenToBrowsingContextLoadedEvent() throws ExecutionException, InterruptedException, TimeoutException { try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) { @@ -129,7 +121,7 @@ void canListenToBrowsingContextLoadedEvent() inspector.onBrowsingContextLoaded(future::complete); BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle()); - context.navigate(server.whereIs("/bidi/logEntryAdded.html"), ReadinessState.COMPLETE); + context.navigate(appServer.whereIs("/bidi/logEntryAdded.html"), ReadinessState.COMPLETE); NavigationInfo navigationInfo = future.get(5, TimeUnit.SECONDS); assertThat(navigationInfo.getBrowsingContextId()).isEqualTo(context.getId()); @@ -138,6 +130,7 @@ void canListenToBrowsingContextLoadedEvent() } @Test + @NeedsFreshDriver void canListenToNavigationStartedEvent() throws ExecutionException, InterruptedException, TimeoutException { try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) { @@ -145,7 +138,7 @@ void canListenToNavigationStartedEvent() inspector.onNavigationStarted(future::complete); BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle()); - context.navigate(server.whereIs("/bidi/logEntryAdded.html"), ReadinessState.COMPLETE); + context.navigate(appServer.whereIs("/bidi/logEntryAdded.html"), ReadinessState.COMPLETE); NavigationInfo navigationInfo = future.get(5, TimeUnit.SECONDS); assertThat(navigationInfo.getBrowsingContextId()).isEqualTo(context.getId()); @@ -154,18 +147,19 @@ void canListenToNavigationStartedEvent() } @Test + @NeedsFreshDriver void canListenToFragmentNavigatedEvent() throws ExecutionException, InterruptedException, TimeoutException { try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) { CompletableFuture future = new CompletableFuture<>(); BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle()); - context.navigate(server.whereIs("/linked_image.html"), ReadinessState.COMPLETE); + context.navigate(appServer.whereIs("/linked_image.html"), ReadinessState.COMPLETE); inspector.onFragmentNavigated(future::complete); context.navigate( - server.whereIs("/linked_image.html#linkToAnchorOnThisPage"), ReadinessState.COMPLETE); + appServer.whereIs("/linked_image.html#linkToAnchorOnThisPage"), ReadinessState.COMPLETE); NavigationInfo navigationInfo = future.get(5, TimeUnit.SECONDS); assertThat(navigationInfo.getBrowsingContextId()).isEqualTo(context.getId()); @@ -174,6 +168,7 @@ void canListenToFragmentNavigatedEvent() } @Test + @NeedsFreshDriver void canListenToUserPromptOpenedEvent() throws ExecutionException, InterruptedException, TimeoutException { try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) { @@ -182,7 +177,7 @@ void canListenToUserPromptOpenedEvent() BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle()); inspector.onUserPromptOpened(future::complete); - driver.get(server.whereIs("/alerts.html")); + driver.get(appServer.whereIs("/alerts.html")); driver.findElement(By.id("alert")).click(); @@ -193,6 +188,7 @@ void canListenToUserPromptOpenedEvent() } @Test + @NeedsFreshDriver // TODO: This test is flaky for comparing the browsing context id for Chrome and Edge. Fix flaky // test. void canListenToUserPromptClosedEvent() @@ -203,7 +199,7 @@ void canListenToUserPromptClosedEvent() BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle()); inspector.onUserPromptClosed(future::complete); - driver.get(server.whereIs("/alerts.html")); + driver.get(appServer.whereIs("/alerts.html")); driver.findElement(By.id("prompt")).click(); @@ -216,12 +212,4 @@ void canListenToUserPromptClosedEvent() assertThat(userPromptClosed.getAccepted()).isTrue(); } } - - @AfterEach - public void quitDriver() { - if (driver != null) { - driver.quit(); - } - safelyCall(server::stop); - } } diff --git a/java/test/org/openqa/selenium/bidi/browsingcontext/BrowsingContextTest.java b/java/test/org/openqa/selenium/bidi/browsingcontext/BrowsingContextTest.java index af26b601e8551..44e0e0ed8b905 100644 --- a/java/test/org/openqa/selenium/bidi/browsingcontext/BrowsingContextTest.java +++ b/java/test/org/openqa/selenium/bidi/browsingcontext/BrowsingContextTest.java @@ -22,11 +22,8 @@ import static org.openqa.selenium.support.ui.ExpectedConditions.alertIsPresent; import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs; import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated; -import static org.openqa.selenium.testing.Safely.safelyCall; import java.util.List; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.openqa.selenium.By; import org.openqa.selenium.JavascriptExecutor; @@ -35,24 +32,16 @@ import org.openqa.selenium.WindowType; import org.openqa.selenium.bidi.BiDiException; import org.openqa.selenium.bidi.module.Browser; -import org.openqa.selenium.environment.webserver.AppServer; -import org.openqa.selenium.environment.webserver.NettyAppServer; import org.openqa.selenium.environment.webserver.Page; import org.openqa.selenium.print.PrintOptions; import org.openqa.selenium.remote.RemoteWebElement; import org.openqa.selenium.testing.JupiterTestBase; +import org.openqa.selenium.testing.NeedsFreshDriver; class BrowsingContextTest extends JupiterTestBase { - private AppServer server; - - @BeforeEach - public void setUp() { - server = new NettyAppServer(); - server.start(); - } - @Test + @NeedsFreshDriver void canCreateABrowsingContextForGivenId() { String id = driver.getWindowHandle(); BrowsingContext browsingContext = new BrowsingContext(driver, id); @@ -60,12 +49,14 @@ void canCreateABrowsingContextForGivenId() { } @Test + @NeedsFreshDriver void canCreateAWindow() { BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW); assertThat(browsingContext.getId()).isNotEmpty(); } @Test + @NeedsFreshDriver void canCreateAWindowWithAReferenceContext() { BrowsingContext browsingContext = new BrowsingContext( @@ -76,12 +67,14 @@ void canCreateAWindowWithAReferenceContext() { } @Test + @NeedsFreshDriver void canCreateATab() { BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB); assertThat(browsingContext.getId()).isNotEmpty(); } @Test + @NeedsFreshDriver void canCreateATabWithAReferenceContext() { BrowsingContext browsingContext = new BrowsingContext( @@ -91,6 +84,7 @@ void canCreateATabWithAReferenceContext() { } @Test + @NeedsFreshDriver void canCreateAContextWithAllParameters() { Browser browser = new Browser(driver); String userContextId = browser.createUserContext(); @@ -107,10 +101,11 @@ void canCreateAContextWithAllParameters() { } @Test + @NeedsFreshDriver void canNavigateToAUrl() { BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB); - String url = server.whereIs("/bidi/logEntryAdded.html"); + String url = appServer.whereIs("/bidi/logEntryAdded.html"); NavigationResult info = browsingContext.navigate(url); assertThat(browsingContext.getId()).isNotEmpty(); @@ -118,10 +113,11 @@ void canNavigateToAUrl() { } @Test + @NeedsFreshDriver void canNavigateToAUrlWithReadinessState() { BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB); - String url = server.whereIs("/bidi/logEntryAdded.html"); + String url = appServer.whereIs("/bidi/logEntryAdded.html"); NavigationResult info = browsingContext.navigate(url, ReadinessState.COMPLETE); assertThat(browsingContext.getId()).isNotEmpty(); @@ -129,11 +125,12 @@ void canNavigateToAUrlWithReadinessState() { } @Test + @NeedsFreshDriver void canGetTreeWithAChild() { String referenceContextId = driver.getWindowHandle(); BrowsingContext parentWindow = new BrowsingContext(driver, referenceContextId); - String url = server.whereIs("iframes.html"); + String url = appServer.whereIs("iframes.html"); parentWindow.navigate(url, ReadinessState.COMPLETE); @@ -147,11 +144,12 @@ void canGetTreeWithAChild() { } @Test + @NeedsFreshDriver void canGetTreeWithDepth() { String referenceContextId = driver.getWindowHandle(); BrowsingContext parentWindow = new BrowsingContext(driver, referenceContextId); - String url = server.whereIs("iframes.html"); + String url = appServer.whereIs("iframes.html"); parentWindow.navigate(url, ReadinessState.COMPLETE); @@ -164,6 +162,7 @@ void canGetTreeWithDepth() { } @Test + @NeedsFreshDriver void canGetAllTopLevelContexts() { BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle()); BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW); @@ -174,6 +173,7 @@ void canGetAllTopLevelContexts() { } @Test + @NeedsFreshDriver void canCloseAWindow() { BrowsingContext window1 = new BrowsingContext(driver, WindowType.WINDOW); BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW); @@ -184,6 +184,7 @@ void canCloseAWindow() { } @Test + @NeedsFreshDriver void canCloseATab() { BrowsingContext tab1 = new BrowsingContext(driver, WindowType.TAB); BrowsingContext tab2 = new BrowsingContext(driver, WindowType.TAB); @@ -194,6 +195,7 @@ void canCloseATab() { } @Test + @NeedsFreshDriver void canActivateABrowsingContext() { BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle()); // 2nd window is focused @@ -211,10 +213,11 @@ void canActivateABrowsingContext() { // Refer: https://github.com/w3c/webdriver-bidi/issues/187 @Test + @NeedsFreshDriver void canReloadABrowsingContext() { BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB); - String url = server.whereIs("/bidi/logEntryAdded.html"); + String url = appServer.whereIs("/bidi/logEntryAdded.html"); browsingContext.navigate(url, ReadinessState.COMPLETE); NavigationResult reloadInfo = browsingContext.reload(); @@ -223,10 +226,11 @@ void canReloadABrowsingContext() { } @Test + @NeedsFreshDriver void canReloadWithReadinessState() { BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB); - String url = server.whereIs("/bidi/logEntryAdded.html"); + String url = appServer.whereIs("/bidi/logEntryAdded.html"); browsingContext.navigate(url, ReadinessState.COMPLETE); NavigationResult reloadInfo = browsingContext.reload(ReadinessState.COMPLETE); @@ -236,6 +240,7 @@ void canReloadWithReadinessState() { } @Test + @NeedsFreshDriver void canHandleUserPrompt() { BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle()); @@ -250,6 +255,7 @@ void canHandleUserPrompt() { } @Test + @NeedsFreshDriver void canAcceptUserPrompt() { BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle()); @@ -264,6 +270,7 @@ void canAcceptUserPrompt() { } @Test + @NeedsFreshDriver void canDismissUserPrompt() { BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle()); @@ -278,6 +285,7 @@ void canDismissUserPrompt() { } @Test + @NeedsFreshDriver void canPassUserTextToUserPrompt() { BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle()); @@ -294,6 +302,7 @@ void canPassUserTextToUserPrompt() { } @Test + @NeedsFreshDriver void canAcceptUserPromptWithUserText() { BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle()); @@ -310,6 +319,7 @@ void canAcceptUserPromptWithUserText() { } @Test + @NeedsFreshDriver void canDismissUserPromptWithUserText() { BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle()); @@ -333,6 +343,7 @@ void canDismissUserPromptWithUserText() { // TODO: A potential solution can be replicating classic WebDriver screenshot tests. // Meanwhile, trusting the browsers to do the right thing. @Test + @NeedsFreshDriver void canCaptureScreenshot() { BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle()); @@ -344,6 +355,7 @@ void canCaptureScreenshot() { } @Test + @NeedsFreshDriver void canCaptureScreenshotWithAllParameters() { BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle()); @@ -369,6 +381,7 @@ void canCaptureScreenshotWithAllParameters() { } @Test + @NeedsFreshDriver void canCaptureScreenshotOfViewport() { BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle()); @@ -385,6 +398,7 @@ void canCaptureScreenshotOfViewport() { } @Test + @NeedsFreshDriver void canCaptureElementScreenshot() { BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle()); @@ -399,6 +413,7 @@ void canCaptureElementScreenshot() { } @Test + @NeedsFreshDriver void canSetViewport() { BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle()); driver.get(appServer.whereIs("formPage.html")); @@ -415,6 +430,7 @@ void canSetViewport() { } @Test + @NeedsFreshDriver void canSetViewportWithDevicePixelRatio() { BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle()); driver.get(appServer.whereIs("formPage.html")); @@ -436,6 +452,7 @@ void canSetViewportWithDevicePixelRatio() { } @Test + @NeedsFreshDriver void canPrintPage() { BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle()); @@ -453,6 +470,7 @@ void canPrintPage() { } @Test + @NeedsFreshDriver void canNavigateBackInTheBrowserHistory() { BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle()); browsingContext.navigate(pages.formPage, ReadinessState.COMPLETE); @@ -465,6 +483,7 @@ void canNavigateBackInTheBrowserHistory() { } @Test + @NeedsFreshDriver void canNavigateForwardInTheBrowserHistory() { BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle()); browsingContext.navigate(pages.formPage, ReadinessState.COMPLETE); @@ -506,12 +525,4 @@ private String promptPage() { private boolean getDocumentFocus() { return (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();"); } - - @AfterEach - public void quitDriver() { - if (driver != null) { - driver.quit(); - } - safelyCall(server::stop); - } } diff --git a/java/test/org/openqa/selenium/bidi/browsingcontext/LocateNodesTest.java b/java/test/org/openqa/selenium/bidi/browsingcontext/LocateNodesTest.java index c1f967ebc36ba..611f3c18ba086 100644 --- a/java/test/org/openqa/selenium/bidi/browsingcontext/LocateNodesTest.java +++ b/java/test/org/openqa/selenium/bidi/browsingcontext/LocateNodesTest.java @@ -17,15 +17,12 @@ package org.openqa.selenium.bidi.browsingcontext; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; -import static org.openqa.selenium.testing.Safely.safelyCall; import static org.openqa.selenium.testing.drivers.Browser.*; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Optional; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.openqa.selenium.bidi.module.Script; import org.openqa.selenium.bidi.script.EvaluateResult; @@ -35,21 +32,14 @@ import org.openqa.selenium.bidi.script.RemoteReference; import org.openqa.selenium.bidi.script.RemoteValue; import org.openqa.selenium.bidi.script.ResultOwnership; -import org.openqa.selenium.environment.webserver.AppServer; -import org.openqa.selenium.environment.webserver.NettyAppServer; import org.openqa.selenium.testing.JupiterTestBase; +import org.openqa.selenium.testing.NeedsFreshDriver; import org.openqa.selenium.testing.NotYetImplemented; public class LocateNodesTest extends JupiterTestBase { - private AppServer server; - - @BeforeEach - public void setUp() { - server = new NettyAppServer(); - server.start(); - } @Test + @NeedsFreshDriver void canLocateNodes() { BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle()); assertThat(browsingContext.getId()).isNotEmpty(); @@ -63,6 +53,7 @@ void canLocateNodes() { } @Test + @NeedsFreshDriver void canLocateNodesWithJustLocator() { BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle()); assertThat(browsingContext.getId()).isNotEmpty(); @@ -74,6 +65,7 @@ void canLocateNodesWithJustLocator() { } @Test + @NeedsFreshDriver void canLocateNode() { BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle()); assertThat(browsingContext.getId()).isNotEmpty(); @@ -85,6 +77,7 @@ void canLocateNode() { } @Test + @NeedsFreshDriver void canLocateNodesWithCSSLocator() { BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle()); assertThat(browsingContext.getId()).isNotEmpty(); @@ -107,6 +100,7 @@ void canLocateNodesWithCSSLocator() { } @Test + @NeedsFreshDriver void canLocateNodesWithXPathLocator() { BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle()); assertThat(browsingContext.getId()).isNotEmpty(); @@ -129,6 +123,7 @@ void canLocateNodesWithXPathLocator() { } @Test + @NeedsFreshDriver @NotYetImplemented(FIREFOX) void canLocateNodesWithInnerText() { BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle()); @@ -148,6 +143,7 @@ void canLocateNodesWithInnerText() { } @Test + @NeedsFreshDriver void canLocateNodesWithMaxNodeCount() { BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle()); assertThat(browsingContext.getId()).isNotEmpty(); @@ -162,6 +158,7 @@ void canLocateNodesWithMaxNodeCount() { } @Test + @NeedsFreshDriver void canLocateNodesGivenStartNodes() { String handle = driver.getWindowHandle(); BrowsingContext browsingContext = new BrowsingContext(driver, handle); @@ -200,6 +197,7 @@ void canLocateNodesGivenStartNodes() { } @Test + @NeedsFreshDriver void canLocateNodesInAGivenSandbox() { String sandbox = "sandbox"; BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle()); @@ -241,12 +239,4 @@ void canLocateNodesInAGivenSandbox() { String sharedId = (String) ((RemoteValue) sharedIdMap.get("sharedId")).getValue().get(); assertThat(sharedId).isEqualTo(nodeId); } - - @AfterEach - public void quitDriver() { - if (driver != null) { - driver.quit(); - } - safelyCall(server::stop); - } } diff --git a/java/test/org/openqa/selenium/bidi/input/ReleaseCommandTest.java b/java/test/org/openqa/selenium/bidi/input/ReleaseCommandTest.java index f973be888bd0c..44555f8118544 100644 --- a/java/test/org/openqa/selenium/bidi/input/ReleaseCommandTest.java +++ b/java/test/org/openqa/selenium/bidi/input/ReleaseCommandTest.java @@ -27,29 +27,25 @@ import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebElement; import org.openqa.selenium.bidi.module.Input; -import org.openqa.selenium.environment.webserver.AppServer; -import org.openqa.selenium.environment.webserver.NettyAppServer; import org.openqa.selenium.interactions.Actions; import org.openqa.selenium.testing.JupiterTestBase; +import org.openqa.selenium.testing.NeedsFreshDriver; public class ReleaseCommandTest extends JupiterTestBase { private Input input; private String windowHandle; - private AppServer server; - @BeforeEach public void setUp() { windowHandle = driver.getWindowHandle(); input = new Input(driver); - server = new NettyAppServer(); - server.start(); } @Test + @NeedsFreshDriver public void testReleaseInBrowsingContext() { - driver.get(server.whereIs("/bidi/release_action.html")); + driver.get(appServer.whereIs("/bidi/release_action.html")); WebElement inputTextBox = driver.findElement(By.id("keys")); diff --git a/java/test/org/openqa/selenium/bidi/input/SetFilesCommandTest.java b/java/test/org/openqa/selenium/bidi/input/SetFilesCommandTest.java index 87a9e5e7d8069..0439fd7329f59 100644 --- a/java/test/org/openqa/selenium/bidi/input/SetFilesCommandTest.java +++ b/java/test/org/openqa/selenium/bidi/input/SetFilesCommandTest.java @@ -29,27 +29,23 @@ import org.openqa.selenium.WebElement; import org.openqa.selenium.bidi.module.Input; import org.openqa.selenium.bidi.script.RemoteReference; -import org.openqa.selenium.environment.webserver.AppServer; -import org.openqa.selenium.environment.webserver.NettyAppServer; import org.openqa.selenium.remote.RemoteWebElement; import org.openqa.selenium.testing.JupiterTestBase; +import org.openqa.selenium.testing.NeedsFreshDriver; public class SetFilesCommandTest extends JupiterTestBase { private Input input; private String windowHandle; - private AppServer server; - @BeforeEach public void setUp() { windowHandle = driver.getWindowHandle(); input = new Input(driver); - server = new NettyAppServer(); - server.start(); } @Test + @NeedsFreshDriver void canSetFiles() throws IOException { driver.get(pages.formPage); WebElement uploadElement = driver.findElement(By.id("upload")); @@ -71,6 +67,7 @@ void canSetFiles() throws IOException { } @Test + @NeedsFreshDriver public void canSetFilesWithElementId() throws IOException { driver.get(pages.formPage); WebElement uploadElement = driver.findElement(By.id("upload")); @@ -88,6 +85,7 @@ public void canSetFilesWithElementId() throws IOException { } @Test + @NeedsFreshDriver void canSetFile() throws IOException { driver.get(pages.formPage); WebElement uploadElement = driver.findElement(By.id("upload")); @@ -106,6 +104,7 @@ void canSetFile() throws IOException { } @Test + @NeedsFreshDriver void canSetFileWithElementId() throws IOException { driver.get(pages.formPage); WebElement uploadElement = driver.findElement(By.id("upload")); diff --git a/java/test/org/openqa/selenium/bidi/log/LogInspectorTest.java b/java/test/org/openqa/selenium/bidi/log/LogInspectorTest.java index be6e7a0f12f9c..5619a890b0fc1 100644 --- a/java/test/org/openqa/selenium/bidi/log/LogInspectorTest.java +++ b/java/test/org/openqa/selenium/bidi/log/LogInspectorTest.java @@ -20,7 +20,6 @@ import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.assertj.core.api.AssertionsForClassTypes.assertThatExceptionOfType; import static org.assertj.core.api.AssertionsForClassTypes.fail; -import static org.openqa.selenium.testing.Safely.safelyCall; import java.util.HashSet; import java.util.Set; @@ -29,36 +28,27 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.openqa.selenium.By; import org.openqa.selenium.WindowType; import org.openqa.selenium.bidi.module.LogInspector; import org.openqa.selenium.bidi.script.Source; -import org.openqa.selenium.environment.webserver.AppServer; -import org.openqa.selenium.environment.webserver.NettyAppServer; import org.openqa.selenium.testing.JupiterTestBase; +import org.openqa.selenium.testing.NeedsFreshDriver; class LogInspectorTest extends JupiterTestBase { String page; - private AppServer server; - - @BeforeEach - public void setUp() { - server = new NettyAppServer(); - server.start(); - } @Test + @NeedsFreshDriver void canListenToConsoleLog() throws ExecutionException, InterruptedException, TimeoutException { try (LogInspector logInspector = new LogInspector(driver)) { CompletableFuture future = new CompletableFuture<>(); logInspector.onConsoleEntry(future::complete); - page = server.whereIs("/bidi/logEntryAdded.html"); + page = appServer.whereIs("/bidi/logEntryAdded.html"); driver.get(page); driver.findElement(By.id("consoleLog")).click(); @@ -76,12 +66,13 @@ void canListenToConsoleLog() throws ExecutionException, InterruptedException, Ti } @Test + @NeedsFreshDriver void canFilterConsoleLogs() throws ExecutionException, InterruptedException, TimeoutException { try (LogInspector logInspector = new LogInspector(driver)) { CompletableFuture future = new CompletableFuture<>(); logInspector.onConsoleEntry(future::complete, FilterBy.logLevel(LogLevel.INFO)); - page = server.whereIs("/bidi/logEntryAdded.html"); + page = appServer.whereIs("/bidi/logEntryAdded.html"); driver.get(page); driver.findElement(By.id("consoleLog")).click(); @@ -111,13 +102,14 @@ void canFilterConsoleLogs() throws ExecutionException, InterruptedException, Tim } @Test + @NeedsFreshDriver void canListenToJavascriptLog() throws ExecutionException, InterruptedException, TimeoutException { try (LogInspector logInspector = new LogInspector(driver)) { CompletableFuture future = new CompletableFuture<>(); logInspector.onJavaScriptLog(future::complete); - page = server.whereIs("/bidi/logEntryAdded.html"); + page = appServer.whereIs("/bidi/logEntryAdded.html"); driver.get(page); driver.findElement(By.id("jsException")).click(); @@ -134,12 +126,13 @@ void canListenToJavascriptLog() } @Test + @NeedsFreshDriver void canFilterJavascriptLogs() throws ExecutionException, InterruptedException { try (LogInspector logInspector = new LogInspector(driver)) { CompletableFuture future = new CompletableFuture<>(); logInspector.onJavaScriptLog(future::complete, FilterBy.logLevel(LogLevel.ERROR)); - page = server.whereIs("/bidi/logEntryAdded.html"); + page = appServer.whereIs("/bidi/logEntryAdded.html"); driver.get(page); driver.findElement(By.id("jsException")).click(); @@ -165,13 +158,14 @@ void canFilterJavascriptLogs() throws ExecutionException, InterruptedException { } @Test + @NeedsFreshDriver void canListenToJavascriptErrorLog() throws ExecutionException, InterruptedException, TimeoutException { try (LogInspector logInspector = new LogInspector(driver)) { CompletableFuture future = new CompletableFuture<>(); logInspector.onJavaScriptException(future::complete); - page = server.whereIs("/bidi/logEntryAdded.html"); + page = appServer.whereIs("/bidi/logEntryAdded.html"); driver.get(page); driver.findElement(By.id("jsException")).click(); @@ -184,13 +178,14 @@ void canListenToJavascriptErrorLog() } @Test + @NeedsFreshDriver void canRetrieveStacktraceForALog() throws ExecutionException, InterruptedException, TimeoutException { try (LogInspector logInspector = new LogInspector(driver)) { CompletableFuture future = new CompletableFuture<>(); logInspector.onJavaScriptException(future::complete); - page = server.whereIs("/bidi/logEntryAdded.html"); + page = appServer.whereIs("/bidi/logEntryAdded.html"); driver.get(page); driver.findElement(By.id("logWithStacktrace")).click(); @@ -202,12 +197,13 @@ void canRetrieveStacktraceForALog() } @Test + @NeedsFreshDriver void canFilterLogs() throws ExecutionException, InterruptedException { try (LogInspector logInspector = new LogInspector(driver)) { CompletableFuture future = new CompletableFuture<>(); logInspector.onLog(future::complete, FilterBy.logLevel(LogLevel.INFO)); - page = server.whereIs("/bidi/logEntryAdded.html"); + page = appServer.whereIs("/bidi/logEntryAdded.html"); driver.get(page); driver.findElement(By.id("consoleLog")).click(); @@ -231,9 +227,10 @@ void canFilterLogs() throws ExecutionException, InterruptedException { @Disabled("Until browsers support subscribing to multiple contexts.") @Test + @NeedsFreshDriver void canListenToConsoleLogForABrowsingContext() throws ExecutionException, InterruptedException, TimeoutException { - page = server.whereIs("/bidi/logEntryAdded.html"); + page = appServer.whereIs("/bidi/logEntryAdded.html"); String browsingContextId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle(); try (LogInspector logInspector = new LogInspector(browsingContextId, driver)) { @@ -255,9 +252,10 @@ void canListenToConsoleLogForABrowsingContext() @Disabled("Until browsers support subscribing to multiple contexts.") @Test + @NeedsFreshDriver void canListenToJavascriptLogForABrowsingContext() throws ExecutionException, InterruptedException, TimeoutException { - page = server.whereIs("/bidi/logEntryAdded.html"); + page = appServer.whereIs("/bidi/logEntryAdded.html"); String browsingContextId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle(); try (LogInspector logInspector = new LogInspector(browsingContextId, driver)) { @@ -277,9 +275,10 @@ void canListenToJavascriptLogForABrowsingContext() @Disabled("Until browsers support subscribing to multiple contexts.") @Test + @NeedsFreshDriver void canListenToJavascriptErrorLogForABrowsingContext() throws ExecutionException, InterruptedException, TimeoutException { - page = server.whereIs("/bidi/logEntryAdded.html"); + page = appServer.whereIs("/bidi/logEntryAdded.html"); String browsingContextId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle(); try (LogInspector logInspector = new LogInspector(browsingContextId, driver)) { @@ -299,9 +298,10 @@ void canListenToJavascriptErrorLogForABrowsingContext() @Disabled("Until browsers support subscribing to multiple contexts.") @Test + @NeedsFreshDriver void canListenToConsoleLogForMultipleBrowsingContexts() throws ExecutionException, InterruptedException, TimeoutException { - page = server.whereIs("/bidi/logEntryAdded.html"); + page = appServer.whereIs("/bidi/logEntryAdded.html"); String firstBrowsingContextId = driver.getWindowHandle(); String secondBrowsingContextId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle(); @@ -337,8 +337,9 @@ void canListenToConsoleLogForMultipleBrowsingContexts() @Disabled("Until browsers support subscribing to multiple contexts.") @Test + @NeedsFreshDriver void canListenToJavascriptLogForMultipleBrowsingContexts() throws InterruptedException { - page = server.whereIs("/bidi/logEntryAdded.html"); + page = appServer.whereIs("/bidi/logEntryAdded.html"); String firstBrowsingContextId = driver.getWindowHandle(); String secondBrowsingContextId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle(); @@ -374,8 +375,9 @@ void canListenToJavascriptLogForMultipleBrowsingContexts() throws InterruptedExc @Disabled("Until browsers support subscribing to multiple contexts.") @Test + @NeedsFreshDriver void canListenToJavascriptErrorLogForMultipleBrowsingContexts() throws InterruptedException { - page = server.whereIs("/bidi/logEntryAdded.html"); + page = appServer.whereIs("/bidi/logEntryAdded.html"); String firstBrowsingContextId = driver.getWindowHandle(); String secondBrowsingContextId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle(); @@ -411,8 +413,9 @@ void canListenToJavascriptErrorLogForMultipleBrowsingContexts() throws Interrupt @Disabled("Until browsers support subscribing to multiple contexts.") @Test + @NeedsFreshDriver void canListenToAnyTypeOfLogForMultipleBrowsingContexts() throws InterruptedException { - page = server.whereIs("/bidi/logEntryAdded.html"); + page = appServer.whereIs("/bidi/logEntryAdded.html"); String firstBrowsingContextId = driver.getWindowHandle(); String secondBrowsingContextId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle(); @@ -440,6 +443,7 @@ void canListenToAnyTypeOfLogForMultipleBrowsingContexts() throws InterruptedExce } @Test + @NeedsFreshDriver void canListenToLogsWithMultipleConsumers() throws ExecutionException, InterruptedException, TimeoutException { try (LogInspector logInspector = new LogInspector(driver)) { @@ -449,7 +453,7 @@ void canListenToLogsWithMultipleConsumers() CompletableFuture completableFuture2 = new CompletableFuture<>(); logInspector.onJavaScriptLog(completableFuture2::complete); - page = server.whereIs("/bidi/logEntryAdded.html"); + page = appServer.whereIs("/bidi/logEntryAdded.html"); driver.get(page); driver.findElement(By.id("jsException")).click(); @@ -466,12 +470,4 @@ void canListenToLogsWithMultipleConsumers() assertThat(logEntry.getLevel()).isEqualTo(LogLevel.ERROR); } } - - @AfterEach - public void quitDriver() { - if (driver != null) { - driver.quit(); - } - safelyCall(server::stop); - } } diff --git a/java/test/org/openqa/selenium/bidi/network/AddInterceptParametersTest.java b/java/test/org/openqa/selenium/bidi/network/AddInterceptParametersTest.java index 21384e9aa5e7c..28ce439a3a653 100644 --- a/java/test/org/openqa/selenium/bidi/network/AddInterceptParametersTest.java +++ b/java/test/org/openqa/selenium/bidi/network/AddInterceptParametersTest.java @@ -18,30 +18,19 @@ package org.openqa.selenium.bidi.network; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; -import static org.openqa.selenium.testing.Safely.safelyCall; import static org.openqa.selenium.testing.drivers.Browser.EDGE; import java.util.List; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.openqa.selenium.bidi.module.Network; -import org.openqa.selenium.environment.webserver.AppServer; -import org.openqa.selenium.environment.webserver.NettyAppServer; import org.openqa.selenium.testing.JupiterTestBase; +import org.openqa.selenium.testing.NeedsFreshDriver; import org.openqa.selenium.testing.NotYetImplemented; class AddInterceptParametersTest extends JupiterTestBase { - private AppServer server; - - @BeforeEach - public void setUp() { - server = new NettyAppServer(); - server.start(); - } - @Test + @NeedsFreshDriver @NotYetImplemented(EDGE) void canAddInterceptPhase() { try (Network network = new Network(driver)) { @@ -52,6 +41,7 @@ void canAddInterceptPhase() { } @Test + @NeedsFreshDriver @NotYetImplemented(EDGE) void canAddInterceptPhases() { try (Network network = new Network(driver)) { @@ -64,6 +54,7 @@ void canAddInterceptPhases() { } @Test + @NeedsFreshDriver @NotYetImplemented(EDGE) void canAddStringUrlPattern() { try (Network network = new Network(driver)) { @@ -76,6 +67,7 @@ void canAddStringUrlPattern() { } @Test + @NeedsFreshDriver @NotYetImplemented(EDGE) void canAddStringUrlPatterns() { try (Network network = new Network(driver)) { @@ -91,6 +83,7 @@ void canAddStringUrlPatterns() { } @Test + @NeedsFreshDriver @NotYetImplemented(EDGE) void canAddUrlPattern() { try (Network network = new Network(driver)) { @@ -110,6 +103,7 @@ void canAddUrlPattern() { } @Test + @NeedsFreshDriver @NotYetImplemented(EDGE) void canAddUrlPatterns() { try (Network network = new Network(driver)) { @@ -136,12 +130,4 @@ void canAddUrlPatterns() { assertThat(intercept).isNotNull(); } } - - @AfterEach - public void quitDriver() { - if (driver != null) { - driver.quit(); - } - safelyCall(server::stop); - } } diff --git a/java/test/org/openqa/selenium/bidi/network/NetworkCommandsTest.java b/java/test/org/openqa/selenium/bidi/network/NetworkCommandsTest.java index 1b82ad4d13861..cb7c065bb49ba 100644 --- a/java/test/org/openqa/selenium/bidi/network/NetworkCommandsTest.java +++ b/java/test/org/openqa/selenium/bidi/network/NetworkCommandsTest.java @@ -19,15 +19,12 @@ import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; -import static org.openqa.selenium.testing.Safely.safelyCall; import static org.openqa.selenium.testing.drivers.Browser.*; import java.time.Duration; import java.time.temporal.ChronoUnit; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.openqa.selenium.Alert; @@ -36,23 +33,16 @@ import org.openqa.selenium.UsernameAndPassword; import org.openqa.selenium.WebDriverException; import org.openqa.selenium.bidi.module.Network; -import org.openqa.selenium.environment.webserver.AppServer; -import org.openqa.selenium.environment.webserver.NettyAppServer; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.testing.JupiterTestBase; +import org.openqa.selenium.testing.NeedsFreshDriver; import org.openqa.selenium.testing.NotYetImplemented; class NetworkCommandsTest extends JupiterTestBase { private String page; - private AppServer server; - - @BeforeEach - public void setUp() { - server = new NettyAppServer(); - server.start(); - } @Test + @NeedsFreshDriver @NotYetImplemented(EDGE) @NotYetImplemented(CHROME) void canAddIntercept() { @@ -64,6 +54,7 @@ void canAddIntercept() { } @Test + @NeedsFreshDriver @NotYetImplemented(EDGE) @NotYetImplemented(CHROME) void canContinueRequest() throws InterruptedException { @@ -73,7 +64,7 @@ void canContinueRequest() throws InterruptedException { CountDownLatch latch = new CountDownLatch(1); - // String alternatePage = server.whereIs("printPage.html"); + // String alternatePage = appServer.whereIs("printPage.html"); // TODO: Test sending request to alternate page once it is supported by browsers network.onBeforeRequestSent( beforeRequestSent -> { @@ -89,7 +80,7 @@ void canContinueRequest() throws InterruptedException { assertThat(intercept).isNotNull(); - driver.get(server.whereIs("/bidi/logEntryAdded.html")); + driver.get(appServer.whereIs("/bidi/logEntryAdded.html")); boolean countdown = latch.await(5, TimeUnit.SECONDS); assertThat(countdown).isTrue(); @@ -97,6 +88,7 @@ void canContinueRequest() throws InterruptedException { } @Test + @NeedsFreshDriver @NotYetImplemented(EDGE) @NotYetImplemented(CHROME) void canContinueResponse() throws InterruptedException { @@ -117,7 +109,7 @@ void canContinueResponse() throws InterruptedException { assertThat(intercept).isNotNull(); - driver.get(server.whereIs("/bidi/logEntryAdded.html")); + driver.get(appServer.whereIs("/bidi/logEntryAdded.html")); boolean countdown = latch.await(5, TimeUnit.SECONDS); assertThat(countdown).isTrue(); @@ -125,6 +117,7 @@ void canContinueResponse() throws InterruptedException { } @Test + @NeedsFreshDriver @NotYetImplemented(EDGE) @NotYetImplemented(CHROME) void canProvideResponse() throws InterruptedException { @@ -144,7 +137,7 @@ void canProvideResponse() throws InterruptedException { assertThat(intercept).isNotNull(); - driver.get(server.whereIs("/bidi/logEntryAdded.html")); + driver.get(appServer.whereIs("/bidi/logEntryAdded.html")); boolean countdown = latch.await(5, TimeUnit.SECONDS); assertThat(countdown).isTrue(); @@ -177,7 +170,7 @@ void canProvideResponseWithAllParameters() throws InterruptedException { assertThat(intercept).isNotNull(); - driver.get(server.whereIs("/bidi/logEntryAdded.html")); + driver.get(appServer.whereIs("/bidi/logEntryAdded.html")); boolean countdown = latch.await(5, TimeUnit.SECONDS); assertThat(countdown).isTrue(); @@ -187,6 +180,7 @@ void canProvideResponseWithAllParameters() throws InterruptedException { } @Test + @NeedsFreshDriver @NotYetImplemented(EDGE) @NotYetImplemented(CHROME) void canRemoveIntercept() { @@ -200,6 +194,7 @@ void canRemoveIntercept() { } @Test + @NeedsFreshDriver @NotYetImplemented(EDGE) @NotYetImplemented(CHROME) void canContinueWithAuthCredentials() { @@ -211,13 +206,14 @@ void canContinueWithAuthCredentials() { responseDetails.getRequest().getRequestId(), new UsernameAndPassword("test", "test"))); - page = server.whereIs("basicAuth"); + page = appServer.whereIs("basicAuth"); driver.get(page); assertThat(driver.findElement(By.tagName("h1")).getText()).isEqualTo("authorized"); } } @Test + @NeedsFreshDriver @NotYetImplemented(EDGE) @NotYetImplemented(CHROME) void canContinueWithoutAuthCredentials() { @@ -227,7 +223,7 @@ void canContinueWithoutAuthCredentials() { responseDetails -> // Does not handle the alert network.continueWithAuthNoCredentials(responseDetails.getRequest().getRequestId())); - page = server.whereIs("basicAuth"); + page = appServer.whereIs("basicAuth"); driver.get(page); // This would fail if alert was handled Alert alert = wait.until(ExpectedConditions.alertIsPresent()); @@ -236,6 +232,7 @@ void canContinueWithoutAuthCredentials() { } @Test + @NeedsFreshDriver @NotYetImplemented(EDGE) @NotYetImplemented(CHROME) void canCancelAuth() { @@ -245,7 +242,7 @@ void canCancelAuth() { responseDetails -> // Does not handle the alert network.cancelAuth(responseDetails.getRequest().getRequestId())); - page = server.whereIs("basicAuth"); + page = appServer.whereIs("basicAuth"); driver.get(page); assertThatThrownBy(() -> wait.until(ExpectedConditions.alertIsPresent())) .isInstanceOf(TimeoutException.class); @@ -253,6 +250,7 @@ void canCancelAuth() { } @Test + @NeedsFreshDriver @NotYetImplemented(EDGE) @NotYetImplemented(CHROME) void canFailRequest() { @@ -260,18 +258,10 @@ void canFailRequest() { network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT)); network.onBeforeRequestSent( responseDetails -> network.failRequest(responseDetails.getRequest().getRequestId())); - page = server.whereIs("basicAuth"); + page = appServer.whereIs("basicAuth"); driver.manage().timeouts().pageLoadTimeout(Duration.of(5, ChronoUnit.SECONDS)); assertThatThrownBy(() -> driver.get(page)).isInstanceOf(WebDriverException.class); } } - - @AfterEach - public void quitDriver() { - if (driver != null) { - driver.quit(); - } - safelyCall(server::stop); - } } diff --git a/java/test/org/openqa/selenium/bidi/network/NetworkEventsTest.java b/java/test/org/openqa/selenium/bidi/network/NetworkEventsTest.java index 28beec38ff0ab..7f221f6fc20bc 100644 --- a/java/test/org/openqa/selenium/bidi/network/NetworkEventsTest.java +++ b/java/test/org/openqa/selenium/bidi/network/NetworkEventsTest.java @@ -18,44 +18,34 @@ package org.openqa.selenium.bidi.network; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; -import static org.openqa.selenium.testing.Safely.safelyCall; import static org.openqa.selenium.testing.drivers.Browser.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.openqa.selenium.Cookie; import org.openqa.selenium.WebDriverException; import org.openqa.selenium.bidi.module.Network; -import org.openqa.selenium.environment.webserver.AppServer; -import org.openqa.selenium.environment.webserver.NettyAppServer; import org.openqa.selenium.testing.JupiterTestBase; +import org.openqa.selenium.testing.NeedsFreshDriver; import org.openqa.selenium.testing.NotYetImplemented; import org.openqa.selenium.testing.Pages; class NetworkEventsTest extends JupiterTestBase { private String page; - private AppServer server; - - @BeforeEach - public void setUp() { - server = new NettyAppServer(); - server.start(); - } @Test + @NeedsFreshDriver @NotYetImplemented(EDGE) void canListenToBeforeRequestSentEvent() throws ExecutionException, InterruptedException, TimeoutException { try (Network network = new Network(driver)) { CompletableFuture future = new CompletableFuture<>(); network.onBeforeRequestSent(future::complete); - page = server.whereIs("/bidi/logEntryAdded.html"); + page = appServer.whereIs("/bidi/logEntryAdded.html"); driver.get(page); BeforeRequestSent requestSent = future.get(5, TimeUnit.SECONDS); @@ -69,13 +59,14 @@ void canListenToBeforeRequestSentEvent() } @Test + @NeedsFreshDriver @NotYetImplemented(EDGE) void canListenToResponseStartedEvent() throws ExecutionException, InterruptedException, TimeoutException { try (Network network = new Network(driver)) { CompletableFuture future = new CompletableFuture<>(); network.onResponseStarted(future::complete); - page = server.whereIs("/bidi/logEntryAdded.html"); + page = appServer.whereIs("/bidi/logEntryAdded.html"); driver.get(page); ResponseDetails response = future.get(5, TimeUnit.SECONDS); @@ -91,13 +82,14 @@ void canListenToResponseStartedEvent() } @Test + @NeedsFreshDriver @NotYetImplemented(EDGE) void canListenToResponseCompletedEvent() throws ExecutionException, InterruptedException, TimeoutException { try (Network network = new Network(driver)) { CompletableFuture future = new CompletableFuture<>(); network.onResponseCompleted(future::complete); - page = server.whereIs("/bidi/logEntryAdded.html"); + page = appServer.whereIs("/bidi/logEntryAdded.html"); driver.get(page); ResponseDetails response = future.get(5, TimeUnit.SECONDS); @@ -113,13 +105,14 @@ void canListenToResponseCompletedEvent() } @Test + @NeedsFreshDriver @NotYetImplemented(EDGE) void canListenToResponseCompletedEventWithCookie() throws ExecutionException, InterruptedException, TimeoutException { try (Network network = new Network(driver)) { CompletableFuture future = new CompletableFuture<>(); - driver.get(new Pages(server).blankPage); + driver.get(new Pages(appServer).blankPage); driver.manage().addCookie(new Cookie("foo", "bar")); network.onBeforeRequestSent(future::complete); driver.navigate().refresh(); @@ -135,6 +128,7 @@ void canListenToResponseCompletedEventWithCookie() } @Test + @NeedsFreshDriver @NotYetImplemented(EDGE) @NotYetImplemented(CHROME) void canListenToOnAuthRequiredEvent() @@ -142,7 +136,7 @@ void canListenToOnAuthRequiredEvent() try (Network network = new Network(driver)) { CompletableFuture future = new CompletableFuture<>(); network.onAuthRequired(future::complete); - page = server.whereIs("basicAuth"); + page = appServer.whereIs("basicAuth"); driver.get(page); ResponseDetails response = future.get(5, TimeUnit.SECONDS); @@ -158,13 +152,14 @@ void canListenToOnAuthRequiredEvent() } @Test + @NeedsFreshDriver @NotYetImplemented(EDGE) @NotYetImplemented(CHROME) void canListenToFetchError() throws ExecutionException, InterruptedException, TimeoutException { try (Network network = new Network(driver)) { CompletableFuture future = new CompletableFuture<>(); network.onFetchError(future::complete); - page = server.whereIs("error"); + page = appServer.whereIs("error"); try { driver.get("https://not_a_valid_url.test/"); } catch (WebDriverException ignored) { @@ -181,12 +176,4 @@ void canListenToFetchError() throws ExecutionException, InterruptedException, Ti assertThat(fetchError.getErrorText()).contains("UNKNOWN_HOST"); } } - - @AfterEach - public void quitDriver() { - if (driver != null) { - driver.quit(); - } - safelyCall(server::stop); - } } diff --git a/java/test/org/openqa/selenium/bidi/script/CallFunctionParameterTest.java b/java/test/org/openqa/selenium/bidi/script/CallFunctionParameterTest.java index 7caeb5fa8aad7..e853e39296431 100644 --- a/java/test/org/openqa/selenium/bidi/script/CallFunctionParameterTest.java +++ b/java/test/org/openqa/selenium/bidi/script/CallFunctionParameterTest.java @@ -18,7 +18,6 @@ package org.openqa.selenium.bidi.script; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; -import static org.openqa.selenium.testing.Safely.safelyCall; import static org.openqa.selenium.testing.drivers.Browser.IE; import static org.openqa.selenium.testing.drivers.Browser.SAFARI; @@ -26,27 +25,17 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.openqa.selenium.By; import org.openqa.selenium.WindowType; import org.openqa.selenium.bidi.module.Script; -import org.openqa.selenium.environment.webserver.AppServer; -import org.openqa.selenium.environment.webserver.NettyAppServer; import org.openqa.selenium.testing.JupiterTestBase; +import org.openqa.selenium.testing.NeedsFreshDriver; import org.openqa.selenium.testing.NotYetImplemented; public class CallFunctionParameterTest extends JupiterTestBase { - private AppServer server; - - @BeforeEach - public void setUp() { - server = new NettyAppServer(); - server.start(); - } - @Test + @NeedsFreshDriver void canCallFunctionWithDeclaration() { String id = driver.getWindowHandle(); try (Script script = new Script(id, driver)) { @@ -65,6 +54,7 @@ void canCallFunctionWithDeclaration() { } @Test + @NeedsFreshDriver void canEvaluateScriptWithUserActivationTrue() { String id = driver.getWindowHandle(); try (Script script = new Script(id, driver)) { @@ -93,6 +83,7 @@ void canEvaluateScriptWithUserActivationTrue() { } @Test + @NeedsFreshDriver void canEvaluateScriptWithUserActivationFalse() { String id = driver.getWindowHandle(); try (Script script = new Script(id, driver)) { @@ -121,6 +112,7 @@ void canEvaluateScriptWithUserActivationFalse() { } @Test + @NeedsFreshDriver void canCallFunctionWithArguments() { String id = driver.getWindowHandle(); try (Script script = new Script(id, driver)) { @@ -147,6 +139,7 @@ void canCallFunctionWithArguments() { } @Test + @NeedsFreshDriver void canCallFunctionToGetIFrameBrowsingContext() { String url = appServer.whereIs("click_too_big_in_frame.html"); driver.get(url); @@ -180,6 +173,7 @@ void canCallFunctionToGetIFrameBrowsingContext() { } @Test + @NeedsFreshDriver void canCallFunctionToGetElement() { String url = appServer.whereIs("/bidi/logEntryAdded.html"); driver.get(url); @@ -207,6 +201,7 @@ void canCallFunctionToGetElement() { } @Test + @NeedsFreshDriver void canCallFunctionWithAwaitPromise() { String id = driver.getWindowHandle(); try (Script script = new Script(id, driver)) { @@ -233,6 +228,7 @@ void canCallFunctionWithAwaitPromise() { } @Test + @NeedsFreshDriver void canCallFunctionWithAwaitPromiseFalse() { String id = driver.getWindowHandle(); try (Script script = new Script(id, driver)) { @@ -257,6 +253,7 @@ void canCallFunctionWithAwaitPromiseFalse() { } @Test + @NeedsFreshDriver void canCallFunctionWithThisParameter() { String id = driver.getWindowHandle(); try (Script script = new Script(id, driver)) { @@ -282,6 +279,7 @@ void canCallFunctionWithThisParameter() { } @Test + @NeedsFreshDriver void canCallFunctionWithOwnershipRoot() { String id = driver.getWindowHandle(); try (Script script = new Script(id, driver)) { @@ -301,6 +299,7 @@ void canCallFunctionWithOwnershipRoot() { } @Test + @NeedsFreshDriver void canCallFunctionWithOwnershipNone() { String id = driver.getWindowHandle(); try (Script script = new Script(id, driver)) { @@ -320,6 +319,7 @@ void canCallFunctionWithOwnershipNone() { } @Test + @NeedsFreshDriver @NotYetImplemented(SAFARI) @NotYetImplemented(IE) void canCallFunctionThatThrowsException() { @@ -346,6 +346,7 @@ void canCallFunctionThatThrowsException() { } @Test + @NeedsFreshDriver void canCallFunctionInASandBox() { String id = driver.getWindowHandle(); try (Script script = new Script(id, driver)) { @@ -386,6 +387,7 @@ void canCallFunctionInASandBox() { } @Test + @NeedsFreshDriver void canCallFunctionInARealm() { String firstTab = driver.getWindowHandle(); String secondTab = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle(); @@ -430,12 +432,4 @@ void canCallFunctionInARealm() { assertThat((Long) successSecondContextresult.getResult().getValue().get()).isEqualTo(5L); } } - - @AfterEach - public void quitDriver() { - if (driver != null) { - driver.quit(); - } - safelyCall(server::stop); - } } diff --git a/java/test/org/openqa/selenium/bidi/script/EvaluateParametersTest.java b/java/test/org/openqa/selenium/bidi/script/EvaluateParametersTest.java index 7a3087d1136f2..e51dff72265fb 100644 --- a/java/test/org/openqa/selenium/bidi/script/EvaluateParametersTest.java +++ b/java/test/org/openqa/selenium/bidi/script/EvaluateParametersTest.java @@ -18,29 +18,19 @@ package org.openqa.selenium.bidi.script; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; -import static org.openqa.selenium.testing.Safely.safelyCall; import java.util.List; import java.util.Optional; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.openqa.selenium.WindowType; import org.openqa.selenium.bidi.module.Script; -import org.openqa.selenium.environment.webserver.AppServer; -import org.openqa.selenium.environment.webserver.NettyAppServer; import org.openqa.selenium.testing.JupiterTestBase; +import org.openqa.selenium.testing.NeedsFreshDriver; public class EvaluateParametersTest extends JupiterTestBase { - private AppServer server; - - @BeforeEach - public void setUp() { - server = new NettyAppServer(); - server.start(); - } @Test + @NeedsFreshDriver void canEvaluateScript() { String id = driver.getWindowHandle(); try (Script script = new Script(id, driver)) { @@ -58,6 +48,7 @@ void canEvaluateScript() { } @Test + @NeedsFreshDriver void canEvaluateScriptWithUserActivationTrue() { String id = driver.getWindowHandle(); try (Script script = new Script(id, driver)) { @@ -85,6 +76,7 @@ void canEvaluateScriptWithUserActivationTrue() { } @Test + @NeedsFreshDriver void canEvaluateScriptWithUserActivationFalse() { String id = driver.getWindowHandle(); try (Script script = new Script(id, driver)) { @@ -112,6 +104,7 @@ void canEvaluateScriptWithUserActivationFalse() { } @Test + @NeedsFreshDriver void canEvaluateScriptThatThrowsException() { String id = driver.getWindowHandle(); try (Script script = new Script(id, driver)) { @@ -133,6 +126,7 @@ void canEvaluateScriptThatThrowsException() { } @Test + @NeedsFreshDriver void canEvaluateScriptWithResulWithOwnership() { String id = driver.getWindowHandle(); try (Script script = new Script(id, driver)) { @@ -152,6 +146,7 @@ void canEvaluateScriptWithResulWithOwnership() { } @Test + @NeedsFreshDriver void canEvaluateInASandBox() { String id = driver.getWindowHandle(); try (Script script = new Script(id, driver)) { @@ -191,6 +186,7 @@ void canEvaluateInASandBox() { } @Test + @NeedsFreshDriver void canEvaluateInARealm() { String firstTab = driver.getWindowHandle(); String secondTab = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle(); @@ -229,12 +225,4 @@ void canEvaluateInARealm() { assertThat((Long) successSecondContextResult.getResult().getValue().get()).isEqualTo(5L); } } - - @AfterEach - public void quitDriver() { - if (driver != null) { - driver.quit(); - } - safelyCall(server::stop); - } } diff --git a/java/test/org/openqa/selenium/bidi/script/ScriptCommandsTest.java b/java/test/org/openqa/selenium/bidi/script/ScriptCommandsTest.java index 108e2d1554513..059ca1bb43814 100644 --- a/java/test/org/openqa/selenium/bidi/script/ScriptCommandsTest.java +++ b/java/test/org/openqa/selenium/bidi/script/ScriptCommandsTest.java @@ -19,7 +19,6 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; -import static org.openqa.selenium.testing.Safely.safelyCall; import java.util.ArrayList; import java.util.HashMap; @@ -31,8 +30,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicReference; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.openqa.selenium.By; import org.openqa.selenium.WebDriverException; @@ -41,21 +38,14 @@ import org.openqa.selenium.bidi.log.LogLevel; import org.openqa.selenium.bidi.module.LogInspector; import org.openqa.selenium.bidi.module.Script; -import org.openqa.selenium.environment.webserver.AppServer; -import org.openqa.selenium.environment.webserver.NettyAppServer; import org.openqa.selenium.testing.JupiterTestBase; +import org.openqa.selenium.testing.NeedsFreshDriver; import org.openqa.selenium.testing.Pages; public class ScriptCommandsTest extends JupiterTestBase { - private AppServer server; - - @BeforeEach - public void setUp() { - server = new NettyAppServer(); - server.start(); - } @Test + @NeedsFreshDriver void canCallFunctionWithDeclaration() { String id = driver.getWindowHandle(); Script script = new Script(id, driver); @@ -74,6 +64,7 @@ void canCallFunctionWithDeclaration() { } @Test + @NeedsFreshDriver void canCallFunctionWithArguments() { String id = driver.getWindowHandle(); Script script = new Script(id, driver); @@ -103,6 +94,7 @@ void canCallFunctionWithArguments() { } @Test + @NeedsFreshDriver void canCallFunctionToGetIFrameBrowsingContext() { String url = appServer.whereIs("click_too_big_in_frame.html"); driver.get(url); @@ -136,6 +128,7 @@ void canCallFunctionToGetIFrameBrowsingContext() { } @Test + @NeedsFreshDriver void canCallFunctionToGetElement() { String url = appServer.whereIs("/bidi/logEntryAdded.html"); driver.get(url); @@ -165,6 +158,7 @@ void canCallFunctionToGetElement() { } @Test + @NeedsFreshDriver void canCallFunctionWithAwaitPromise() { String id = driver.getWindowHandle(); Script script = new Script(id, driver); @@ -192,6 +186,7 @@ void canCallFunctionWithAwaitPromise() { } @Test + @NeedsFreshDriver void canCallFunctionWithAwaitPromiseFalse() { String id = driver.getWindowHandle(); Script script = new Script(id, driver); @@ -217,6 +212,7 @@ void canCallFunctionWithAwaitPromiseFalse() { } @Test + @NeedsFreshDriver void canCallFunctionWithThisParameter() { String id = driver.getWindowHandle(); Script script = new Script(id, driver); @@ -244,6 +240,7 @@ void canCallFunctionWithThisParameter() { } @Test + @NeedsFreshDriver void canCallFunctionWithOwnershipRoot() { String id = driver.getWindowHandle(); Script script = new Script(id, driver); @@ -266,6 +263,7 @@ void canCallFunctionWithOwnershipRoot() { } @Test + @NeedsFreshDriver void canCallFunctionWithOwnershipNone() { String id = driver.getWindowHandle(); Script script = new Script(id, driver); @@ -288,6 +286,7 @@ void canCallFunctionWithOwnershipNone() { } @Test + @NeedsFreshDriver void canCallFunctionThatThrowsException() { String id = driver.getWindowHandle(); Script script = new Script(id, driver); @@ -313,6 +312,7 @@ void canCallFunctionThatThrowsException() { } @Test + @NeedsFreshDriver void canCallFunctionInASandBox() { String id = driver.getWindowHandle(); Script script = new Script(id, driver); @@ -373,6 +373,7 @@ void canCallFunctionInASandBox() { } @Test + @NeedsFreshDriver void canCallFunctionInARealm() { String firstTab = driver.getWindowHandle(); String secondTab = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle(); @@ -433,6 +434,7 @@ void canCallFunctionInARealm() { } @Test + @NeedsFreshDriver void canEvaluateScript() { String id = driver.getWindowHandle(); Script script = new Script(id, driver); @@ -450,6 +452,7 @@ void canEvaluateScript() { } @Test + @NeedsFreshDriver void canEvaluateScriptThatThrowsException() { String id = driver.getWindowHandle(); Script script = new Script(id, driver); @@ -469,6 +472,7 @@ void canEvaluateScriptThatThrowsException() { } @Test + @NeedsFreshDriver void canEvaluateScriptWithResulWithOwnership() { String id = driver.getWindowHandle(); Script script = new Script(id, driver); @@ -487,6 +491,7 @@ void canEvaluateScriptWithResulWithOwnership() { } @Test + @NeedsFreshDriver void canEvaluateInASandBox() { String id = driver.getWindowHandle(); Script script = new Script(id, driver); @@ -523,6 +528,7 @@ void canEvaluateInASandBox() { } @Test + @NeedsFreshDriver void canEvaluateInARealm() { String firstTab = driver.getWindowHandle(); String secondTab = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle(); @@ -559,6 +565,7 @@ void canEvaluateInARealm() { } @Test + @NeedsFreshDriver void canDisownHandles() { String id = driver.getWindowHandle(); Script script = new Script(id, driver); @@ -615,6 +622,7 @@ void canDisownHandles() { } @Test + @NeedsFreshDriver void canDisownHandlesInRealm() { String id = driver.getWindowHandle(); Script script = new Script(id, driver); @@ -671,6 +679,7 @@ void canDisownHandlesInRealm() { } @Test + @NeedsFreshDriver void canGetAllRealms() { String firstWindow = driver.getWindowHandle(); String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle(); @@ -695,6 +704,7 @@ void canGetAllRealms() { } @Test + @NeedsFreshDriver void canGetRealmByType() { String firstWindow = driver.getWindowHandle(); String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle(); @@ -719,6 +729,7 @@ void canGetRealmByType() { } @Test + @NeedsFreshDriver void canGetRealmInBrowsingContext() { String windowId = driver.getWindowHandle(); String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle(); @@ -735,6 +746,7 @@ void canGetRealmInBrowsingContext() { } @Test + @NeedsFreshDriver void canGetRealmInBrowsingContextByType() { String windowId = driver.getWindowHandle(); driver.switchTo().newWindow(WindowType.TAB).getWindowHandle(); @@ -752,6 +764,7 @@ void canGetRealmInBrowsingContextByType() { } @Test + @NeedsFreshDriver void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException { Script script = new Script(driver); String id = script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}"); @@ -763,7 +776,7 @@ void canAddPreloadScript() throws ExecutionException, InterruptedException, Time CompletableFuture future = new CompletableFuture<>(); logInspector.onConsoleEntry(future::complete); - driver.get(new Pages(server).blankPage); + driver.get(new Pages(appServer).blankPage); ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS); @@ -774,6 +787,7 @@ void canAddPreloadScript() throws ExecutionException, InterruptedException, Time } @Test + @NeedsFreshDriver void canAddPreloadScriptWithArguments() { Script script = new Script(driver); String id = @@ -785,6 +799,7 @@ void canAddPreloadScriptWithArguments() { } @Test + @NeedsFreshDriver void canAddPreloadScriptWithChannelOptions() { Script script = new Script(driver); SerializationOptions serializationOptions = new SerializationOptions(); @@ -798,13 +813,14 @@ void canAddPreloadScriptWithChannelOptions() { } @Test + @NeedsFreshDriver void canAddPreloadScriptInASandbox() { Script script = new Script(driver); String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox"); assertThat(id).isNotNull(); assertThat(id).isNotEmpty(); - driver.get(new Pages(server).blankPage); + driver.get(new Pages(appServer).blankPage); EvaluateResult result = script.evaluateFunctionInBrowsingContext( @@ -814,13 +830,14 @@ void canAddPreloadScriptInASandbox() { } @Test + @NeedsFreshDriver void canRemovePreloadedScript() { Script script = new Script(driver.getWindowHandle(), driver); String id = script.addPreloadScript("() => { window.bar=2; }"); assertThat(id).isNotNull(); assertThat(id).isNotEmpty(); - driver.get(new Pages(server).blankPage); + driver.get(new Pages(appServer).blankPage); EvaluateResult result = script.evaluateFunctionInBrowsingContext( @@ -837,12 +854,4 @@ void canRemovePreloadedScript() { assertThat(((EvaluateResultSuccess) resultAfterRemoval).getResult().getValue().isPresent()) .isFalse(); } - - @AfterEach - public void quitDriver() { - if (driver != null) { - driver.quit(); - } - safelyCall(server::stop); - } } diff --git a/java/test/org/openqa/selenium/bidi/script/ScriptEventsTest.java b/java/test/org/openqa/selenium/bidi/script/ScriptEventsTest.java index 6696794291447..8893ff050ab10 100644 --- a/java/test/org/openqa/selenium/bidi/script/ScriptEventsTest.java +++ b/java/test/org/openqa/selenium/bidi/script/ScriptEventsTest.java @@ -17,7 +17,6 @@ package org.openqa.selenium.bidi.script; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; -import static org.openqa.selenium.testing.Safely.safelyCall; import static org.openqa.selenium.testing.drivers.Browser.*; import java.util.List; @@ -26,27 +25,18 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.openqa.selenium.bidi.browsingcontext.BrowsingContext; import org.openqa.selenium.bidi.module.Script; -import org.openqa.selenium.environment.webserver.AppServer; -import org.openqa.selenium.environment.webserver.NettyAppServer; import org.openqa.selenium.testing.JupiterTestBase; +import org.openqa.selenium.testing.NeedsFreshDriver; import org.openqa.selenium.testing.NotYetImplemented; import org.openqa.selenium.testing.Pages; public class ScriptEventsTest extends JupiterTestBase { - private AppServer server; - - @BeforeEach - public void setUp() { - server = new NettyAppServer(); - server.start(); - } @Test + @NeedsFreshDriver void canListenToChannelMessage() throws ExecutionException, InterruptedException, TimeoutException { try (Script script = new Script(driver)) { @@ -74,6 +64,7 @@ void canListenToChannelMessage() } @Test + @NeedsFreshDriver void canListenToRealmCreatedEvent() throws ExecutionException, InterruptedException, TimeoutException { try (Script script = new Script(driver)) { @@ -82,7 +73,7 @@ void canListenToRealmCreatedEvent() BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle()); - context.navigate(new Pages(server).blankPage); + context.navigate(new Pages(appServer).blankPage); RealmInfo realmInfo = future.get(5, TimeUnit.SECONDS); assertThat(realmInfo.getRealmId()).isNotNull(); assertThat(realmInfo.getRealmType()).isEqualTo(RealmType.WINDOW); @@ -90,6 +81,7 @@ void canListenToRealmCreatedEvent() } @Test + @NeedsFreshDriver @NotYetImplemented(EDGE) @NotYetImplemented(CHROME) @NotYetImplemented(FIREFOX) @@ -107,12 +99,4 @@ void canListenToRealmDestroyedEvent() assertThat(realmInfo.getRealmType()).isEqualTo(RealmType.WINDOW); } } - - @AfterEach - public void quitDriver() { - if (driver != null) { - driver.quit(); - } - safelyCall(server::stop); - } } diff --git a/java/test/org/openqa/selenium/environment/InProcessTestEnvironment.java b/java/test/org/openqa/selenium/environment/InProcessTestEnvironment.java index 150f0a2685a5a..70b29dfd27a70 100644 --- a/java/test/org/openqa/selenium/environment/InProcessTestEnvironment.java +++ b/java/test/org/openqa/selenium/environment/InProcessTestEnvironment.java @@ -24,8 +24,8 @@ public class InProcessTestEnvironment implements TestEnvironment { private final AppServer appServer; - public InProcessTestEnvironment() { - appServer = new NettyAppServer(); + public InProcessTestEnvironment(boolean secureServer) { + appServer = new NettyAppServer(secureServer); appServer.start(); } @@ -40,6 +40,6 @@ public void stop() { } public static void main(String[] args) { - new InProcessTestEnvironment(); + new InProcessTestEnvironment(true); } } diff --git a/java/test/org/openqa/selenium/environment/webserver/NettyAppServer.java b/java/test/org/openqa/selenium/environment/webserver/NettyAppServer.java index d477bb4f1a2fd..04316b0e451d8 100644 --- a/java/test/org/openqa/selenium/environment/webserver/NettyAppServer.java +++ b/java/test/org/openqa/selenium/environment/webserver/NettyAppServer.java @@ -68,13 +68,13 @@ public class NettyAppServer implements AppServer { LOG.log( Level.WARNING, String.format("NettyAppServer retry #%s. ", e.getAttemptCount())); - initValues(); + initValues(secure != null); }) .onRetriesExceeded(e -> LOG.log(Level.WARNING, "NettyAppServer start aborted.")) .build(); - public NettyAppServer() { - initValues(); + public NettyAppServer(boolean secureServer) { + initValues(secureServer); } public NettyAppServer(HttpHandler handler) { @@ -116,7 +116,7 @@ public static void main(String[] args) { System.out.printf("Server started. Root URL: %s%n", server.whereIs("/")); } - private void initValues() { + private void initValues(boolean secureServer) { Config config = createDefaultConfig(); BaseServerOptions options = new BaseServerOptions(config); @@ -128,16 +128,18 @@ private void initValues() { server = new NettyServer(options, handler); - Config secureConfig = new CompoundConfig(sslConfig, createDefaultConfig()); - BaseServerOptions secureOptions = new BaseServerOptions(secureConfig); + if (secureServer) { + Config secureConfig = new CompoundConfig(sslConfig, createDefaultConfig()); + BaseServerOptions secureOptions = new BaseServerOptions(secureConfig); - HttpHandler secureHandler = - new HandlersForTests( - secureOptions.getHostname().orElse("localhost"), - secureOptions.getPort(), - tempDir.toPath()); + HttpHandler secureHandler = + new HandlersForTests( + secureOptions.getHostname().orElse("localhost"), + secureOptions.getPort(), + tempDir.toPath()); - secure = new NettyServer(secureOptions, secureHandler); + secure = new NettyServer(secureOptions, secureHandler); + } } @Override diff --git a/java/test/org/openqa/selenium/environment/webserver/NettyAppServerTest.java b/java/test/org/openqa/selenium/environment/webserver/NettyAppServerTest.java index 86b40e0282449..3574739763528 100644 --- a/java/test/org/openqa/selenium/environment/webserver/NettyAppServerTest.java +++ b/java/test/org/openqa/selenium/environment/webserver/NettyAppServerTest.java @@ -21,6 +21,6 @@ class NettyAppServerTest extends AppServerTestBase { @Override protected AppServer createAppServer() { - return new NettyAppServer(); + return new NettyAppServer(false); } } diff --git a/java/test/org/openqa/selenium/federatedcredentialmanagement/FederatedCredentialManagementTest.java b/java/test/org/openqa/selenium/federatedcredentialmanagement/FederatedCredentialManagementTest.java index 8bf947f4ca584..ddb9b5b462f45 100644 --- a/java/test/org/openqa/selenium/federatedcredentialmanagement/FederatedCredentialManagementTest.java +++ b/java/test/org/openqa/selenium/federatedcredentialmanagement/FederatedCredentialManagementTest.java @@ -36,8 +36,10 @@ import org.openqa.selenium.chrome.ChromeOptions; import org.openqa.selenium.support.ui.WebDriverWait; import org.openqa.selenium.testing.JupiterTestBase; +import org.openqa.selenium.testing.NeedsSecureServer; import org.openqa.selenium.testing.NotYetImplemented; +@NeedsSecureServer class FederatedCredentialManagementTest extends JupiterTestBase { private JavascriptExecutor jsAwareDriver; diff --git a/java/test/org/openqa/selenium/grid/config/BUILD.bazel b/java/test/org/openqa/selenium/grid/config/BUILD.bazel index fb4e41dcd7875..9575e42d240fb 100644 --- a/java/test/org/openqa/selenium/grid/config/BUILD.bazel +++ b/java/test/org/openqa/selenium/grid/config/BUILD.bazel @@ -11,7 +11,6 @@ java_test_suite( "//java/src/org/openqa/selenium/json", artifact("com.beust:jcommander"), artifact("com.google.guava:guava"), - artifact("io.ous:jtoml"), artifact("org.junit.jupiter:junit-jupiter-api"), artifact("org.assertj:assertj-core"), ] + JUNIT5_DEPS, diff --git a/java/test/org/openqa/selenium/grid/config/TomlConfigTest.java b/java/test/org/openqa/selenium/grid/config/TomlConfigTest.java index 2de672f07d78e..9eaedae3c258b 100644 --- a/java/test/org/openqa/selenium/grid/config/TomlConfigTest.java +++ b/java/test/org/openqa/selenium/grid/config/TomlConfigTest.java @@ -18,6 +18,7 @@ package org.openqa.selenium.grid.config; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import java.io.StringReader; import java.util.Arrays; @@ -30,18 +31,24 @@ class TomlConfigTest { @Test void shouldUseATableAsASection() { - String raw = "[cheeses]\nselected=brie"; + String raw = "[cheeses]\nselected=\"brie\""; Config config = new TomlConfig(new StringReader(raw)); - assertThat(config.get("cheeses", "selected")).isEqualTo(Optional.of("brie")); } + @Test + void shouldCheckForErrorsAndThrow() { + String raw = "[cheeses]\nselected=brie"; + assertThatThrownBy(() -> new TomlConfig(new StringReader(raw))) + .isInstanceOf(ConfigException.class); + } + @Test void shouldContainConfigFromArrayOfTables() { String[] rawConfig = new String[] { "[cheeses]", - "default = manchego", + "default = \"manchego\"", "[[cheeses.type]]", "name = \"soft cheese\"", "default = \"brie\"", @@ -104,7 +111,7 @@ void ensureCanReadListOfLists() { String[] rawConfig = new String[] { "[cheeses]", - "default = manchego", + "default = \"manchego\"", "[[cheeses.type]]", "name = \"soft cheese\"", "default = \"brie\"", diff --git a/java/test/org/openqa/selenium/grid/node/ForwardWebDriverCommandTest.java b/java/test/org/openqa/selenium/grid/node/ForwardWebDriverCommandTest.java index 8f0df29251870..e52f5d7d45e77 100644 --- a/java/test/org/openqa/selenium/grid/node/ForwardWebDriverCommandTest.java +++ b/java/test/org/openqa/selenium/grid/node/ForwardWebDriverCommandTest.java @@ -17,12 +17,12 @@ package org.openqa.selenium.grid.node; -import static java.net.HttpURLConnection.HTTP_INTERNAL_ERROR; +import static java.net.HttpURLConnection.HTTP_NOT_FOUND; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.*; import static org.openqa.selenium.remote.http.Contents.asJson; -import com.google.common.collect.ImmutableMap; +import java.util.Map; import java.util.UUID; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -69,11 +69,18 @@ void testExecuteWithInvalidSessionOwner() { HttpResponse actualResponse = command.execute(mockRequest); HttpResponse expectResponse = new HttpResponse() - .setStatus(HTTP_INTERNAL_ERROR) + .setStatus(HTTP_NOT_FOUND) .setContent( asJson( - ImmutableMap.of( - "error", String.format("Session not found in node %s", mockNode.getId())))); + Map.of( + "value", + Map.of( + "error", + "invalid session id", + "message", + "Cannot find session with id: " + sessionId, + "stacktrace", + "")))); assertEquals(expectResponse.getStatus(), actualResponse.getStatus()); assertEquals(expectResponse.getContentEncoding(), actualResponse.getContentEncoding()); } diff --git a/java/test/org/openqa/selenium/grid/node/NodeTest.java b/java/test/org/openqa/selenium/grid/node/NodeTest.java index c2a66d2162c4b..b9e8fcc7399de 100644 --- a/java/test/org/openqa/selenium/grid/node/NodeTest.java +++ b/java/test/org/openqa/selenium/grid/node/NodeTest.java @@ -23,8 +23,6 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.InstanceOfAssertFactories.MAP; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.openqa.selenium.json.Json.MAP_TYPE; import static org.openqa.selenium.remote.http.Contents.string; import static org.openqa.selenium.remote.http.HttpMethod.DELETE; @@ -402,20 +400,14 @@ void shouldOnlyRespondToWebDriverCommandsForSessionsTheNodeOwns() { assertThat(node2.matches(req2)).isTrue(); // Assert that should not respond to commands for sessions Node 1 does not own - NoSuchSessionException exception = - assertThrows(NoSuchSessionException.class, () -> node.execute(req2)); - assertTrue( - exception - .getMessage() - .startsWith(String.format("Cannot find session with id: %s", session2.getId()))); + HttpResponse res1 = node.execute(req2); + assertThat(res1.getStatus()).isEqualTo(404); + assertThat(Contents.string(res1)).contains("invalid session id"); // Assert that should not respond to commands for sessions Node 2 does not own - NoSuchSessionException exception2 = - assertThrows(NoSuchSessionException.class, () -> node2.execute(req)); - assertTrue( - exception2 - .getMessage() - .startsWith(String.format("Cannot find session with id: %s", session.getId()))); + HttpResponse res2 = node2.execute(req); + assertThat(res2.getStatus()).isEqualTo(404); + assertThat(Contents.string(res2)).contains("invalid session id"); } @Test diff --git a/java/test/org/openqa/selenium/grid/router/DistributedCdpTest.java b/java/test/org/openqa/selenium/grid/router/DistributedCdpTest.java index 40d0bf46ad8a8..ceb1cf37a1eb7 100644 --- a/java/test/org/openqa/selenium/grid/router/DistributedCdpTest.java +++ b/java/test/org/openqa/selenium/grid/router/DistributedCdpTest.java @@ -68,7 +68,7 @@ void ensureBasicFunctionality() { "[node]\n" + "selenium-manager = false\n" + "driver-implementation = " - + browser.displayName()))); + + String.format("\"%s\"", browser.displayName())))); Server server = new NettyServer( diff --git a/java/test/org/openqa/selenium/grid/router/RemoteWebDriverBiDiTest.java b/java/test/org/openqa/selenium/grid/router/RemoteWebDriverBiDiTest.java index aee7a084a388b..5538b346022ed 100644 --- a/java/test/org/openqa/selenium/grid/router/RemoteWebDriverBiDiTest.java +++ b/java/test/org/openqa/selenium/grid/router/RemoteWebDriverBiDiTest.java @@ -27,7 +27,9 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.openqa.selenium.By; @@ -54,8 +56,14 @@ import org.openqa.selenium.testing.drivers.Browser; class RemoteWebDriverBiDiTest { + private static AppServer server; private WebDriver driver; - private AppServer server; + + @BeforeAll + static void serverSetup() { + server = new NettyAppServer(false); + server.start(); + } @BeforeEach void setup() { @@ -69,13 +77,10 @@ void setup() { "[node]\n" + "selenium-manager = false\n" + "driver-implementation = " - + browser.displayName()))); + + String.format("\"%s\"", browser.displayName())))); driver = new RemoteWebDriver(deployment.getServer().getUrl(), browser.getCapabilities()); driver = new Augmenter().augment(driver); - - server = new NettyAppServer(); - server.start(); } @Test @@ -138,6 +143,10 @@ void canNavigateToUrl() { @AfterEach void clean() { driver.quit(); + } + + @AfterAll + static void stopServer() { server.stop(); } } diff --git a/java/test/org/openqa/selenium/grid/router/RemoteWebDriverDownloadTest.java b/java/test/org/openqa/selenium/grid/router/RemoteWebDriverDownloadTest.java index 96f9ba64b23bf..c8cea51cbaecb 100644 --- a/java/test/org/openqa/selenium/grid/router/RemoteWebDriverDownloadTest.java +++ b/java/test/org/openqa/selenium/grid/router/RemoteWebDriverDownloadTest.java @@ -84,11 +84,11 @@ public void setupServers() { + "selenium-manager = true\n" + "enable-managed-downloads = true\n" + "driver-implementation = " - + browser.displayName()))); + + String.format("\"%s\"", browser.displayName())))); tearDowns.add(deployment); server = deployment.getServer(); - appServer = new NettyAppServer(); + appServer = new NettyAppServer(false); tearDowns.add(() -> appServer.stop()); appServer.start(); } diff --git a/java/test/org/openqa/selenium/grid/router/StressTest.java b/java/test/org/openqa/selenium/grid/router/StressTest.java index 3be76395e4f01..bfc892ada697e 100644 --- a/java/test/org/openqa/selenium/grid/router/StressTest.java +++ b/java/test/org/openqa/selenium/grid/router/StressTest.java @@ -73,10 +73,15 @@ public void setupServers() { new StringReader( "[node]\n" + "driver-implementation = " - + browser.displayName() + + String.format("\"%s\"", browser.displayName()) + "\n" + "session-timeout = 11" + "\n" + + "overwrite-max-sessions = true" + + "\n" + + "max-sessions = " + + Runtime.getRuntime().availableProcessors() * 2 + + "\n" + "enable-managed-downloads = true"))); tearDowns.add(deployment); diff --git a/java/test/org/openqa/selenium/javascript/JavaScriptTestSuite.java b/java/test/org/openqa/selenium/javascript/JavaScriptTestSuite.java index a9052a500b8a3..cbb5f660b959a 100644 --- a/java/test/org/openqa/selenium/javascript/JavaScriptTestSuite.java +++ b/java/test/org/openqa/selenium/javascript/JavaScriptTestSuite.java @@ -61,7 +61,8 @@ private static boolean isBazel() { @BeforeEach public void setup() { - testEnvironment = GlobalTestEnvironment.getOrCreate(InProcessTestEnvironment::new); + // this field is actually in use, javascript test do access it + testEnvironment = GlobalTestEnvironment.getOrCreate(() -> new InProcessTestEnvironment(true)); } @AfterEach diff --git a/java/test/org/openqa/selenium/remote/http/FormEncodedDataTest.java b/java/test/org/openqa/selenium/remote/http/FormEncodedDataTest.java deleted file mode 100644 index 063446a56c624..0000000000000 --- a/java/test/org/openqa/selenium/remote/http/FormEncodedDataTest.java +++ /dev/null @@ -1,150 +0,0 @@ -// 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. - -package org.openqa.selenium.remote.http; - -import static java.nio.charset.StandardCharsets.UTF_8; -import static java.util.Collections.singletonList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Fail.fail; -import static org.openqa.selenium.remote.http.Contents.bytes; -import static org.openqa.selenium.remote.http.Contents.utf8String; -import static org.openqa.selenium.remote.http.HttpMethod.GET; - -import com.google.common.collect.ImmutableMap; -import com.google.common.net.MediaType; -import java.net.URLEncoder; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - -@Tag("UnitTests") -class FormEncodedDataTest { - - @Test - void shouldRequireCorrectContentType() { - HttpRequest request = createRequest("key", "value").removeHeader("Content-Type"); - Optional>> data = FormEncodedData.getData(request); - - assertThat(data).isNotPresent(); - } - - @Test - void canReadASinglePairOfValues() { - HttpRequest request = createRequest("key", "value"); - - Optional>> data = FormEncodedData.getData(request); - - assertThat(data.get()).isEqualTo(ImmutableMap.of("key", singletonList("value"))); - } - - @Test - void canReadTwoValues() { - HttpRequest request = createRequest("key", "value", "foo", "bar"); - - Optional>> data = FormEncodedData.getData(request); - - assertThat(data.get()) - .isEqualTo(ImmutableMap.of("key", singletonList("value"), "foo", singletonList("bar"))); - } - - @Test - void shouldSetEmptyValuesToTheEmptyString() { - HttpRequest request = createRequest("key", null); - - Optional>> data = FormEncodedData.getData(request); - - assertThat(data.get()).isEqualTo(ImmutableMap.of("key", singletonList(""))); - } - - @Test - void shouldDecodeParameterNames() { - HttpRequest request = createRequest("%foo%", "value"); - - Optional>> data = FormEncodedData.getData(request); - - assertThat(data.get()).isEqualTo(ImmutableMap.of("%foo%", singletonList("value"))); - } - - @Test - void shouldDecodeParameterValues() { - HttpRequest request = createRequest("key", "%bar%"); - - Optional>> data = FormEncodedData.getData(request); - - assertThat(data.get()).isEqualTo(ImmutableMap.of("key", singletonList("%bar%"))); - } - - @Test - void shouldCollectMultipleValuesForTheSameParameterNamePreservingOrder() { - HttpRequest request = createRequest("foo", "bar", "foo", "baz"); - - Optional>> data = FormEncodedData.getData(request); - - assertThat(data.get()).isEqualTo(ImmutableMap.of("foo", Arrays.asList("bar", "baz"))); - } - - @Test - void aSingleParameterNameIsEnough() { - HttpRequest request = - new HttpRequest(GET, "/example") - .addHeader("Content-Type", MediaType.FORM_DATA.toString()) - .setContent(bytes("param".getBytes())); - - Optional>> data = FormEncodedData.getData(request); - - assertThat(data.get()).isEqualTo(ImmutableMap.of("param", singletonList(""))); - } - - private HttpRequest createRequest(String key, String value, String... others) { - if (others.length % 2 != 0) { - fail("Other parameters must be of even length"); - } - - List allStrings = new ArrayList<>(); - allStrings.add(key); - allStrings.add(value); - allStrings.addAll(Arrays.asList(others)); - - StringBuilder content = new StringBuilder(); - Iterator iterator = allStrings.iterator(); - boolean isFirst = true; - while (iterator.hasNext()) { - if (!isFirst) { - content.append("&"); - } - content.append(URLEncoder.encode(iterator.next(), UTF_8)); - - String next = iterator.next(); - if (next != null) { - content.append("=").append(URLEncoder.encode(next, UTF_8)); - } - if (isFirst) { - isFirst = false; - } - } - - return new HttpRequest(GET, "/foo") - .addHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8") - .setContent(utf8String(content.toString())); - } -} diff --git a/java/test/org/openqa/selenium/safari/CrossDomainTest.java b/java/test/org/openqa/selenium/safari/CrossDomainTest.java index 2f9e5c4a51724..842f0fc7db4c4 100644 --- a/java/test/org/openqa/selenium/safari/CrossDomainTest.java +++ b/java/test/org/openqa/selenium/safari/CrossDomainTest.java @@ -41,7 +41,7 @@ class CrossDomainTest extends JupiterTestBase { @BeforeAll public static void startSecondServer() { - otherServer = new NettyAppServer(); + otherServer = new NettyAppServer(false); otherServer.start(); otherPages = new Pages(otherServer); diff --git a/java/test/org/openqa/selenium/testing/BUILD.bazel b/java/test/org/openqa/selenium/testing/BUILD.bazel index 9bc398860502a..68d6d6a2f675d 100644 --- a/java/test/org/openqa/selenium/testing/BUILD.bazel +++ b/java/test/org/openqa/selenium/testing/BUILD.bazel @@ -20,6 +20,7 @@ java_library( "Ignore.java", "IgnoreList.java", "NeedsFreshDriver.java", + "NeedsSecureServer.java", "NoDriverAfterTest.java", "NoDriverBeforeTest.java", "NotWorkingInRemoteBazelBuilds.java", diff --git a/java/test/org/openqa/selenium/testing/JupiterTestBase.java b/java/test/org/openqa/selenium/testing/JupiterTestBase.java index bd42009600ba5..a540bafb7c849 100644 --- a/java/test/org/openqa/selenium/testing/JupiterTestBase.java +++ b/java/test/org/openqa/selenium/testing/JupiterTestBase.java @@ -22,6 +22,8 @@ import java.net.MalformedURLException; import java.net.URL; import java.time.Duration; +import java.util.Optional; +import java.util.logging.Logger; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; @@ -37,6 +39,8 @@ public abstract class JupiterTestBase { + private static final Logger LOG = Logger.getLogger(JupiterTestBase.class.getName()); + @RegisterExtension protected static SeleniumExtension seleniumExtension = new SeleniumExtension(); protected TestEnvironment environment; @@ -54,9 +58,27 @@ public static void shouldTestBeRunAtAll() { @BeforeEach public void prepareEnvironment() { - environment = GlobalTestEnvironment.getOrCreate(InProcessTestEnvironment::new); + boolean needsSecureServer = + Optional.ofNullable(this.getClass().getAnnotation(NeedsSecureServer.class)) + .map(NeedsSecureServer::value) + .orElse(false); + + environment = + GlobalTestEnvironment.getOrCreate(() -> new InProcessTestEnvironment(needsSecureServer)); appServer = environment.getAppServer(); + if (needsSecureServer) { + try { + appServer.whereIsSecure("/"); + } catch (IllegalStateException ex) { + // this should not happen with bazel, a new JVM is used for each class + // the annotation is on class level, so we should never see this + LOG.info("appServer is restarted with secureServer=true"); + environment.stop(); + environment = new InProcessTestEnvironment(true); + } + } + pages = new Pages(appServer); driver = seleniumExtension.getDriver(); diff --git a/java/test/org/openqa/selenium/testing/NeedsSecureServer.java b/java/test/org/openqa/selenium/testing/NeedsSecureServer.java new file mode 100644 index 0000000000000..beda0b16d666b --- /dev/null +++ b/java/test/org/openqa/selenium/testing/NeedsSecureServer.java @@ -0,0 +1,30 @@ +// 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. + +package org.openqa.selenium.testing; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface NeedsSecureServer { + + boolean value() default true; +} diff --git a/java/test/org/openqa/selenium/testing/drivers/Browser.java b/java/test/org/openqa/selenium/testing/drivers/Browser.java index bab6e081dbd5b..a75d321bd7ac8 100644 --- a/java/test/org/openqa/selenium/testing/drivers/Browser.java +++ b/java/test/org/openqa/selenium/testing/drivers/Browser.java @@ -83,7 +83,7 @@ public Capabilities getCapabilities() { } if (Boolean.getBoolean("webdriver.headless")) { - options.addArguments("--headless=chrome"); + options.addArguments("--headless=new"); } options.addArguments( diff --git a/javascript/node/selenium-webdriver/bidi/browsingContext.js b/javascript/node/selenium-webdriver/bidi/browsingContext.js index eeba70ff7153f..9a32004c14d15 100644 --- a/javascript/node/selenium-webdriver/bidi/browsingContext.js +++ b/javascript/node/selenium-webdriver/bidi/browsingContext.js @@ -528,10 +528,15 @@ class BrowsingContext { throw Error(`Pass in an array of ReferenceValue objects. Received: ${startNodes}`) } + let startNodesSerialized = undefined + if (startNodes !== undefined && Array.isArray(startNodes)) { + startNodesSerialized = [] startNodes.forEach((node) => { if (!(node instanceof ReferenceValue)) { throw Error(`Pass in a ReferenceValue object. Received: ${node}`) + } else { + startNodesSerialized.push(node.asMap()) } }) } @@ -544,7 +549,7 @@ class BrowsingContext { maxNodeCount: maxNodeCount, sandbox: sandbox, serializationOptions: serializationOptions, - startNodes: startNodes, + startNodes: startNodesSerialized, }, } diff --git a/javascript/node/selenium-webdriver/test/bidi/locate_nodes_test.js b/javascript/node/selenium-webdriver/test/bidi/locate_nodes_test.js index 109f2e07ad00e..a41bb344d79e8 100644 --- a/javascript/node/selenium-webdriver/test/bidi/locate_nodes_test.js +++ b/javascript/node/selenium-webdriver/test/bidi/locate_nodes_test.js @@ -19,7 +19,7 @@ const assert = require('node:assert') const { Browser } = require('selenium-webdriver') -const { Pages, suite } = require('../../lib/test') +const { Pages, suite, ignore } = require('../../lib/test') const BrowsingContext = require('selenium-webdriver/bidi/browsingContext') const { Locator } = require('selenium-webdriver/bidi/browsingContext') const { ScriptManager } = require('selenium-webdriver/index') @@ -80,7 +80,7 @@ suite( assert.notEqual(element.sharedId, undefined) }) - xit('can locate node with xpath locator', async function () { + it('can locate node with xpath locator', async function () { const id = await driver.getWindowHandle() const browsingContext = await BrowsingContext(driver, { browsingContextId: id, @@ -97,7 +97,7 @@ suite( assert.notEqual(element.sharedId, undefined) }) - xit('can locate node with inner test locator', async function () { + ignore(env.browsers(Browser.FIREFOX)).it('can locate node with inner test locator', async function () { const id = await driver.getWindowHandle() const browsingContext = await BrowsingContext(driver, { browsingContextId: id, @@ -109,12 +109,9 @@ suite( const element = elements[0] assert.strictEqual(element.type, 'node') assert.notEqual(element.value, undefined) - assert.strictEqual(element.value.localName, 'div') - assert.strictEqual(element.value.attributes.class, 'content') - assert.notEqual(element.sharedId, undefined) }) - xit('can locate node with max node count', async function () { + it('can locate node with max node count', async function () { const id = await driver.getWindowHandle() const browsingContext = await BrowsingContext(driver, { browsingContextId: id, @@ -126,7 +123,7 @@ suite( assert.strictEqual(elements.length, 4) }) - xit('can locate node with given start nodes', async function () { + it('can locate node with given start nodes', async function () { const id = await driver.getWindowHandle() const browsingContext = await BrowsingContext(driver, { browsingContextId: id, @@ -155,14 +152,7 @@ suite( startNodes.push(new ReferenceValue(node.handle, node.sharedId)) }) - const elements = await browsingContext.locateNodes( - Locator.css('input'), - 50, - 'none', - undefined, - undefined, - startNodes, - ) + const elements = await browsingContext.locateNodes(Locator.css('input'), 50, 'none', undefined, startNodes) assert.strictEqual(elements.length, 35) }) @@ -236,5 +226,5 @@ suite( }) }) }, - { browsers: [Browser.FIREFOX] }, + { browsers: [Browser.FIREFOX, Browser.CHROME, Browser.EDGE] }, ) diff --git a/py/selenium/webdriver/remote/webelement.py b/py/selenium/webdriver/remote/webelement.py index 08c772eaad56e..e5a3adad0d7b4 100644 --- a/py/selenium/webdriver/remote/webelement.py +++ b/py/selenium/webdriver/remote/webelement.py @@ -173,6 +173,13 @@ def get_attribute(self, name) -> str | None: # Check if the "active" CSS class is applied to an element. is_active = "active" in target_element.get_attribute("class") """ + + warnings.warn( + "using WebElement.get_attribute() has been deprecated. Please use get_dom_attribute() instead.", + DeprecationWarning, + stacklevel=2, + ) + if getAttribute_js is None: _load_js() attribute_value = self.parent.execute_script( diff --git a/py/test/selenium/webdriver/common/alerts_tests.py b/py/test/selenium/webdriver/common/alerts_tests.py index ea37e0e3d5371..9479df88fadf5 100644 --- a/py/test/selenium/webdriver/common/alerts_tests.py +++ b/py/test/selenium/webdriver/common/alerts_tests.py @@ -294,6 +294,7 @@ def test_alert_should_not_allow_additional_commands_if_dismissed(driver, pages): @pytest.mark.xfail_remote(reason="https://bugzilla.mozilla.org/show_bug.cgi?id=1279211") @pytest.mark.xfail_chrome @pytest.mark.xfail_edge +@pytest.mark.xfail_safari def test_unexpected_alert_present_exception_contains_alert_text(driver, pages): pages.load("alerts.html") driver.find_element(by=By.ID, value="alert").click() diff --git a/py/test/selenium/webdriver/common/api_example_tests.py b/py/test/selenium/webdriver/common/api_example_tests.py index 7b8a4cedee3d8..40b3d2b7a2f01 100644 --- a/py/test/selenium/webdriver/common/api_example_tests.py +++ b/py/test/selenium/webdriver/common/api_example_tests.py @@ -240,6 +240,7 @@ def test_is_element_displayed(driver, pages): @pytest.mark.xfail_chrome +@pytest.mark.xfail_safari def test_move_window_position(driver, pages): pages.load("blank.html") loc = driver.get_window_position() diff --git a/py/test/selenium/webdriver/common/bidi_tests.py b/py/test/selenium/webdriver/common/bidi_tests.py index cfa34a55a6cae..6872bc211f4ba 100644 --- a/py/test/selenium/webdriver/common/bidi_tests.py +++ b/py/test/selenium/webdriver/common/bidi_tests.py @@ -18,7 +18,6 @@ from selenium.webdriver.common.by import By from selenium.webdriver.common.log import Log -from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.ui import WebDriverWait @@ -76,8 +75,6 @@ async def test_collect_log_mutations(driver, pages): WebDriverWait(driver, 10).until( lambda d: d.find_element(By.ID, "revealed").value_of_css_property("display") != "none" ) - WebDriverWait(driver, 5).until(EC.visibility_of(driver.find_element(By.ID, "revealed"))) - assert event["attribute_name"] == "style" assert event["current_value"] == "" assert event["old_value"] == "display:none;" diff --git a/py/test/selenium/webdriver/common/interactions_tests.py b/py/test/selenium/webdriver/common/interactions_tests.py index 8c2ad03fc8d6f..7ffe0e9dc4e0b 100644 --- a/py/test/selenium/webdriver/common/interactions_tests.py +++ b/py/test/selenium/webdriver/common/interactions_tests.py @@ -253,6 +253,7 @@ def test_can_pause(driver, pages): @pytest.mark.xfail_firefox @pytest.mark.xfail_remote +@pytest.mark.xfail_safari def test_can_scroll_to_element(driver, pages): pages.load("scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html") iframe = driver.find_element(By.TAG_NAME, "iframe") @@ -266,6 +267,7 @@ def test_can_scroll_to_element(driver, pages): @pytest.mark.xfail_firefox @pytest.mark.xfail_remote +@pytest.mark.xfail_safari def test_can_scroll_from_element_by_amount(driver, pages): pages.load("scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html") iframe = driver.find_element(By.TAG_NAME, "iframe") @@ -280,6 +282,7 @@ def test_can_scroll_from_element_by_amount(driver, pages): @pytest.mark.xfail_firefox @pytest.mark.xfail_remote +@pytest.mark.xfail_safari def test_can_scroll_from_element_with_offset_by_amount(driver, pages): pages.load("scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html") footer = driver.find_element(By.TAG_NAME, "footer") @@ -314,6 +317,7 @@ def test_can_scroll_from_viewport_by_amount(driver, pages): assert _in_viewport(driver, footer) +@pytest.mark.xfail_safari def test_can_scroll_from_viewport_with_offset_by_amount(driver, pages): pages.load("scrolling_tests/frame_with_nested_scrolling_frame.html") scroll_origin = ScrollOrigin.from_viewport(10, 10) diff --git a/py/test/selenium/webdriver/common/interactions_with_device_tests.py b/py/test/selenium/webdriver/common/interactions_with_device_tests.py index 926b93c641e44..f82f3967a0776 100644 --- a/py/test/selenium/webdriver/common/interactions_with_device_tests.py +++ b/py/test/selenium/webdriver/common/interactions_with_device_tests.py @@ -247,6 +247,7 @@ def test_can_pause_with_pointer(driver, pages): @pytest.mark.xfail_firefox @pytest.mark.xfail_remote +@pytest.mark.xfail_safari def test_can_scroll_to_element_with_wheel(driver, pages): pages.load("scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html") iframe = driver.find_element(By.TAG_NAME, "iframe") @@ -262,6 +263,7 @@ def test_can_scroll_to_element_with_wheel(driver, pages): @pytest.mark.xfail_firefox @pytest.mark.xfail_remote +@pytest.mark.xfail_safari def test_can_scroll_from_element_by_amount_with_wheel(driver, pages): pages.load("scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html") iframe = driver.find_element(By.TAG_NAME, "iframe") @@ -278,6 +280,7 @@ def test_can_scroll_from_element_by_amount_with_wheel(driver, pages): @pytest.mark.xfail_firefox @pytest.mark.xfail_remote +@pytest.mark.xfail_safari def test_can_scroll_from_element_with_offset_by_amount_with_wheel(driver, pages): pages.load("scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html") footer = driver.find_element(By.TAG_NAME, "footer") @@ -320,6 +323,7 @@ def test_can_scroll_from_viewport_by_amount_with_wheel(driver, pages): @pytest.mark.xfail_firefox +@pytest.mark.xfail_safari def test_can_scroll_from_viewport_with_offset_by_amount_with_wheel(driver, pages): pages.load("scrolling_tests/frame_with_nested_scrolling_frame.html") scroll_origin = ScrollOrigin.from_viewport(10, 10) diff --git a/py/test/selenium/webdriver/common/position_and_size_tests.py b/py/test/selenium/webdriver/common/position_and_size_tests.py index a438c0f5e0c88..081c51358a517 100644 --- a/py/test/selenium/webdriver/common/position_and_size_tests.py +++ b/py/test/selenium/webdriver/common/position_and_size_tests.py @@ -53,6 +53,7 @@ def test_should_get_coordinates_of_an_invisible_element(driver, pages): _check_location(element.location, x=0, y=0) +@pytest.mark.xfail_safari def test_should_scroll_page_and_get_coordinates_of_an_element_that_is_out_of_view_port(driver, pages): pages.load("coordinates_tests/page_with_element_out_of_view.html") element = driver.find_element(By.ID, "box") @@ -89,6 +90,7 @@ def test_should_get_coordinates_of_an_element_in_anested_frame(driver, pages): _check_location(element.location, x=10, y=10) +@pytest.mark.xfail_safari def test_should_get_coordinates_of_an_element_with_fixed_position(driver, pages): pages.load("coordinates_tests/page_with_fixed_element.html") element = driver.find_element(By.ID, "fixed") diff --git a/py/test/selenium/webdriver/common/selenium_manager_tests.py b/py/test/selenium/webdriver/common/selenium_manager_tests.py index 8692644cee0c4..67239bf87a67d 100644 --- a/py/test/selenium/webdriver/common/selenium_manager_tests.py +++ b/py/test/selenium/webdriver/common/selenium_manager_tests.py @@ -15,6 +15,7 @@ # specific language governing permissions and limitations # under the License. import json +import platform import sys from pathlib import Path from unittest import mock @@ -59,10 +60,14 @@ def test_uses_windows(monkeypatch): def test_uses_linux(monkeypatch): monkeypatch.setattr(sys, "platform", "linux") - binary = SeleniumManager()._get_binary() - project_root = Path(selenium.__file__).parent.parent - assert binary == project_root.joinpath("selenium/webdriver/common/linux/selenium-manager") + if platform.machine() == "arm64": + with pytest.raises(WebDriverException, match="Unsupported platform/architecture combination: linux/arm64"): + SeleniumManager()._get_binary() + else: + binary = SeleniumManager()._get_binary() + project_root = Path(selenium.__file__).parent.parent + assert binary == project_root.joinpath("selenium/webdriver/common/linux/selenium-manager") def test_uses_mac(monkeypatch): diff --git a/py/test/selenium/webdriver/common/upload_tests.py b/py/test/selenium/webdriver/common/upload_tests.py index f5521abd50fd8..642085790e303 100644 --- a/py/test/selenium/webdriver/common/upload_tests.py +++ b/py/test/selenium/webdriver/common/upload_tests.py @@ -16,11 +16,14 @@ # under the License. import os +import textwrap import pytest from selenium.webdriver.common.by import By from selenium.webdriver.remote.webelement import WebElement +from selenium.webdriver.support import expected_conditions as EC +from selenium.webdriver.support.wait import WebDriverWait @pytest.fixture @@ -28,32 +31,33 @@ def get_local_path(): current_dir = os.path.dirname(os.path.realpath(__file__)) def wrapped(filename): - return os.path.join(current_dir, filename) + full_path = os.path.join(current_dir, filename) + return textwrap.fill(full_path, width=512) return wrapped +@pytest.mark.xfail_safari def test_can_upload_file(driver, pages, get_local_path): pages.load("upload.html") driver.find_element(By.ID, "upload").send_keys(get_local_path("test_file.txt")) driver.find_element(By.ID, "go").click() driver.switch_to.frame(driver.find_element(By.ID, "upload_target")) - body = driver.find_element(By.CSS_SELECTOR, "body").text - assert "test_file.txt" in body + WebDriverWait(driver, 10).until(EC.text_to_be_present_in_element((By.CSS_SELECTOR, "body"), "test_file.txt")) +@pytest.mark.xfail_safari def test_can_upload_two_files(driver, pages, get_local_path): pages.load("upload.html") two_file_paths = get_local_path("test_file.txt") + "\n" + get_local_path("test_file2.txt") driver.find_element(By.ID, "upload").send_keys(two_file_paths) driver.find_element(By.ID, "go").click() driver.switch_to.frame(driver.find_element(By.ID, "upload_target")) - body = driver.find_element(By.CSS_SELECTOR, "body").text - assert "test_file.txt" in body - assert "test_file2.txt" in body + WebDriverWait(driver, 10).until(EC.text_to_be_present_in_element((By.CSS_SELECTOR, "body"), "test_file.txt")) + WebDriverWait(driver, 10).until(EC.text_to_be_present_in_element((By.CSS_SELECTOR, "body"), "test_file2.txt")) @pytest.mark.xfail_firefox diff --git a/py/test/selenium/webdriver/common/w3c_interaction_tests.py b/py/test/selenium/webdriver/common/w3c_interaction_tests.py index d0a00ac26a2d4..5376265ede3bb 100644 --- a/py/test/selenium/webdriver/common/w3c_interaction_tests.py +++ b/py/test/selenium/webdriver/common/w3c_interaction_tests.py @@ -176,6 +176,7 @@ def test_dragging_element_with_mouse_fires_events(driver, pages): @pytest.mark.xfail_firefox @pytest.mark.xfail_remote +@pytest.mark.xfail_safari def test_pen_pointer_properties(driver, pages): pages.load("pointerActionsPage.html") @@ -223,6 +224,7 @@ def test_pen_pointer_properties(driver, pages): @pytest.mark.xfail_firefox @pytest.mark.xfail_remote +@pytest.mark.xfail_safari def test_touch_pointer_properties(driver, pages): pages.load("pointerActionsPage.html") pointerArea = driver.find_element(By.CSS_SELECTOR, "#pointerArea") diff --git a/py/test/selenium/webdriver/common/webdriverwait_tests.py b/py/test/selenium/webdriver/common/webdriverwait_tests.py index 14019d185e8b0..f332933e4241c 100644 --- a/py/test/selenium/webdriver/common/webdriverwait_tests.py +++ b/py/test/selenium/webdriver/common/webdriverwait_tests.py @@ -35,6 +35,7 @@ def throw_sere(driver): @pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") @pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") +@pytest.mark.xfail_safari def test_should_fail_with_invalid_selector_exception(driver, pages): pages.load("dynamic.html") with pytest.raises(InvalidSelectorException): diff --git a/py/test/selenium/webdriver/common/webserver.py b/py/test/selenium/webdriver/common/webserver.py index 5a227c1722f6c..bd108dade8278 100644 --- a/py/test/selenium/webdriver/common/webserver.py +++ b/py/test/selenium/webdriver/common/webserver.py @@ -59,27 +59,43 @@ def updir(): class HtmlOnlyHandler(BaseHTTPRequestHandler): - """Http handler.""" + """Handler for HTML responses and JSON files.""" + + def _serve_page(self, page_number): + """Serve a dynamically generated HTML page.""" + html = f"""Page{page_number} + Page number {page_number} +

top

+ """ + return html.encode("utf-8") + + def _serve_file(self, file_path): + """Serve a file from the HTML root directory.""" + with open(file_path, encoding="latin-1") as f: + return f.read().encode("utf-8") + + def _send_response(self, content_type="text/html"): + """Send a response.""" + self.send_response(200) + self.send_header("Content-type", content_type) + self.end_headers() def do_GET(self): """GET method handler.""" try: path = self.path[1:].split("?")[0] - if path[:5] == "page/": - html = """Page{page_number} - Page number {page_number} -

top - """.format( - page_number=path[5:] - ) - html = html.encode("utf-8") + file_path = os.path.join(HTML_ROOT, path) + if path.startswith("page/"): + html = self._serve_page(path[5:]) + self._send_response("text/html") + self.wfile.write(html) + elif os.path.isfile(file_path): + content_type = "application/json" if file_path.endswith(".json") else "text/html" + content = self._serve_file(file_path) + self._send_response(content_type) + self.wfile.write(content) else: - with open(os.path.join(HTML_ROOT, path), encoding="latin-1") as f: - html = f.read().encode("utf-8") - self.send_response(200) - self.send_header("Content-type", "text/html") - self.end_headers() - self.wfile.write(html) + self.send_error(404, f"File Not Found: {path}") except OSError: self.send_error(404, f"File Not Found: {path}") @@ -87,34 +103,12 @@ def do_POST(self): """POST method handler.""" try: remaining_bytes = int(self.headers["content-length"]) - contents = "" - line = self.rfile.readline() - contents += line.decode("utf-8") - remaining_bytes -= len(line) - line = self.rfile.readline() - contents += line.decode("utf-8") - remaining_bytes -= len(line) - fn = re.findall(r'Content-Disposition.*name="upload"; filename="(.*)"', line.decode("utf-8")) - if not fn: - self.send_error(500, f"File not found. {contents}") + contents = self.rfile.read(remaining_bytes).decode("utf-8") + fn_match = re.search(r'Content-Disposition.*name="upload"; filename="(.*)"', contents) + if not fn_match: + self.send_error(500, f"File not found in content. {contents}") return - line = self.rfile.readline() - remaining_bytes -= len(line) - contents += line.decode("utf-8") - line = self.rfile.readline() - remaining_bytes -= len(line) - contents += line.decode("utf-8") - preline = self.rfile.readline() - remaining_bytes -= len(preline) - while remaining_bytes > 0: - line = self.rfile.readline() - remaining_bytes -= len(line) - contents += line.decode("utf-8") - - self.send_response(200) - self.send_header("Content-type", "text/html") - self.end_headers() - + self._send_response("text/html") self.wfile.write( f""" {contents} diff --git a/py/test/selenium/webdriver/common/window_switching_tests.py b/py/test/selenium/webdriver/common/window_switching_tests.py index 1e2359cd52b36..2883ab2c55f69 100644 --- a/py/test/selenium/webdriver/common/window_switching_tests.py +++ b/py/test/selenium/webdriver/common/window_switching_tests.py @@ -130,6 +130,7 @@ def test_should_throw_no_such_window_exception_on_any_element_operation_if_awind element.text +@pytest.mark.xfail_safari def test_clicking_on_abutton_that_closes_an_open_window_does_not_cause_the_browser_to_hang(driver, pages): pages.load("xhtmlTest.html") current = driver.current_window_handle diff --git a/py/test/selenium/webdriver/safari/__init__.py b/py/test/selenium/webdriver/safari/__init__.py new file mode 100644 index 0000000000000..a5b1e6f85a09e --- /dev/null +++ b/py/test/selenium/webdriver/safari/__init__.py @@ -0,0 +1,16 @@ +# 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. diff --git a/py/test/selenium/webdriver/safari/safari_service_tests.py b/py/test/selenium/webdriver/safari/safari_service_tests.py new file mode 100644 index 0000000000000..494cbe6be6143 --- /dev/null +++ b/py/test/selenium/webdriver/safari/safari_service_tests.py @@ -0,0 +1,59 @@ +# 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. + +import os + +import pytest + +from selenium.webdriver.safari.service import Service + + +@pytest.fixture +def service(): + return Service() + + +@pytest.mark.usefixtures("service") +class TestSafariDriverService: + service_path = "/path/to/safaridriver" + + @pytest.fixture(autouse=True) + def setup_and_teardown(self): + os.environ["SE_SAFARIDRIVER"] = self.service_path + yield + os.environ.pop("SE_SAFARIDRIVER", None) + + def test_uses_path_from_env_variable(self, service): + assert "safaridriver" in service.path + + def test_updates_path_after_setting_env_variable(self, service): + new_path = "/foo/bar" + os.environ["SE_SAFARIDRIVER"] = new_path + service.executable_path = self.service_path # Simulating the update + + assert "safaridriver" in service.executable_path + + +def test_enable_logging(): + enable_logging = True + service = Service(enable_logging=enable_logging) + assert "--diagnose" in service.service_args + + +def test_service_url(): + service = Service(port=1313) + assert service.service_url == "http://localhost:1313" diff --git a/rust/Cargo.Bazel.lock b/rust/Cargo.Bazel.lock index 187142b30214a..aa489691c16ae 100644 --- a/rust/Cargo.Bazel.lock +++ b/rust/Cargo.Bazel.lock @@ -1,5 +1,5 @@ { - "checksum": "1b307b787c95f27b60af367955d57dfd4b21ff233bf6e156a87950f4c610430e", + "checksum": "94895b25f9b1d0a76ec78d588887353422bc623faf9ef986467b199d2a966765", "crates": { "addr2line 0.21.0": { "name": "addr2line", @@ -572,14 +572,14 @@ ], "license_file": "LICENSE-APACHE" }, - "anyhow 1.0.89": { + "anyhow 1.0.91": { "name": "anyhow", - "version": "1.0.89", + "version": "1.0.91", "package_url": "https://github.com/dtolnay/anyhow", "repository": { "Http": { - "url": "https://static.crates.io/crates/anyhow/1.0.89/download", - "sha256": "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" + "url": "https://static.crates.io/crates/anyhow/1.0.91/download", + "sha256": "c042108f3ed77fd83760a5fd79b53be043192bb3b9dba91d8c574c0ada7850c8" } }, "targets": [ @@ -623,7 +623,7 @@ "deps": { "common": [ { - "id": "anyhow 1.0.89", + "id": "anyhow 1.0.91", "target": "build_script_build" }, { @@ -634,7 +634,7 @@ "selects": {} }, "edition": "2018", - "version": "1.0.89" + "version": "1.0.91" }, "build_script_attrs": { "compile_data_glob": [ @@ -2034,16 +2034,79 @@ "id": "jobserver 0.1.31", "target": "jobserver" }, - { - "id": "libc 0.2.160", - "target": "libc" - }, { "id": "shlex 1.3.0", "target": "shlex" } ], - "selects": {} + "selects": { + "aarch64-apple-darwin": [ + { + "id": "libc 0.2.160", + "target": "libc" + } + ], + "aarch64-unknown-linux-gnu": [ + { + "id": "libc 0.2.160", + "target": "libc" + } + ], + "aarch64-unknown-nixos-gnu": [ + { + "id": "libc 0.2.160", + "target": "libc" + } + ], + "arm-unknown-linux-gnueabi": [ + { + "id": "libc 0.2.160", + "target": "libc" + } + ], + "i686-unknown-linux-gnu": [ + { + "id": "libc 0.2.160", + "target": "libc" + } + ], + "powerpc-unknown-linux-gnu": [ + { + "id": "libc 0.2.160", + "target": "libc" + } + ], + "s390x-unknown-linux-gnu": [ + { + "id": "libc 0.2.160", + "target": "libc" + } + ], + "x86_64-apple-darwin": [ + { + "id": "libc 0.2.160", + "target": "libc" + } + ], + "x86_64-unknown-freebsd": [ + { + "id": "libc 0.2.160", + "target": "libc" + } + ], + "x86_64-unknown-linux-gnu": [ + { + "id": "libc 0.2.160", + "target": "libc" + } + ], + "x86_64-unknown-nixos-gnu": [ + { + "id": "libc 0.2.160", + "target": "libc" + } + ] + } }, "edition": "2018", "version": "1.1.30" @@ -4058,7 +4121,7 @@ "target": "log" }, { - "id": "regex 1.11.0", + "id": "regex 1.11.1", "target": "regex" } ], @@ -10411,14 +10474,14 @@ ], "license_file": "LICENSE" }, - "regex 1.11.0": { + "regex 1.11.1": { "name": "regex", - "version": "1.11.0", + "version": "1.11.1", "package_url": "https://github.com/rust-lang/regex", "repository": { "Http": { - "url": "https://static.crates.io/crates/regex/1.11.0/download", - "sha256": "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" + "url": "https://static.crates.io/crates/regex/1.11.1/download", + "sha256": "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" } }, "targets": [ @@ -10484,7 +10547,7 @@ "selects": {} }, "edition": "2021", - "version": "1.11.0" + "version": "1.11.1" }, "license": "MIT OR Apache-2.0", "license_ids": [ @@ -12808,7 +12871,7 @@ "target": "quote" }, { - "id": "regex 1.11.0", + "id": "regex 1.11.1", "target": "regex" }, { @@ -14073,7 +14136,7 @@ "deps": { "common": [ { - "id": "anyhow 1.0.89", + "id": "anyhow 1.0.91", "target": "anyhow" }, { @@ -14117,7 +14180,7 @@ "target": "log" }, { - "id": "regex 1.11.0", + "id": "regex 1.11.1", "target": "regex" }, { @@ -22673,7 +22736,7 @@ ] }, "direct_deps": [ - "anyhow 1.0.89", + "anyhow 1.0.91", "apple-flat-package 0.18.0", "bzip2 0.4.4", "clap 4.5.20", @@ -22684,7 +22747,7 @@ "flate2 1.0.34", "infer 0.16.0", "log 0.4.22", - "regex 1.11.0", + "regex 1.11.1", "reqwest 0.12.8", "serde 1.0.210", "serde_json 1.0.128",