Skip to content

Commit 3f546d9

Browse files
committed
[js] Add some checks to catch misuse of the options classes, whose semantics
have changed since 3.6
1 parent 1389672 commit 3f546d9

File tree

2 files changed

+107
-7
lines changed

2 files changed

+107
-7
lines changed

javascript/node/selenium-webdriver/index.js

Lines changed: 71 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,23 @@
2222

2323
'use strict';
2424

25-
const chrome = require('./chrome');
26-
const edge = require('./edge');
27-
const firefox = require('./firefox');
2825
const _http = require('./http');
29-
const ie = require('./ie');
3026
const by = require('./lib/by');
3127
const capabilities = require('./lib/capabilities');
28+
const chrome = require('./chrome');
3229
const command = require('./lib/command');
30+
const edge = require('./edge');
3331
const error = require('./lib/error');
32+
const firefox = require('./firefox');
33+
const ie = require('./ie');
3434
const input = require('./lib/input');
3535
const logging = require('./lib/logging');
3636
const promise = require('./lib/promise');
37+
const remote = require('./remote');
38+
const safari = require('./safari');
3739
const session = require('./lib/session');
3840
const until = require('./lib/until');
3941
const webdriver = require('./lib/webdriver');
40-
const remote = require('./remote');
41-
const safari = require('./safari');
4242

4343
const Browser = capabilities.Browser;
4444
const Capabilities = capabilities.Capabilities;
@@ -597,6 +597,14 @@ class Builder {
597597
capabilities.merge(this.edgeOptions_);
598598
}
599599

600+
checkOptions(
601+
capabilities, 'chromeOptions', chrome.Options, 'setChromeOptions');
602+
checkOptions(
603+
capabilities, 'moz:firefoxOptions', firefox.Options,
604+
'setFirefoxOptions');
605+
checkOptions(
606+
capabilities, 'safari.options', safari.Options, 'setSafariOptions');
607+
600608
// Check for a remote browser.
601609
let url = this.url_;
602610
if (!this.ignoreEnv_) {
@@ -669,6 +677,63 @@ class Builder {
669677
}
670678

671679

680+
/**
681+
* In the 3.x releases, the various browser option classes
682+
* (e.g. firefox.Options) had to be manually set as an option using the
683+
* Capabilties class:
684+
*
685+
* let ffo = new firefox.Options();
686+
* // Configure firefox options...
687+
*
688+
* let caps = new Capabilities();
689+
* caps.set('moz:firefoxOptions', ffo);
690+
*
691+
* let driver = new Builder()
692+
* .withCapabilities(caps)
693+
* .build();
694+
*
695+
* The options are now subclasses of Capabilities and can be used directly. A
696+
* direct translation of the above is:
697+
*
698+
* let ffo = new firefox.Options();
699+
* // Configure firefox options...
700+
*
701+
* let driver = new Builder()
702+
* .withCapabilities(ffo)
703+
* .build();
704+
*
705+
* You can also set the options for various browsers at once and let the builder
706+
* choose the correct set at runtime (see Builder docs above):
707+
*
708+
* let ffo = new firefox.Options();
709+
* // Configure ...
710+
*
711+
* let co = new chrome.Options();
712+
* // Configure ...
713+
*
714+
* let driver = new Builder()
715+
* .setChromeOptions(co)
716+
* .setFirefoxOptions(ffo)
717+
* .build();
718+
*
719+
* @param {!Capabilities} caps
720+
* @param {string} key
721+
* @param {function(new: Capabilities)} optionType
722+
* @param {string} setMethod
723+
* @throws {error.InvalidArgumentError}
724+
*/
725+
function checkOptions(caps, key, optionType, setMethod) {
726+
let val = caps.get(key);
727+
if (val instanceof optionType) {
728+
throw new error.InvalidArgumentError(
729+
'Options class extends Capabilities and should not be set as key '
730+
+ `"${key}"; set browser-specific options with `
731+
+ `Builder.${setMethod}(). For more information, see the `
732+
+ 'documentation attached to the function that threw this error');
733+
}
734+
}
735+
736+
672737
// PUBLIC API
673738

674739

javascript/node/selenium-webdriver/test/session_test.js renamed to javascript/node/selenium-webdriver/test/builder_test.js

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,14 @@ const assert = require('assert');
2121

2222
const chrome = require('../chrome');
2323
const edge = require('../edge');
24+
const error = require('../lib/error');
2425
const firefox = require('../firefox');
2526
const ie = require('../ie');
2627
const safari = require('../safari');
2728
const test = require('../lib/test');
2829
const {Browser} = require('../lib/capabilities');
2930
const {Pages} = require('../lib/test');
30-
const {WebDriver} = require('..');
31+
const {Builder, Capabilities, WebDriver} = require('..');
3132

3233

3334
test.suite(function(env) {
@@ -68,4 +69,38 @@ test.suite(function(env) {
6869
});
6970
});
7071
}
72+
73+
class OptionsTest {
74+
constructor(ctor, key) {
75+
this.ctor = ctor;
76+
this.key = key;
77+
}
78+
}
79+
80+
});
81+
82+
describe('Builder', function() {
83+
describe('catches incorrect use of browser options class', function() {
84+
function test(key, options) {
85+
it(key, async function() {
86+
let builder = new Builder()
87+
.withCapabilities(new Capabilities()
88+
.set('browserName', 'fake-browser-should-not-try-to-start')
89+
.set(key, new options()));
90+
try {
91+
let driver = await builder.build();
92+
await driver.quit();
93+
return Promise.reject(Error('should have failed'));
94+
} catch (ex) {
95+
if (!(ex instanceof error.InvalidArgumentError)) {
96+
throw ex;
97+
}
98+
}
99+
});
100+
}
101+
102+
test('chromeOptions', chrome.Options);
103+
test('moz:firefoxOptions', firefox.Options);
104+
test('safari.options', safari.Options);
105+
});
71106
});

0 commit comments

Comments
 (0)