Skip to content

Commit 5edc25d

Browse files
committed
[grid] Firefox CDP version "85" -> "85.0"
This allows matching better and helps when CDP over Grid for Firefox is done. Also, switching `isSupportingCdp` to `true` for Firefox as well, since it works for some cases.
1 parent 09358a2 commit 5edc25d

File tree

3 files changed

+141
-143
lines changed

3 files changed

+141
-143
lines changed

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

Lines changed: 134 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,12 @@
1717

1818
package org.openqa.selenium.firefox;
1919

20+
import static org.openqa.selenium.remote.CapabilityType.PROXY;
21+
2022
import com.google.common.collect.ImmutableMap;
2123
import com.google.common.collect.Maps;
2224
import com.google.common.collect.Sets;
25+
2326
import org.openqa.selenium.Beta;
2427
import org.openqa.selenium.Capabilities;
2528
import org.openqa.selenium.ImmutableCapabilities;
@@ -58,8 +61,6 @@
5861
import java.util.Set;
5962
import java.util.stream.StreamSupport;
6063

61-
import static org.openqa.selenium.remote.CapabilityType.PROXY;
62-
6364
/**
6465
* An implementation of the {#link WebDriver} interface that drives Firefox.
6566
* <p>
@@ -78,107 +79,39 @@
7879
public class FirefoxDriver extends RemoteWebDriver
7980
implements WebStorage, HasExtensions, HasFullPageScreenshot, HasContext, HasDevTools {
8081

81-
public static final class SystemProperty {
82-
83-
/**
84-
* System property that defines the location of the Firefox executable file.
85-
*/
86-
public static final String BROWSER_BINARY = "webdriver.firefox.bin";
87-
88-
/**
89-
* System property that defines the location of the file where Firefox log should be stored.
90-
*/
91-
public static final String BROWSER_LOGFILE = "webdriver.firefox.logfile";
92-
93-
/**
94-
* System property that defines the additional library path (Linux only).
95-
*/
96-
public static final String BROWSER_LIBRARY_PATH = "webdriver.firefox.library.path";
97-
98-
/**
99-
* System property that defines the profile that should be used as a template.
100-
* When the driver starts, it will make a copy of the profile it is using,
101-
* rather than using that profile directly.
102-
*/
103-
public static final String BROWSER_PROFILE = "webdriver.firefox.profile";
104-
105-
/**
106-
* System property that defines the location of the webdriver.xpi browser extension to install
107-
* in the browser. If not set, the prebuilt extension bundled with this class will be used.
108-
*/
109-
public static final String DRIVER_XPI_PROPERTY = "webdriver.firefox.driver";
110-
111-
/**
112-
* Boolean system property that instructs FirefoxDriver to use Marionette backend,
113-
* overrides any capabilities specified by the user
114-
*/
115-
public static final String DRIVER_USE_MARIONETTE = "webdriver.firefox.marionette";
116-
}
117-
11882
/**
11983
* @deprecated Use {@link Capability#BINARY}
12084
*/
12185
@Deprecated
12286
public static final String BINARY = Capability.BINARY;
123-
12487
/**
12588
* @deprecated Use {@link Capability#PROFILE}
12689
*/
12790
@Deprecated
12891
public static final String PROFILE = Capability.PROFILE;
129-
13092
/**
13193
* @deprecated Use {@link Capability#MARIONETTE}
13294
*/
13395
@Deprecated
13496
public static final String MARIONETTE = Capability.MARIONETTE;
135-
136-
public static final class Capability {
137-
public static final String BINARY = "firefox_binary";
138-
public static final String PROFILE = "firefox_profile";
139-
public static final String MARIONETTE = "marionette";
140-
}
141-
142-
@Beta
143-
public static RemoteWebDriverBuilder builder() {
144-
return RemoteWebDriver.builder().oneOf(new FirefoxOptions());
145-
}
146-
147-
private static class FirefoxDriverCommandExecutor extends DriverCommandExecutor {
148-
public FirefoxDriverCommandExecutor(DriverService service) {
149-
super(service, getExtraCommands());
150-
}
151-
152-
private static Map<String, CommandInfo> getExtraCommands() {
153-
return ImmutableMap.<String, CommandInfo>builder()
154-
.putAll(new AddHasContext().getAdditionalCommands())
155-
.putAll(new AddHasExtensions().getAdditionalCommands())
156-
.putAll(new AddHasFullPageScreenshot().getAdditionalCommands())
157-
.build();
158-
}
159-
}
160-
16197
private final Capabilities capabilities;
162-
protected FirefoxBinary binary;
16398
private final RemoteWebStorage webStorage;
16499
private final HasExtensions extensions;
165100
private final HasFullPageScreenshot fullPageScreenshot;
166101
private final HasContext context;
167102
private final Optional<URI> cdpUri;
103+
protected FirefoxBinary binary;
168104
private DevTools devTools;
169-
170105
public FirefoxDriver() {
171106
this(new FirefoxOptions());
172107
}
173-
174108
/**
175109
* @deprecated Use {@link #FirefoxDriver(FirefoxOptions)}.
176110
*/
177111
@Deprecated
178112
public FirefoxDriver(Capabilities desiredCapabilities) {
179113
this(new FirefoxOptions(Require.nonNull("Capabilities", desiredCapabilities)));
180114
}
181-
182115
/**
183116
* @deprecated Use {@link #FirefoxDriver(FirefoxDriverService, FirefoxOptions)}.
184117
*/
@@ -188,7 +121,6 @@ public FirefoxDriver(FirefoxDriverService service, Capabilities desiredCapabilit
188121
Require.nonNull("Driver service", service),
189122
new FirefoxOptions(desiredCapabilities));
190123
}
191-
192124
public FirefoxDriver(FirefoxOptions options) {
193125
this(toExecutor(options), options);
194126
}
@@ -215,30 +147,82 @@ private FirefoxDriver(FirefoxDriverCommandExecutor executor, FirefoxOptions opti
215147

216148
this.cdpUri = cdpUri;
217149
this.capabilities = cdpUri.map(uri ->
218-
new ImmutableCapabilities(
219-
new PersistentCapabilities(capabilities)
220-
.setCapability("se:cdp", uri.toString())
221-
.setCapability("se:cdpVersion", "85")))
222-
.orElse(new ImmutableCapabilities(capabilities));
150+
new ImmutableCapabilities(
151+
new PersistentCapabilities(capabilities)
152+
.setCapability("se:cdp", uri.toString())
153+
.setCapability("se:cdpVersion", "85.0")))
154+
.orElse(new ImmutableCapabilities(capabilities));
155+
}
156+
157+
@Beta
158+
public static RemoteWebDriverBuilder builder() {
159+
return RemoteWebDriver.builder().oneOf(new FirefoxOptions());
223160
}
224161

