Skip to content

Commit f7517aa

Browse files
authored
Merge branch 'trunk' into fix-SeleniumManager
2 parents 6c2a3aa + d55eff3 commit f7517aa

File tree

24 files changed

+1023
-21
lines changed

24 files changed

+1023
-21
lines changed

.github/workflows/ci-python.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,4 +113,6 @@ jobs:
113113
browser: ${{ matrix.browser }}
114114
os: ${{ matrix.os }}
115115
cache-key: py-browser-${{ matrix.browser }}
116-
run: bazel test --flaky_test_attempts 3 //py:test-${{ matrix.browser }}
116+
run: |
117+
bazel test --local_test_jobs 1 --flaky_test_attempts 3 //py:common-${{ matrix.browser }}-bidi
118+
bazel test --local_test_jobs 1 --flaky_test_attempts 3 //py:test-${{ matrix.browser }}

.skipped-tests

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
-//py:test-chrome-test/selenium/webdriver/chrome/chrome_launcher_tests.py
3232
-//py:test-chrome-test/selenium/webdriver/chrome/chrome_service_tests.py
3333
-//py:test-chrome-test/selenium/webdriver/chrome/proxy_tests.py
34+
-//py:test-edge-test/selenium/webdriver/edge/edge_launcher_tests.py
35+
-//py:test-edge-test/selenium/webdriver/edge/edge_service_tests.py
3436
-//rb/spec/integration/selenium/webdriver/chrome:service-chrome
3537
-//rb/spec/integration/selenium/webdriver/chrome:service-chrome-bidi
3638
-//rb/spec/integration/selenium/webdriver/chrome:service-chrome-remote

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,18 @@ Run unit tests with:
317317
bazel test //py:unit
318318
```
319319

320+
To run common tests with a specific browser:
321+
322+
```sh
323+
bazel test //py:common-<browsername>
324+
```
325+
326+
To run common tests with a specific browser (include BiDi tests):
327+
328+
```sh
329+
bazel test //py:common-<browsername>-bidi
330+
```
331+
320332
To run tests with a specific browser:
321333

322334
```sh

dotnet/src/webdriver/RelativeBy.cs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,28 @@ public override ReadOnlyCollection<IWebElement> FindElements(ISearchContext cont
108108
filterParameters["filters"] = this.filters;
109109
parameters["relative"] = filterParameters;
110110
object rawElements = js.ExecuteScript(wrappedAtom, parameters);
111-
ReadOnlyCollection<IWebElement> elements = rawElements as ReadOnlyCollection<IWebElement>;
112-
return elements;
111+
112+
if (rawElements is ReadOnlyCollection<IWebElement> elements)
113+
{
114+
return elements;
115+
}
116+
117+
// De-serializer quirk - if the response is empty then the de-serializer will not know we're getting back elements
118+
// We will have a ReadOnlyCollection<object>
119+
120+
if (rawElements is ReadOnlyCollection<object> elementsObj)
121+
{
122+
if (elementsObj.Count == 0)
123+
{
124+
#if NET8_0_OR_GREATER
125+
return ReadOnlyCollection<IWebElement>.Empty;
126+
#else
127+
return new List<IWebElement>().AsReadOnly();
128+
#endif
129+
}
130+
}
131+
132+
throw new WebDriverException($"Could not de-serialize element list response{Environment.NewLine}{rawElements}");
113133
}
114134

115135
/// <summary>
@@ -288,7 +308,7 @@ private RelativeBy Near(object locator, int atMostDistanceInPixels)
288308

289309
Dictionary<string, object> filter = new Dictionary<string, object>();
290310
filter["kind"] = "near";
291-
filter["args"] = new List<object>() { GetSerializableObject(locator), "distance", atMostDistanceInPixels };
311+
filter["args"] = new List<object>() { GetSerializableObject(locator), atMostDistanceInPixels };
292312
this.filters.Add(filter);
293313

294314
return new RelativeBy(this.root, this.filters);

dotnet/test/common/RelativeLocatorTest.cs

Lines changed: 192 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
using OpenQA.Selenium.Environment;
2222
using System.Collections.Generic;
2323
using System.Collections.ObjectModel;
24+
using System.Linq;
2425

