Skip to content

Commit d9615cb

Browse files
authored
Merge branch 'trunk' into release-preparation-4.28.0
2 parents 9b0dbab + 6141259 commit d9615cb

File tree

19 files changed

+624
-71
lines changed

19 files changed

+624
-71
lines changed

.github/workflows/update-documentation.yml

-4
Original file line numberDiff line numberDiff line change
@@ -140,10 +140,6 @@ jobs:
140140
run: |
141141
git config --local user.email "[email protected]"
142142
git config --local user.name "Selenium CI Bot"
143-
- name: Install specific version of DocFX tool
144-
# Pinning to 2.75.3 to avoid breaking changes in newer versions
145-
# See https://github.com/dotnet/docfx/issues/9855
146-
run: dotnet tool install --global --version 2.75.3 docfx
147143
- name: Update Documentation
148144
if: needs.determine-language.outputs.language == 'all' || needs.determine-language.outputs.language == 'dotnet'
149145
run: ./go dotnet:docs

MODULE.bazel

+1-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ register_toolchains("@dotnet_toolchains//:all")
9393
oci = use_extension("@rules_oci//oci:extensions.bzl", "oci")
9494
oci.pull(
9595
name = "java_image_base",
96-
digest = "sha256:161a1d97d592b3f1919801578c3a47c8e932071168a96267698f4b669c24c76d",
96+
digest = "sha256:1df9f3e6a2de0544dd04f1840aa811d334045c9126f9e93d8da45448061ad51e",
9797
image = "gcr.io/distroless/java17",
9898
)
9999
oci.pull(

Rakefile

+2-3
Original file line numberDiff line numberDiff line change
@@ -777,10 +777,9 @@ namespace :dotnet do
777777
task :docs, [:skip_update] do |_task, arguments|
778778
FileUtils.rm_rf('build/docs/api/dotnet/')
779779
begin
780-
# Pinning to 2.75.3 to avoid breaking changes in newer versions
781-
# See https://github.com/dotnet/docfx/issues/9855
780+
# Pinning to 2.78.2 to avoid breaking changes in newer versions
782781
sh 'dotnet tool uninstall --global docfx || true'
783-
sh 'dotnet tool install --global --version 2.75.3 docfx'
782+
sh 'dotnet tool install --global --version 2.78.2 docfx'
784783
# sh 'dotnet tool update -g docfx'
785784
rescue StandardError
786785
puts 'Please ensure that .NET SDK is installed.'

dotnet/docs/docfx.json

+2-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
],
1212
"dest": "webdriver",
1313
"namespaceLayout": "nested",
14-
"outputFormat": "apiPage"
14+
//"outputFormat": "apiPage" // "apiPage" generation with errors
1515
},
1616
{
1717
"src": [
@@ -24,9 +24,8 @@
2424
],
2525
"dest": "support",
2626
"namespaceLayout": "nested",
27-
"outputFormat": "apiPage"
27+
//"outputFormat": "apiPage" // "apiPage" generation with errors
2828
}
29-
3029
],
3130
"build": {
3231
"content": [

java/src/org/openqa/selenium/PageLoadStrategy.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717

1818
package org.openqa.selenium;
1919

20+
import org.jspecify.annotations.NullMarked;
21+
import org.jspecify.annotations.Nullable;
22+
23+
@NullMarked
2024
public enum PageLoadStrategy {
2125
NONE("none"),
2226
EAGER("eager"),
@@ -33,7 +37,7 @@ public String toString() {
3337
return String.valueOf(text);
3438
}
3539

36-
public static PageLoadStrategy fromString(String text) {
40+
public static @Nullable PageLoadStrategy fromString(@Nullable String text) {
3741
if (text != null) {
3842
for (PageLoadStrategy b : PageLoadStrategy.values()) {
3943
if (text.equalsIgnoreCase(b.text)) {

java/src/org/openqa/selenium/UnexpectedAlertBehaviour.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717

1818
package org.openqa.selenium;
1919

20+
import org.jspecify.annotations.NullMarked;
21+
import org.jspecify.annotations.Nullable;
22+
23+
@NullMarked
2024
public enum UnexpectedAlertBehaviour {
2125
ACCEPT("accept"),
2226
DISMISS("dismiss"),
@@ -35,7 +39,7 @@ public String toString() {
3539
return String.valueOf(text);
3640
}
3741

38-
public static UnexpectedAlertBehaviour fromString(String text) {
42+
public static @Nullable UnexpectedAlertBehaviour fromString(@Nullable String text) {
3943
if (text != null) {
4044
for (UnexpectedAlertBehaviour b : UnexpectedAlertBehaviour.values()) {
4145
if (text.equalsIgnoreCase(b.text)) {

java/src/org/openqa/selenium/WindowType.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@
1717

1818
package org.openqa.selenium;
1919

20+
import org.jspecify.annotations.NullMarked;
21+
import org.jspecify.annotations.Nullable;
22+
2023
/** Represents the type of new browser window that may be created. */
24+
@NullMarked
2125
public enum WindowType {
2226
WINDOW("window"),
2327
TAB("tab"),
@@ -34,7 +38,7 @@ public String toString() {
3438
return String.valueOf(text);
3539
}
3640

37-
public static WindowType fromString(String text) {
41+
public static @Nullable WindowType fromString(@Nullable String text) {
3842
if (text != null) {
3943
for (WindowType b : WindowType.values()) {
4044
if (text.equalsIgnoreCase(b.text)) {

java/src/org/openqa/selenium/interactions/Actions.java

+9-6
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
import java.util.Objects;
3131
import java.util.Set;
3232
import java.util.function.IntConsumer;
33+
import org.jspecify.annotations.NullMarked;
34+
import org.jspecify.annotations.Nullable;
3335
import org.openqa.selenium.WebDriver;
3436
import org.openqa.selenium.WebElement;
3537
import org.openqa.selenium.interactions.PointerInput.Origin;
@@ -44,16 +46,17 @@
4446
*
4547
* <p>Call {@link #perform()} at the end of the method chain to actually perform the actions.
4648
*/
49+
@NullMarked
4750
public class Actions {
4851

4952
private final WebDriver driver;
5053

5154
// W3C
5255
private final Map<InputSource, Sequence> sequences = new HashMap<>();
5356

54-
private PointerInput activePointer;
55-
private KeyInput activeKeyboard;
56-
private WheelInput activeWheel;
57+
private @Nullable PointerInput activePointer;
58+
private @Nullable KeyInput activeKeyboard;
59+
private @Nullable WheelInput activeWheel;
5760
private Duration actionDuration;
5861

5962
public Actions(WebDriver driver) {
@@ -537,21 +540,21 @@ public KeyInput getActiveKeyboard() {
537540
if (this.activeKeyboard == null) {
538541
setActiveKeyboard("default keyboard");
539542
}
540-
return this.activeKeyboard;
543+
return Require.nonNull("ActiveKeyboard", this.activeKeyboard);
541544
}
542545

543546
public PointerInput getActivePointer() {
544547
if (this.activePointer == null) {
545548
setActivePointer(PointerInput.Kind.MOUSE, "default mouse");
546549
}
547-
return this.activePointer;
550+
return Require.nonNull("ActivePointer", this.activePointer);
548551
}
549552

550553
public WheelInput getActiveWheel() {
551554
if (this.activeWheel == null) {
552555
setActiveWheel("default wheel");
553556
}
554-
return this.activeWheel;
557+
return Require.nonNull("ActiveWheel", this.activeWheel);
555558
}
556559

557560
public Duration getActionDuration() {

java/src/org/openqa/selenium/interactions/Pause.java

+2
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@
2222
import java.time.Duration;
2323
import java.util.HashMap;
2424
import java.util.Map;
25+
import org.jspecify.annotations.NullMarked;
2526

2627
/** Indicates that a given {@link InputSource} should pause for a given duration. */
28+
@NullMarked
2729
public class Pause extends Interaction implements Encodable {
2830

2931
private final Duration duration;

java/src/org/openqa/selenium/interactions/Sequence.java

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.util.LinkedList;
2323
import java.util.List;
2424
import java.util.Map;
25+
import org.jspecify.annotations.NullMarked;
2526

2627
/**
2728
* A sequence of action objects for a given {@link InputSource} for use with the W3C <a
@@ -30,6 +31,7 @@
3031
* Interaction}s, with the first item in each sequence being executed at the same time, then the
3132
* second, and so on, until all interactions in all sequences have been executed.
3233
*/
34+
@NullMarked
3335
public class Sequence implements Encodable {
3436

3537
private final List<Encodable> actions = new LinkedList<>();

java/src/org/openqa/selenium/interactions/WheelInput.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import java.util.Map;
2525
import java.util.Optional;
2626
import java.util.UUID;
27+
import org.jspecify.annotations.NullMarked;
28+
import org.jspecify.annotations.Nullable;
2729
import org.openqa.selenium.Point;
2830
import org.openqa.selenium.WebElement;
2931
import org.openqa.selenium.WrapsElement;
@@ -33,11 +35,12 @@
3335
* Models a <a href="https://www.w3.org/TR/webdriver/#dfn-wheel-input-source">wheel input
3436
* source</a>.
3537
*/
38+
@NullMarked
3639
public class WheelInput implements InputSource, Encodable {
3740

3841
private final String name;
3942

40-
public WheelInput(String name) {
43+
public WheelInput(@Nullable String name) {
4144
this.name = Optional.ofNullable(name).orElse(UUID.randomUUID().toString());
4245
}
4346

java/src/org/openqa/selenium/logging/LogEntries.java

+2
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,15 @@
2323
import java.util.Iterator;
2424
import java.util.List;
2525
import java.util.stream.StreamSupport;
26+
import org.jspecify.annotations.NullMarked;
2627
import org.openqa.selenium.Beta;
2728

2829
/**
2930
* Represent a pool of {@link LogEntry}. This class also provides filtering mechanisms based on
3031
* levels.
3132
*/
3233
@Beta
34+
@NullMarked
3335
public class LogEntries implements Iterable<LogEntry> {
3436

3537
private final List<LogEntry> entries;

java/src/org/openqa/selenium/logging/LogEntry.java

+2
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@
2222
import java.util.HashMap;
2323
import java.util.Map;
2424
import java.util.logging.Level;
25+
import org.jspecify.annotations.NullMarked;
2526

2627
/** Represents a single log statement. */
28+
@NullMarked
2729
public class LogEntry {
2830

2931
private final Level level;

java/src/org/openqa/selenium/logging/LogLevelMapping.java

+11-4
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,20 @@
2020
import java.util.Collections;
2121
import java.util.HashMap;
2222
import java.util.Map;
23+
import java.util.Optional;
2324
import java.util.logging.Level;
25+
import org.jspecify.annotations.NullMarked;
26+
import org.jspecify.annotations.Nullable;
2427

28+
@NullMarked
2529
public class LogLevelMapping {
2630

2731
/** WebDriver log level DEBUG which is mapped to Level.FINE. */
2832
private static final String DEBUG = "DEBUG";
2933

34+
// Default the log level to info.
35+
private static final Level DEFAULT_LEVEL = Level.INFO;
36+
3037
private static final Map<Integer, Level> levelMap;
3138

3239
static {
@@ -70,15 +77,15 @@ public static String getName(Level level) {
7077
return normalized == Level.FINE ? DEBUG : normalized.getName();
7178
}
7279

73-
public static Level toLevel(String logLevelName) {
80+
public static Level toLevel(@Nullable String logLevelName) {
7481
if (logLevelName == null || logLevelName.isEmpty()) {
75-
// Default the log level to info.
76-
return Level.INFO;
82+
return DEFAULT_LEVEL;
7783
}
7884

7985
if (logLevelName.equals(DEBUG)) {
8086
return Level.FINE;
8187
}
82-
return levelMap.get(Level.parse(logLevelName).intValue());
88+
return Optional.ofNullable(levelMap.get(Level.parse(logLevelName).intValue()))
89+
.orElse(DEFAULT_LEVEL);
8390
}
8491
}

java/src/org/openqa/selenium/logging/SessionLogs.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,13 @@
2424
import java.util.List;
2525
import java.util.Map;
2626
import java.util.Set;
27+
import org.jspecify.annotations.NullMarked;
2728
import org.openqa.selenium.Beta;
29+
import org.openqa.selenium.internal.Require;
2830

2931
/** Contains the logs for a session divided by supported log types. */
3032
@Beta
33+
@NullMarked
3134
public class SessionLogs {
3235
private final Map<String, LogEntries> logTypeToEntriesMap;
3336

@@ -66,7 +69,7 @@ public static SessionLogs fromJSON(Map<String, Object> rawSessionLogs) {
6669
logEntries.add(
6770
new LogEntry(
6871
LogLevelMapping.toLevel(String.valueOf(rawEntry.get("level"))),
69-
((Number) rawEntry.get("timestamp")).longValue(),
72+
Require.nonNull("timestamp", (Number) rawEntry.get("timestamp")).longValue(),
7073
String.valueOf(rawEntry.get("message"))));
7174
}
7275
sessionLogs.addLog(logType, new LogEntries(logEntries));

java/src/org/openqa/selenium/remote/service/DriverService.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -508,10 +508,10 @@ public DS build() {
508508
if (Locale.getDefault(Locale.Category.FORMAT).getLanguage().equals("ar")) {
509509
throw new NumberFormatException(
510510
String.format(
511-
"Couldn't format the port numbers because the System Language is arabic:"
512-
+ " \"--port=%d\", please make sure to add the required arguments"
513-
+ " \"-Duser.language=en -Duser.region=US\" to your JVM, for more info please"
514-
+ " visit :%n"
511+
"Couldn't format the port numbers because the System Language is arabic: \""
512+
+ String.format("--port=%d", port)
513+
+ "\", please make sure to add the required arguments \"-Duser.language=en"
514+
+ " -Duser.region=US\" to your JVM, for more info please visit :\n"
515515
+ " https://www.selenium.dev/documentation/webdriver/browsers/",
516516
getPort()));
517517
}

java/test/org/openqa/selenium/logging/LoggingTest.java

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ void testLogLevelConversions() {
4040
assertThat(toLevel("WARNING")).isEqualTo(WARNING);
4141
assertThat(toLevel("SEVERE")).isEqualTo(SEVERE);
4242
assertThat(toLevel("OFF")).isEqualTo(OFF);
43+
assertThat(toLevel(null)).isEqualTo(INFO);
4344
}
4445

4546
@Test

py/selenium/webdriver/common/by.py

+52-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,58 @@
2222

2323

2424
class By:
25-
"""Set of supported locator strategies."""
25+
"""Set of supported locator strategies.
26+
27+
ID:
28+
--
29+
Select the element by its ID.
30+
31+
>>> element = driver.find_element(By.ID, 'myElement')
32+
33+
XPATH:
34+
------
35+
Select the element via XPATH.
36+
- absolute path
37+
- relative path
38+
39+
>>> element = driver.find_element(By.XPATH, '//html/body/div')
40+
41+
LINK_TEXT:
42+
----------
43+
Select the link element having the exact text.
44+
45+
>>> element = driver.find_element(By.LINK_TEXT, 'myLink')
46+
47+
PARTIAL_LINK_TEXT:
48+
------------------
49+
Select the link element having the partial text.
50+
51+
>>> element = driver.find_element(By.PARTIAL_LINK_TEXT, 'my')
52+
53+
NAME:
54+
----
55+
Select the element by its name attribute.
56+
57+
>>> element = driver.find_element(By.NAME, 'myElement')
58+
59+
TAG_NAME:
60+
--------
61+
Select the element by its tag name.
62+
63+
>>> element = driver.find_element(By.TAG_NAME, 'div')
64+
65+
CLASS_NAME:
66+
----------
67+
Select the element by its class name.
68+
69+
>>> element = driver.find_element(By.CLASS_NAME, 'myElement')
70+
71+
CSS_SELECTOR:
72+
-------------
73+
Select the element by its CSS selector.
74+
75+
>>> element = driver.find_element(By.CSS_SELECTOR, 'div.myElement')
76+
"""
2677

2778
ID = "id"
2879
XPATH = "xpath"

0 commit comments

Comments
 (0)