Skip to content

Commit a297017

Browse files
committed
[java] Logging warnings when non-W3C caps are being used.
Helps with #10374
1 parent 0d6a695 commit a297017

11 files changed

+83
-22
lines changed

‎java/src/org/openqa/selenium/remote/AcceptedW3CCapabilityKeys.java renamed to ‎java/src/org/openqa/selenium/AcceptedW3CCapabilityKeys.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
// specific language governing permissions and limitations
1616
// under the License.
1717

18-
package org.openqa.selenium.remote;
18+
package org.openqa.selenium;
1919

2020
import java.util.function.Predicate;
2121
import java.util.regex.Pattern;
@@ -36,9 +36,9 @@ public class AcceptedW3CCapabilityKeys implements Predicate<String> {
3636
"^timeouts$",
3737
"^unhandledPromptBehavior$",
3838
"^webSocketUrl$") // from webdriver-bidi
39-
.map(Pattern::compile)
40-
.map(Pattern::asPredicate)
41-
.reduce(identity -> false, Predicate::or);
39+
.map(Pattern::compile)
40+
.map(Pattern::asPredicate)
41+
.reduce(identity -> false, Predicate::or);
4242

4343
@Override
4444
public boolean test(String capabilityName) {

‎java/src/org/openqa/selenium/MutableCapabilities.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
public class MutableCapabilities implements Capabilities {
2929

3030
private static final Set<String> OPTION_KEYS;
31+
3132
static {
3233
HashSet<String> keys = new HashSet<>();
3334
keys.add("chromeOptions");
@@ -87,6 +88,8 @@ public void setCapability(String capabilityName, Platform value) {
8788
public void setCapability(String key, Object value) {
8889
Require.nonNull("Capability name", key);
8990

91+
W3CCapabilityKeysValidator.validateCapability(key);
92+
9093
// We have to special-case some keys and values because of the popular idiom of calling
9194
// something like "capabilities.setCapability(SafariOptions.CAPABILITY, new SafariOptions());"
9295
// and this is no longer needed as options are capabilities. There will be a large amount of

‎java/src/org/openqa/selenium/PersistentCapabilities.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.util.stream.Stream;
2929

3030
public class PersistentCapabilities implements Capabilities {
31+
3132
private final ImmutableCapabilities caps;
3233
private final ImmutableCapabilities overrides;
3334
private final int hashCode;
@@ -52,6 +53,8 @@ public PersistentCapabilities setCapability(String name, Object value) {
5253
Require.nonNull("Name", name);
5354
Require.nonNull("Value", value);
5455

56+
W3CCapabilityKeysValidator.validateCapability(name);
57+
5558
return new PersistentCapabilities(this, new ImmutableCapabilities(name, value));
5659
}
5760

‎java/src/org/openqa/selenium/SharedCapabilitiesMethods.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ static boolean equals(Capabilities left, Capabilities right) {
4646
}
4747

4848
static void setCapability(Map<String, Object> caps, String key, Object value) {
49+
W3CCapabilityKeysValidator.validateCapability(key);
50+
4951
if ("loggingPrefs".equals(key) && value instanceof Map) {
5052
LoggingPreferences prefs = new LoggingPreferences();
5153
@SuppressWarnings("unchecked") Map<String, String> prefsMap = (Map<String, String>) value;
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Licensed to the Software Freedom Conservancy (SFC) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The SFC licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
package org.openqa.selenium;
19+
20+
import java.util.function.Predicate;
21+
import java.util.logging.Level;
22+
import java.util.logging.Logger;
23+
24+
public class W3CCapabilityKeysValidator {
25+
26+
private static final Logger LOG = Logger.getLogger(W3CCapabilityKeysValidator.class.getName());
27+
private static final Predicate<String> ACCEPTED_W3C_PATTERNS = new AcceptedW3CCapabilityKeys();
28+
29+
public static void validateCapability(String capabilityName) {
30+
if (!ACCEPTED_W3C_PATTERNS.test(capabilityName)) {
31+
LOG.log(Level.WARNING,
32+
() -> String.format("Support for Legacy Capabilities is deprecated; " +
33+
"You are sending \"%s\" which is an invalid capability. " +
34+
"Please update to W3C Syntax: https://www.selenium.dev/blog/2022/legacy-protocol-support/",
35+
capabilityName));
36+
}
37+
38+
}
39+
}

‎java/src/org/openqa/selenium/remote/CapabilitiesUtils.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
import com.google.common.collect.ImmutableList;
2121
import com.google.common.collect.ImmutableMap;
2222
import com.google.common.collect.ImmutableSet;
23+
24+
import org.openqa.selenium.AcceptedW3CCapabilityKeys;
2325
import org.openqa.selenium.Capabilities;
2426
import org.openqa.selenium.ImmutableCapabilities;
2527
import org.openqa.selenium.Proxy;

‎java/src/org/openqa/selenium/remote/NewSessionPayload.java

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
import com.google.common.io.CharSource;
2727
import com.google.common.io.CharStreams;
2828
import com.google.common.io.FileBackedOutputStream;
29+
30+
import org.openqa.selenium.AcceptedW3CCapabilityKeys;
2931
import org.openqa.selenium.Capabilities;
3032
import org.openqa.selenium.ImmutableCapabilities;
3133
import org.openqa.selenium.internal.Require;
@@ -61,21 +63,6 @@ public class NewSessionPayload implements Closeable {
6163
private final FileBackedOutputStream backingStore;
6264
private final ImmutableSet<Dialect> dialects;
6365

64-
public static NewSessionPayload create(Capabilities caps) {
65-
// We need to convert the capabilities into a new session payload. At this point we're dealing
66-
// with references, so I'm Just Sure This Will Be Fine.
67-
return create(ImmutableMap.of("desiredCapabilities", caps.asMap()));
68-
}
69-
70-
public static NewSessionPayload create(Map<String, ?> source) {
71-
String json = new Json().toJson(Require.nonNull("Payload", source));
72-
return new NewSessionPayload(new StringReader(json));
73-
}
74-
75-
public static NewSessionPayload create(Reader source) {
76-
return new NewSessionPayload(source);
77-
}
78-
7966
private NewSessionPayload(Reader source) {
8067
// Dedicate up to 10% of all RAM or 20% of available RAM (whichever is smaller) to storing this
8168
// payload.
@@ -116,6 +103,21 @@ private NewSessionPayload(Reader source) {
116103

117104
}
118105

106+
public static NewSessionPayload create(Capabilities caps) {
107+
// We need to convert the capabilities into a new session payload. At this point we're dealing
108+
// with references, so I'm Just Sure This Will Be Fine.
109+
return create(ImmutableMap.of("desiredCapabilities", caps.asMap()));
110+
}
111+
112+
public static NewSessionPayload create(Map<String, ?> source) {
113+
String json = new Json().toJson(Require.nonNull("Payload", source));
114+
return new NewSessionPayload(new StringReader(json));
115+
}
116+
117+
public static NewSessionPayload create(Reader source) {
118+
return new NewSessionPayload(source);
119+
}
120+
119121
private void validate() throws IOException {
120122
Map<String, Object> alwaysMatch = getAlwaysMatch();
121123
if (alwaysMatch == null) {

‎java/src/org/openqa/selenium/remote/ProtocolHandshake.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import com.google.common.io.CountingOutputStream;
2121
import com.google.common.io.FileBackedOutputStream;
2222

23+
import org.openqa.selenium.AcceptedW3CCapabilityKeys;
2324
import org.openqa.selenium.Capabilities;
2425
import org.openqa.selenium.ImmutableCapabilities;
2526
import org.openqa.selenium.Proxy;

‎java/src/org/openqa/selenium/remote/RemoteWebDriverBuilder.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,15 @@
1919

2020
import com.google.common.annotations.VisibleForTesting;
2121
import com.google.common.collect.ImmutableSet;
22+
23+
import org.openqa.selenium.AcceptedW3CCapabilityKeys;
2224
import org.openqa.selenium.Beta;
2325
import org.openqa.selenium.Capabilities;
2426
import org.openqa.selenium.Credentials;
2527
import org.openqa.selenium.ImmutableCapabilities;
2628
import org.openqa.selenium.SessionNotCreatedException;
2729
import org.openqa.selenium.UsernameAndPassword;
30+
import org.openqa.selenium.W3CCapabilityKeysValidator;
2831
import org.openqa.selenium.WebDriver;
2932
import org.openqa.selenium.WebDriverInfo;
3033
import org.openqa.selenium.internal.Either;
@@ -53,6 +56,7 @@
5356
import java.util.Set;
5457
import java.util.TreeMap;
5558
import java.util.function.Function;
59+
import java.util.function.Predicate;
5660
import java.util.function.Supplier;
5761
import java.util.logging.Logger;
5862
import java.util.stream.Collectors;
@@ -89,7 +93,9 @@
8993
*/
9094
@Beta
9195
public class RemoteWebDriverBuilder {
96+
9297
private static final Logger LOG = Logger.getLogger(RemoteWebDriverBuilder.class.getName());
98+
private static final Predicate<String> ACCEPTED_W3C_PATTERNS = new AcceptedW3CCapabilityKeys();
9399
private static final Set<String> ILLEGAL_METADATA_KEYS = ImmutableSet.of(
94100
"alwaysMatch",
95101
"capabilities",
@@ -198,11 +204,14 @@ public RemoteWebDriverBuilder setCapability(String capabilityName, Object value)
198204
Require.nonNull("Capability name", capabilityName);
199205
Require.nonNull("Capability value", value);
200206

207+
W3CCapabilityKeysValidator.validateCapability(capabilityName);
208+
201209
Object previous = additionalCapabilities.put(capabilityName, value);
202210
if (previous != null) {
203211
LOG.log(
204212
getDebugLogLevel(),
205-
String.format("Overwriting capability %s. Previous value %s, new value %s", capabilityName, previous, value));
213+
String.format("Overwriting capability %s. Previous value %s, new value %s", capabilityName,
214+
previous, value));
206215
}
207216

208217
return this;

‎java/test/org/openqa/selenium/chrome/ChromeOptionsTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@
1919

2020
import org.junit.Test;
2121
import org.junit.experimental.categories.Category;
22+
import org.openqa.selenium.AcceptedW3CCapabilityKeys;
2223
import org.openqa.selenium.PageLoadStrategy;
2324
import org.openqa.selenium.UnexpectedAlertBehaviour;
24-
import org.openqa.selenium.remote.AcceptedW3CCapabilityKeys;
2525
import org.openqa.selenium.testing.TestUtilities;
2626
import org.openqa.selenium.testing.UnitTests;
2727

‎java/test/org/openqa/selenium/safari/SafariOptionsTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import org.junit.Test;
2121
import org.junit.experimental.categories.Category;
2222
import org.openqa.selenium.ImmutableCapabilities;
23-
import org.openqa.selenium.remote.AcceptedW3CCapabilityKeys;
23+
import org.openqa.selenium.AcceptedW3CCapabilityKeys;
2424
import org.openqa.selenium.remote.CapabilityType;
2525
import org.openqa.selenium.testing.UnitTests;
2626

0 commit comments

Comments
 (0)