225162
private static FirefoxDriverCommandExecutor toExecutor(FirefoxOptions options) {
226163
Require.nonNull("Options to construct executor from", options);
227164

228165
String sysProperty = System.getProperty(SystemProperty.DRIVER_USE_MARIONETTE);
229-
boolean isLegacy = (sysProperty != null && ! Boolean.parseBoolean(sysProperty))
166+
boolean isLegacy = (sysProperty != null && !Boolean.parseBoolean(sysProperty))
230167
|| options.isLegacy();
231168

232169
FirefoxDriverService.Builder<?, ?> builder =
233-
StreamSupport.stream(ServiceLoader.load(DriverService.Builder.class).spliterator(), false)
234-
.filter(b -> b instanceof FirefoxDriverService.Builder)
235-
.map(FirefoxDriverService.Builder.class::cast)
236-
.filter(b -> b.isLegacy() == isLegacy)
237-
.findFirst().orElseThrow(WebDriverException::new);
170+
StreamSupport.stream(ServiceLoader.load(DriverService.Builder.class).spliterator(), false)
171+
.filter(b -> b instanceof FirefoxDriverService.Builder)
172+
.map(FirefoxDriverService.Builder.class::cast)
173+
.filter(b -> b.isLegacy() == isLegacy)
174+
.findFirst().orElseThrow(WebDriverException::new);
238175

239176
return new FirefoxDriverCommandExecutor(builder.withOptions(options).build());
240177
}
241178