2526
namespace OpenQA.Selenium
2627
{
@@ -29,21 +30,42 @@ namespace OpenQA.Selenium
2930
public class RelativeLocatorTest : DriverTestFixture
3031
{
3132
[Test]
32-
public void ShouldBeAbleToFindElementsAboveAnother()
33+
public void ShouldBeAbleToFindElementsAboveAnotherWithTagName()
3334
{
3435
driver.Url = (EnvironmentManager.Instance.UrlBuilder.WhereIs("relative_locators.html"));
3536

3637
IWebElement lowest = driver.FindElement(By.Id("below"));
3738

3839
ReadOnlyCollection<IWebElement> elements = driver.FindElements(RelativeBy.WithLocator(By.TagName("p")).Above(lowest));
39-
List<string> elementIds = new List<string>();
40-
foreach (IWebElement element in elements)
41-
{
42-
string id = element.GetAttribute("id");
43-
elementIds.Add(id);
44-
}
4540

46-
Assert.That(elementIds, Is.EquivalentTo(new List<string>() { "above", "mid" }));
41+
var values = elements.Select(element => element.GetDomAttribute("id"));
42+
Assert.That(values, Is.EquivalentTo(new List<string>() { "above", "mid" }));
43+
}
44+
45+
[Test]
46+
public void ShouldBeAbleToFindElementsAboveAnotherWithXpath()
47+
{
48+
driver.Url = (EnvironmentManager.Instance.UrlBuilder.WhereIs("relative_locators.html"));
49+
50+
IWebElement lowest = driver.FindElement(By.Id("seventh"));
51+
52+
var elements = driver.FindElements(RelativeBy.WithLocator(By.XPath("//td[1]")).Above(lowest));
53+
54+
var values = elements.Select(element => element.GetDomAttribute("id"));
55+
Assert.That(values, Is.EquivalentTo(new List<string> { "fourth", "first" }));
56+
}
57+
58+
[Test]
59+
public void ShouldBeAbleToFindElementsAboveAnotherWithCssSelector()
60+
{
61+
driver.Url = (EnvironmentManager.Instance.UrlBuilder.WhereIs("relative_locators.html"));
62+
63+
IWebElement lowest = driver.FindElement(By.Id("below"));
64+
65+
var elements = driver.FindElements(RelativeBy.WithLocator(By.CssSelector("p")).Above(lowest));
66+
67+
var values = elements.Select(element => element.GetDomAttribute("id"));
68+
Assert.That(values, Is.EquivalentTo(new List<string> { "mid", "above" }));
4769
}
4870

4971
[Test]
@@ -53,14 +75,170 @@ public void ShouldBeAbleToCombineFilters()
5375

5476
ReadOnlyCollection<IWebElement> seen = driver.FindElements(RelativeBy.WithLocator(By.TagName("td")).Above(By.Id("center")).RightOf(By.Id("second")));
5577

56-
List<string> elementIds = new List<string>();
57-
foreach (IWebElement element in seen)
78+
var elementIds = seen.Select(element => element.GetDomAttribute("id"));
79+
Assert.That(elementIds, Is.EquivalentTo(new List<string>() { "third" }));
80+
}
81+
82+
83+
[Test]
84+
public void ShouldBeAbleToCombineFiltersWithXpath()
85+
{
86+
driver.Url = (EnvironmentManager.Instance.UrlBuilder.WhereIs("relative_locators.html"));
87+
88+
ReadOnlyCollection<IWebElement> seen = driver.FindElements(RelativeBy.WithLocator(By.XPath("//td[1]")).Below(By.Id("second")).Above(By.Id("seventh")));
89+
90+
var values = seen.Select(element => element.GetDomAttribute("id"));
91+
Assert.That(values, Is.EquivalentTo(new List<string> { "fourth" }));
92+
}
93+
94+
[Test]
95+
public void ShouldBeAbleToCombineFiltersWithCssSelector()
96+
{
97+
driver.Url = (EnvironmentManager.Instance.UrlBuilder.WhereIs("relative_locators.html"));
98+
99+
ReadOnlyCollection<IWebElement> seen = driver.FindElements(
100+
RelativeBy.WithLocator(By.CssSelector("td")).Above(By.Id("center")).RightOf(By.Id("second")));
101+
102+
var values = seen.Select(element => element.GetDomAttribute("id"));
103+
Assert.That(values, Is.EquivalentTo(new List<string> { "third" }));
104+
}
105+
106+
[Test]
107+
public void ExerciseNearLocatorWithTagName()
108+
{
109+
driver.Url = (EnvironmentManager.Instance.UrlBuilder.WhereIs("relative_locators.html"));
110+
111+
ReadOnlyCollection<IWebElement> seen = driver.FindElements(RelativeBy.WithLocator(By.TagName("td")).Near(By.Id("center")));
112+
113+
// Elements are sorted by proximity and then DOM insertion order.
114+
// Proximity is determined using distance from center points, so
115+
// we expect the order to be:
116+
// 1. Directly above (short vertical distance, first in DOM)
117+
// 2. Directly below (short vertical distance, later in DOM)
118+
// 3. Directly left (slight longer distance horizontally, first in DOM)
119+
// 4. Directly right (slight longer distance horizontally, later in DOM)
120+
// 5-8. Diagonally close (pythagoras sorting, with top row first
121+
// because of DOM insertion order)
122+
var values = seen.Select(element => element.GetDomAttribute("id"));
123+
Assert.That(values, Is.EquivalentTo(new List<string> { "second", "eighth", "fourth", "sixth", "first", "third", "seventh", "ninth" }));
124+
}
125+
126+
[Test]
127+
public void ExerciseNearLocatorWithXpath()
128+
{
129+
driver.Url = (EnvironmentManager.Instance.UrlBuilder.WhereIs("relative_locators.html"));
130+
131+
ReadOnlyCollection<IWebElement> seen = driver.FindElements(RelativeBy.WithLocator(By.XPath("//td")).Near(By.Id("center")));
132+
133+
// Elements are sorted by proximity and then DOM insertion order.
134+
// Proximity is determined using distance from center points, so
135+
// we expect the order to be:
136+
// 1. Directly above (short vertical distance, first in DOM)
137+
// 2. Directly below (short vertical distance, later in DOM)
138+
// 3. Directly left (slight longer distance horizontally, first in DOM)
139+
// 4. Directly right (slight longer distance horizontally, later in DOM)
140+
// 5-8. Diagonally close (pythagoras sorting, with top row first
141+
// because of DOM insertion order)
142+
var values = seen.Select(element => element.GetDomAttribute("id"));
143+
Assert.That(values, Is.EquivalentTo(new List<string> { "second", "eighth", "fourth", "sixth", "first", "third", "seventh", "ninth" }));
144+
}
145+
146+
[Test]
147+
public void ExerciseNearLocatorWithCssSelector()
148+
{
149+
driver.Url = (EnvironmentManager.Instance.UrlBuilder.WhereIs("relative_locators.html"));
150+
151+
ReadOnlyCollection<IWebElement> seen = driver.FindElements(RelativeBy.WithLocator(By.CssSelector("td")).Near(By.Id("center")));
152+
153+
// Elements are sorted by proximity and then DOM insertion order.
154+
// Proximity is determined using distance from center points, so
155+
// we expect the order to be:
156+
// 1. Directly above (short vertical distance, first in DOM)
157+
// 2. Directly below (short vertical distance, later in DOM)
158+
// 3. Directly left (slight longer distance horizontally, first in DOM)
159+
// 4. Directly right (slight longer distance horizontally, later in DOM)
160+
// 5-8. Diagonally close (pythagoras sorting, with top row first
161+
// because of DOM insertion order)
162+
var values = seen.Select(element => element.GetDomAttribute("id"));
163+
Assert.That(values, Is.EquivalentTo(new List<string> { "second", "eighth", "fourth", "sixth", "first", "third", "seventh", "ninth" }));
164+
}
165+
166+
[Test]
167+
public void EnsureNoRepeatedElements()
168+
{
169+
driver.Url = EnvironmentManager.Instance.UrlBuilder.CreateInlinePage(new InlinePage()
170+
.WithTitle("Repeated Elements")
171+
.WithStyles(
172+
"""
173+
.c {
174+
position: absolute;
175+
border: 1px solid black;
176+
height: 50px;
177+
width: 50px;
178+
}
179+
"""
180+
)
181+
.WithBody(
182+
"""
183+
<span style="position: relative;">
184+
<div id= "a" class="c" style="left:25;top:0;">El-A</div>
185+
<div id= "b" class="c" style="left:78;top:30;">El-B</div>
186+
<div id= "c" class="c" style="left:131;top:60;">El-C</div>
187+
<div id= "d" class="c" style="left:0;top:53;">El-D</div>
188+
<div id= "e" class="c" style="left:53;top:83;">El-E</div>
189+
<div id= "f" class="c" style="left:106;top:113;">El-F</div>
190+
</span>
191+
"""
192+
));
193+
194+
IWebElement @base = driver.FindElement(By.Id("e"));
195+
ReadOnlyCollection<IWebElement> cells = driver.FindElements(RelativeBy.WithLocator(By.TagName("div")).Above(@base));
196+
197+
IWebElement a = driver.FindElement(By.Id("a"));
198+
IWebElement b = driver.FindElement(By.Id("b"));
199+
200+
var values = cells.Select(element => element.GetDomAttribute("id"));
201+
Assert.That(values, Is.EqualTo(new List<string> { b.GetDomAttribute("id"), a.GetDomAttribute("id") }));
202+
}
203+
204+
[Test]
205+
public void NearLocatorShouldFindNearElements()
206+
{
207+
driver.Url = (EnvironmentManager.Instance.UrlBuilder.WhereIs("relative_locators.html"));
208+
209+
var rect1 = driver.FindElement(By.Id("rect1"));
210+
211+
var rect2 = driver.FindElement(RelativeBy.WithLocator(By.Id("rect2")).Near(rect1));
212+
213+
Assert.That(rect2.GetDomAttribute("id"), Is.EqualTo("rect2"));
214+
}
215+
216+
[Test]
217+
public void NearLocatorShouldNotFindFarElements()
218+
{
219+
driver.Url = (EnvironmentManager.Instance.UrlBuilder.WhereIs("relative_locators.html"));
220+
221+
var rect3 = driver.FindElement(By.Id("rect3"));
222+
223+
Assert.That(() =>
58224
{
59-
string id = element.GetAttribute("id");
60-
elementIds.Add(id);
61-
}
225+
var rect2 = driver.FindElement(RelativeBy.WithLocator(By.Id("rect4")).Near(rect3));
62226

63-
Assert.That(elementIds, Is.EquivalentTo(new List<string>() { "third" }));
227+
}, Throws.TypeOf<NoSuchElementException>().With.Message.EqualTo("Unable to find element; For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#no-such-element-exception"));
228+
}
229+
230+
//------------------------------------------------------------------
231+
// Tests below here are not included in the Java test suite
232+
//------------------------------------------------------------------
233+
234+
[Test]
235+
public void ShouldReturnEmptyListWhenNoElementsFound()
236+
{
237+
driver.Url = (EnvironmentManager.Instance.UrlBuilder.WhereIs("relative_locators.html"));
238+
239+
var elements = driver.FindElements(RelativeBy.WithLocator(By.TagName("does-not-exist")));
240+
241+
Assert.That(elements, Is.Empty);
64242
}
65243
}
66244
}

java/src/org/openqa/selenium/devtools/CdpEndpointFinder.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ public static Optional<URI> getReportedUri(Capabilities caps) {
9191
break;
9292
case "firefox":
9393
key = "moz:debuggerAddress";
94+
LOG.warning(
95+
"CDP support for Firefox is deprecated and will be removed in future versions. "
96+
+ "Please switch to WebDriver BiDi.");
9497
break;
9598
default:
9699
return Optional.empty();

java/src/org/openqa/selenium/firefox/FirefoxDriver.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,13 @@ private FirefoxDriver(
164164

165165
Optional<URI> reportedUri =
166166
CdpEndpointFinder.getReportedUri("moz:debuggerAddress", capabilities);
167+
168+
if (reportedUri.isPresent()) {
169+
LOG.warning(
170+
"CDP support for Firefox is deprecated and will be removed in future versions. "
171+
+ "Please switch to WebDriver BiDi.");
172+
}
173+
167174
Optional<HttpClient> client =
168175
reportedUri.map(uri -> CdpEndpointFinder.getHttpClient(factory, uri));
169176
Optional<URI> cdpUri;

javascript/node/selenium-webdriver/lib/webdriver.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1230,6 +1230,12 @@ class WebDriver {
12301230

12311231
const caps = await this.getCapabilities()
12321232

1233+
if (caps['map_'].get('browserName') === 'firefox') {
1234+
console.warn(
1235+
'CDP support for Firefox is deprecated and will be removed in future versions. Please switch to WebDriver BiDi.',
1236+
)
1237+
}
1238+
12331239
if (process.env.SELENIUM_REMOTE_URL) {
12341240
const host = new URL(process.env.SELENIUM_REMOTE_URL).host
12351241
const sessionId = await this.getSession().then((session) => session.getId())

py/BUILD.bazel

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -595,9 +595,7 @@ py_test_suite(
595595
name = "test-safari",
596596
size = "large",
597597
srcs = glob([
598-
"test/selenium/webdriver/common/**/*.py",
599598
"test/selenium/webdriver/safari/**/*.py",
600-
"test/selenium/webdriver/support/**/*.py",
601599
]),
602600
args = [
603601
"--instafail",

0 commit comments

Comments
 (0)