179+
private static boolean isLegacy(Capabilities desiredCapabilities) {
180+
Boolean forceMarionette = forceMarionetteFromSystemProperty();
181+
if (forceMarionette != null) {
182+
return !forceMarionette;
183+
}
184+
Object marionette = desiredCapabilities.getCapability(Capability.MARIONETTE);
185+
return marionette instanceof Boolean && !(Boolean) marionette;
186+
}
187+
188+
private static Boolean forceMarionetteFromSystemProperty() {
189+
String useMarionette = System.getProperty(SystemProperty.DRIVER_USE_MARIONETTE);
190+
if (useMarionette == null) {
191+
return null;
192+
}
193+
return Boolean.valueOf(useMarionette);
194+
}
195+
196+
/**
197+
* Drops capabilities that we shouldn't send over the wire.
198+
*
199+
* Used for capabilities which aren't BeanToJson-convertable, and are only used by the local
200+
* launcher.
201+
*/
202+
private static Capabilities dropCapabilities(Capabilities capabilities) {
203+
if (capabilities == null) {
204+
return new ImmutableCapabilities();
205+
}
206+
207+
MutableCapabilities caps;
208+
209+
if (isLegacy(capabilities)) {
210+
final Set<String> toRemove = Sets.newHashSet(Capability.BINARY, Capability.PROFILE);
211+
caps = new MutableCapabilities(
212+
Maps.filterKeys(capabilities.asMap(), key -> !toRemove.contains(key)));
213+
} else {
214+
caps = new MutableCapabilities(capabilities);
215+
}
216+
217+
// Ensure that the proxy is in a state fit to be sent to the extension
218+
Proxy proxy = Proxy.extractFrom(capabilities);
219+
if (proxy != null) {
220+
caps.setCapability(PROXY, proxy);
221+
}
222+
223+
return caps;
224+
}
225+
242226
@Override
243227
public Capabilities getCapabilities() {
244228
return capabilities;
@@ -247,8 +231,8 @@ public Capabilities getCapabilities() {
247231
@Override
248232
public void setFileDetector(FileDetector detector) {
249233
throw new WebDriverException(
250-
"Setting the file detector only works on remote webdriver instances obtained " +
251-
"via RemoteWebDriver");
234+
"Setting the file detector only works on remote webdriver instances obtained " +
235+
"via RemoteWebDriver");
252236
}
253237

254238
@Override
@@ -261,15 +245,6 @@ public SessionStorage getSessionStorage() {
261245
return webStorage.getSessionStorage();
262246
}
263247

264-
private static boolean isLegacy(Capabilities desiredCapabilities) {
265-
Boolean forceMarionette = forceMarionetteFromSystemProperty();
266-
if (forceMarionette != null) {
267-
return !forceMarionette;
268-
}
269-
Object marionette = desiredCapabilities.getCapability(Capability.MARIONETTE);
270-
return marionette instanceof Boolean && ! (Boolean) marionette;
271-
}
272-
273248
@Override
274249
public String installExtension(Path path) {
275250
Require.nonNull("Path", path);
@@ -304,53 +279,15 @@ public <X> X getFullPageScreenshotAs(OutputType<X> outputType) throws WebDriverE
304279
return fullPageScreenshot.getFullPageScreenshotAs(outputType);
305280
}
306281

307-
@Override
308-
public void setContext(FirefoxCommandContext commandContext) {
309-
Require.nonNull("Firefox Command Context", commandContext);
310-
context.setContext(commandContext);
311-
}
312-
313282
@Override
314283
public FirefoxCommandContext getContext() {
315284
return context.getContext();
316285
}
317286

318-
private static Boolean forceMarionetteFromSystemProperty() {
319-
String useMarionette = System.getProperty(SystemProperty.DRIVER_USE_MARIONETTE);
320-
if (useMarionette == null) {
321-
return null;
322-
}
323-
return Boolean.valueOf(useMarionette);
324-
}
325-
326-
/**
327-
* Drops capabilities that we shouldn't send over the wire.
328-
*
329-
* Used for capabilities which aren't BeanToJson-convertable, and are only used by the local
330-
* launcher.
331-
*/
332-
private static Capabilities dropCapabilities(Capabilities capabilities) {
333-
if (capabilities == null) {
334-
return new ImmutableCapabilities();
335-
}
336-
337-
MutableCapabilities caps;
338-
339-
if (isLegacy(capabilities)) {
340-
final Set<String> toRemove = Sets.newHashSet(Capability.BINARY, Capability.PROFILE);
341-
caps = new MutableCapabilities(
342-
Maps.filterKeys(capabilities.asMap(), key -> !toRemove.contains(key)));
343-
} else {
344-
caps = new MutableCapabilities(capabilities);
345-
}
346-
347-
// Ensure that the proxy is in a state fit to be sent to the extension
348-
Proxy proxy = Proxy.extractFrom(capabilities);
349-
if (proxy != null) {
350-
caps.setCapability(PROXY, proxy);
351-
}
352-
353-
return caps;
287+
@Override
288+
public void setContext(FirefoxCommandContext commandContext) {
289+
Require.nonNull("Firefox Command Context", commandContext);
290+
context.setContext(commandContext);
354291
}
355292

356293
@Override
@@ -383,6 +320,66 @@ public DevTools getDevTools() {
383320
throw new DevToolsException("This version of Firefox or geckodriver does not support CDP");
384321
}
385322

386-
return maybeGetDevTools().orElseThrow(() -> new DevToolsException("Unable to initialize CDP connection"));
323+
return maybeGetDevTools()
324+
.orElseThrow(() -> new DevToolsException("Unable to initialize CDP connection"));
325+
}
326+
327+
public static final class SystemProperty {
328+
329+
/**
330+
* System property that defines the location of the Firefox executable file.
331+
*/
332+
public static final String BROWSER_BINARY = "webdriver.firefox.bin";
333+
334+
/**
335+
* System property that defines the location of the file where Firefox log should be stored.
336+
*/
337+
public static final String BROWSER_LOGFILE = "webdriver.firefox.logfile";
338+
339+
/**
340+
* System property that defines the additional library path (Linux only).
341+
*/
342+
public static final String BROWSER_LIBRARY_PATH = "webdriver.firefox.library.path";
343+
344+
/**
345+
* System property that defines the profile that should be used as a template.
346+
* When the driver starts, it will make a copy of the profile it is using,
347+
* rather than using that profile directly.
348+
*/
349+
public static final String BROWSER_PROFILE = "webdriver.firefox.profile";
350+
351+
/**
352+
* System property that defines the location of the webdriver.xpi browser extension to install
353+
* in the browser. If not set, the prebuilt extension bundled with this class will be used.
354+
*/
355+
public static final String DRIVER_XPI_PROPERTY = "webdriver.firefox.driver";
356+
357+
/**
358+
* Boolean system property that instructs FirefoxDriver to use Marionette backend,
359+
* overrides any capabilities specified by the user
360+
*/
361+
public static final String DRIVER_USE_MARIONETTE = "webdriver.firefox.marionette";
362+
}
363+
364+
public static final class Capability {
365+
366+
public static final String BINARY = "firefox_binary";
367+
public static final String PROFILE = "firefox_profile";
368+
public static final String MARIONETTE = "marionette";
369+
}
370+
371+
private static class FirefoxDriverCommandExecutor extends DriverCommandExecutor {
372+
373+
public FirefoxDriverCommandExecutor(DriverService service) {
374+
super(service, getExtraCommands());
375+
}
376+
377+
private static Map<String, CommandInfo> getExtraCommands() {
378+
return ImmutableMap.<String, CommandInfo>builder()
379+
.putAll(new AddHasContext().getAdditionalCommands())
380+
.putAll(new AddHasExtensions().getAdditionalCommands())
381+
.putAll(new AddHasFullPageScreenshot().getAdditionalCommands())
382+
.build();
383+
}
387384
}
388385
}

0 commit comments

Comments
 (0)