selenium-webdriver 3.6.0 → 4.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGES.md +181 -0
- package/README.md +25 -27
- package/chrome.js +113 -127
- package/edge.js +42 -117
- package/example/chrome_android.js +8 -8
- package/example/chrome_mobile_emulation.js +8 -8
- package/example/firefox_channels.js +22 -18
- package/example/google_search_test.js +39 -26
- package/example/logging.js +39 -6
- package/firefox.js +769 -0
- package/http/index.js +41 -4
- package/http/util.js +11 -6
- package/ie.js +56 -97
- package/index.js +178 -114
- package/jasmine.json +11 -0
- package/lib/actions.js +68 -63
- package/lib/by.js +1 -1
- package/lib/capabilities.js +255 -192
- package/lib/command.js +26 -50
- package/lib/error.js +85 -44
- package/lib/http.js +133 -110
- package/lib/input.js +1044 -8
- package/lib/promise.js +222 -3323
- package/lib/proxy.js +134 -39
- package/lib/test/bootstrap_jasmine.js +28 -0
- package/lib/test/data/actions/click.html +24 -0
- package/lib/test/data/actions/drag.html +77 -0
- package/lib/test/data/actions/record_click.html +21 -0
- package/lib/test/data/chrome/download.html +2 -0
- package/lib/test/data/inputs.html +42 -0
- package/lib/test/data/selectPage.html +12 -0
- package/lib/test/data/simpleTest.html +5 -0
- package/lib/test/data/upload_invisible.html +45 -0
- package/lib/test/fileserver.js +23 -19
- package/lib/test/index.js +30 -212
- package/lib/test/resources.js +0 -1
- package/lib/webdriver.js +675 -936
- package/net/index.js +21 -25
- package/net/portprober.js +51 -68
- package/package.json +5 -3
- package/remote/index.js +5 -19
- package/safari.js +41 -128
- package/test/actions_test.js +173 -18
- package/test/{session_test.js → builder_test.js} +44 -37
- package/test/chrome/devtools_test.js +93 -0
- package/test/chrome/options_test.js +48 -154
- package/test/chrome/service_test.js +7 -7
- package/test/cookie_test.js +77 -63
- package/test/element_finding_test.js +206 -201
- package/test/execute_script_test.js +115 -114
- package/test/fingerprint_test.js +16 -15
- package/test/firefox_test.js +251 -0
- package/test/http/http_test.js +0 -1
- package/test/http/util_test.js +2 -2
- package/test/io/zip_test.js +6 -7
- package/test/lib/error_test.js +34 -7
- package/test/lib/http_test.js +8 -128
- package/test/lib/input_test.js +1379 -0
- package/test/lib/promise_test.js +473 -908
- package/test/lib/webdriver_test.js +296 -868
- package/test/logging_test.js +37 -43
- package/test/page_loading_test.js +71 -81
- package/test/proxy_test.js +64 -72
- package/test/rect_test.js +14 -25
- package/test/remote_test.js +10 -29
- package/test/safari_test.js +7 -71
- package/test/stale_element_test.js +20 -23
- package/test/tag_name_test.js +10 -9
- package/test/upload_test.js +27 -35
- package/test/window_test.js +72 -85
- package/testing/index.js +386 -314
- package/.npmignore +0 -2
- package/example/async_await_test.js +0 -69
- package/example/google_search_generator.js +0 -47
- package/example/parallel_flows.js +0 -51
- package/firefox/binary.js +0 -347
- package/firefox/extension.js +0 -224
- package/firefox/index.js +0 -576
- package/firefox/profile.js +0 -311
- package/lib/events.js +0 -210
- package/lib/test/data/firefox/jetpack-sample.xpi +0 -0
- package/lib/test/data/firefox/sample.xpi +0 -0
- package/lib/test/promise.js +0 -79
- package/opera.js +0 -405
- package/phantomjs.js +0 -282
- package/test/firefox/extension_test.js +0 -120
- package/test/firefox/firefox_test.js +0 -244
- package/test/firefox/profile_test.js +0 -140
- package/test/lib/events_test.js +0 -177
- package/test/lib/promise_aplus_test.js +0 -78
- package/test/lib/promise_error_test.js +0 -884
- package/test/lib/promise_flow_test.js +0 -2288
- package/test/lib/promise_generator_test.js +0 -310
- package/test/phantomjs/execute_phantomjs_test.js +0 -59
- package/test/testing/assert_test.js +0 -373
- package/test/testing/index_test.js +0 -224
- package/testing/assert.js +0 -378
package/CHANGES.md
CHANGED
|
@@ -1,3 +1,184 @@
|
|
|
1
|
+
## v4.0.0-alpha.1
|
|
2
|
+
|
|
3
|
+
### Notice
|
|
4
|
+
|
|
5
|
+
* The minimum supported version of Node is now 8.9.0 LTS
|
|
6
|
+
|
|
7
|
+
### Changes to Supported Browsers
|
|
8
|
+
|
|
9
|
+
Native support has been removed for Opera and PhantomJS as the WebDriver
|
|
10
|
+
implementations for these browsers are no longer under active development.
|
|
11
|
+
|
|
12
|
+
For Opera, users should be able to simply rely on testing Chrome as the Opera
|
|
13
|
+
browser is based on Chromium (and the operadriver was a thin wrapper around
|
|
14
|
+
chromedriver). For PhantomJS, users should use Chrome or Firefox in headless
|
|
15
|
+
mode (see `example/headless.js`)
|
|
16
|
+
|
|
17
|
+
### Changes for W3C WebDriver Spec Compliance
|
|
18
|
+
|
|
19
|
+
* Revamped the actions API to conform with the WebDriver Spec:
|
|
20
|
+
<https://www.w3.org/TR/webdriver/#actions>. For details, refer to the JS doc
|
|
21
|
+
on the `lib/input.Actions` class.
|
|
22
|
+
|
|
23
|
+
As of January, 2018, only Firefox natively supports this new API. You can
|
|
24
|
+
put the `Actions` class into "bridge mode" and it will attempt to translate
|
|
25
|
+
mouse and keyboard actions to the legacy API (see class docs). Alternatively,
|
|
26
|
+
you may continue to use the legacy API directly via the `lib/actions` module.
|
|
27
|
+
__NOTE:__ The legacy API is considered strongly deprecated and will be
|
|
28
|
+
removed in a minor release once Google's Chrome and Microsoft's Edge browsers
|
|
29
|
+
support the new API.
|
|
30
|
+
|
|
31
|
+
* All window manipulation commands are now supported.
|
|
32
|
+
* Added `driver.switchTo().parentFrame()`
|
|
33
|
+
* When a named cookie is requested, attempt to fetch it directly using the
|
|
34
|
+
W3C endpoint, `GET /session/{session id}/cookie/{name}`. If this command is
|
|
35
|
+
not recognized by the remote end, fallback to fetching all cookies and then
|
|
36
|
+
searching for the desired name.
|
|
37
|
+
* Replaced `WebElement.getSize()` and `WebElement.getLocation()` with a single
|
|
38
|
+
method, `WebElement.getRect()`.
|
|
39
|
+
|
|
40
|
+
### API Changes
|
|
41
|
+
|
|
42
|
+
* The core WebDriver API no longer uses promise manager
|
|
43
|
+
- Removed `index.Builder#setControlFlow()`
|
|
44
|
+
- The following thenable types no longer have a `cancel()` method:
|
|
45
|
+
- The dynamically generated thenable WebDrivers created by `index.Builder`
|
|
46
|
+
- `lib/webdriver.AlertPromise`
|
|
47
|
+
- `lib/webdriver.WebElementPromise`
|
|
48
|
+
* Removed `remote/index.DriverService.prototype.stop()` (use `#kill()` instead)
|
|
49
|
+
* Removed the `lib/actions` module
|
|
50
|
+
* Removed the `lib/events` module
|
|
51
|
+
* Removed the `phantomjs` module
|
|
52
|
+
* Removed the 'opera' module
|
|
53
|
+
* Removed the promise manager from `lib/promise`, which includes the removal
|
|
54
|
+
of the following exported names (replacements, if any, in parentheses):
|
|
55
|
+
- CancellableThenable
|
|
56
|
+
- CancellationError
|
|
57
|
+
- ControlFlow
|
|
58
|
+
- Deferred
|
|
59
|
+
- LONG_STACK_TRACES
|
|
60
|
+
- MultipleUnhandledRejectionError
|
|
61
|
+
- Promise (use native Promises)
|
|
62
|
+
- Resolver
|
|
63
|
+
- Scheduler
|
|
64
|
+
- Thenable
|
|
65
|
+
- USE_PROMISE_MANAGER
|
|
66
|
+
- all (use Promise.all)
|
|
67
|
+
- asap (use Promise.resolve)
|
|
68
|
+
- captureStackTrace (use Error.captureStackTrace)
|
|
69
|
+
- consume (use async functions)
|
|
70
|
+
- controlFlow
|
|
71
|
+
- createPromise (use new Promise)
|
|
72
|
+
- defer
|
|
73
|
+
- fulfilled (use Promise.resolve)
|
|
74
|
+
- isGenerator
|
|
75
|
+
- rejected (use Promise.reject)
|
|
76
|
+
- setDefaultFlow
|
|
77
|
+
- when (use Promise.resolve)
|
|
78
|
+
* Changes to the `Builder` class:
|
|
79
|
+
- Added setChromeService, setEdgeService, & setFirefoxService
|
|
80
|
+
- Removed setEnableNativeEvents
|
|
81
|
+
- Removed setScrollBehavior
|
|
82
|
+
* Changes to `chrome.Driver`
|
|
83
|
+
- Added sendDevToolsCommand
|
|
84
|
+
- Added setDownloadPath
|
|
85
|
+
* Changes to `chrome.Options`
|
|
86
|
+
- Now extends the `Capabilities` class
|
|
87
|
+
- Removed from/toCapabilities
|
|
88
|
+
* Changes to `edge.Options`
|
|
89
|
+
- Now extends the `Capabilities` class
|
|
90
|
+
- Removed from/toCapabilities
|
|
91
|
+
* Changes to `ie.Options`
|
|
92
|
+
- Now extends the `Capabilities` class
|
|
93
|
+
- Removed from/toCapabilities
|
|
94
|
+
* Removed the `firefox.Binary` class. Custom binaries can still be selected
|
|
95
|
+
using `firefox.Options#setBinary()`. Likewise, custom binary arguments can be
|
|
96
|
+
specified with `firefox.Options#addArguments()`.
|
|
97
|
+
* Changes to `firefox.Driver`
|
|
98
|
+
- Added installAddon(path)
|
|
99
|
+
- Added uninstallAddon(id)
|
|
100
|
+
* Changes to `firefox.Options`
|
|
101
|
+
- Now extends the `Capabilities` class
|
|
102
|
+
- Removed from/toCapabilities
|
|
103
|
+
- Removed setLoggingPreferences (was a no-op)
|
|
104
|
+
- setProfile now only accepts a path to an existing profile
|
|
105
|
+
- Added addExtensions
|
|
106
|
+
- Added setPreference
|
|
107
|
+
* Removed the `firefox.Profile` class. All of its functionality is now
|
|
108
|
+
provided directly by `firefox.Options`
|
|
109
|
+
* Removed the `firefox/binary` module
|
|
110
|
+
* Removed the `firefox/profile` module
|
|
111
|
+
* Changes to `safari.Options`
|
|
112
|
+
- Now extends the `Capabilities` class
|
|
113
|
+
- Removed from/toCapabilities
|
|
114
|
+
- Removed setCleanSession (was a no-op)
|
|
115
|
+
* Changes to `lib/capabilities.Browser`:
|
|
116
|
+
- Removed several enum values.
|
|
117
|
+
- ANDROID (use Chrome for Android; see docs on the chrome module)
|
|
118
|
+
- IPAD (no support available)
|
|
119
|
+
- IPHONE (no support available)
|
|
120
|
+
- OPERA (use Chrome)
|
|
121
|
+
- PHANTOM_JS (use Chrome or Firefox in headless mode)
|
|
122
|
+
- HTMLUNIT (use Chrome or Firefox in headless mode)
|
|
123
|
+
* Changes to `lib/capabilities.Capabilities`:
|
|
124
|
+
- Removed static factory methods android(), ipad(), iphone(), opera(),
|
|
125
|
+
phantomjs(), htmlunit(), and htmlunitwithjs(). Users can still manually
|
|
126
|
+
configure capabilities for these, but their use is not recommended and
|
|
127
|
+
they will no longer be surfaced in the API.
|
|
128
|
+
* Changes to `lib/error`:
|
|
129
|
+
- Added
|
|
130
|
+
- ElementClickInterceptedError
|
|
131
|
+
- InsecureCertificateError
|
|
132
|
+
- InvalidCoordinatesError
|
|
133
|
+
- NoSuchCookieError
|
|
134
|
+
- Removed
|
|
135
|
+
- ElementNotVisibleError
|
|
136
|
+
- InvalidElementCoordinatesError
|
|
137
|
+
* Changes to `lib/webdriver.WebDriver`:
|
|
138
|
+
- Dropped support for "requiredCapabilities" from WebDriver.createSession
|
|
139
|
+
- actions() now returns the new `lib/input.Actions` class
|
|
140
|
+
- Removed touchActions
|
|
141
|
+
- Renamed schedule to execute
|
|
142
|
+
- Removed the `WebDriver.attachToSession()` factory method. Users can just
|
|
143
|
+
the `WebDriver` constructor directly instead.
|
|
144
|
+
- Removed the `call()` method. This was used to inject custom function calls
|
|
145
|
+
into the control flow. Now that the promise manager is no longer used,
|
|
146
|
+
this method is no longer necessary. Users are now responsible for
|
|
147
|
+
coordinating actions (ideally with async functions) and can just call
|
|
148
|
+
functions directly instead of through `driver.call()`.
|
|
149
|
+
* Changes to `lib/webdriver.WebElement`:
|
|
150
|
+
- Replaced getSize & getLocation with getRect
|
|
151
|
+
* Changes to `lib/webdriver.Alert`:
|
|
152
|
+
- Removed authenticateAs
|
|
153
|
+
* Changes to `lib/webdriver.Options` (`driver.manage()`):
|
|
154
|
+
- Removed timeouts (use get/setTimeouts)
|
|
155
|
+
* Changes to `lib/webdriver.Window` (`driver.manage().window()`):
|
|
156
|
+
- Added
|
|
157
|
+
- getRect
|
|
158
|
+
- setRect
|
|
159
|
+
- fullscreen
|
|
160
|
+
- minimize
|
|
161
|
+
- Removed (use the getRect/setRect methods)
|
|
162
|
+
- getPosition
|
|
163
|
+
- setPosition
|
|
164
|
+
- getSize
|
|
165
|
+
- setSize
|
|
166
|
+
* Removed the `testing/assert` module
|
|
167
|
+
* Changes to `testing/index`
|
|
168
|
+
- Since the promise manager has been removed, it is no longer necessary to
|
|
169
|
+
wrap the Mocha test hooks; instead, users can simply use async functions.
|
|
170
|
+
The following have all been removed:
|
|
171
|
+
- describe
|
|
172
|
+
- before
|
|
173
|
+
- beforeEach
|
|
174
|
+
- after
|
|
175
|
+
- afterEach
|
|
176
|
+
- it
|
|
177
|
+
- Added the `suite` function. For details, refer to the jsdoc or
|
|
178
|
+
`example/google_search_test.js`
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
|
|
1
182
|
## v3.6.0
|
|
2
183
|
|
|
3
184
|
### Bug Fixes
|
package/README.md
CHANGED
|
@@ -11,11 +11,11 @@ Selenium may be installed via npm with
|
|
|
11
11
|
npm install selenium-webdriver
|
|
12
12
|
|
|
13
13
|
You will need to download additional components to work with each of the major
|
|
14
|
-
browsers. The drivers for Chrome, Firefox,
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
browsers. The drivers for Chrome, Firefox, and Microsoft's IE and Edge web
|
|
15
|
+
browsers are all standalone executables that should be placed on your system
|
|
16
|
+
[PATH]. Apple's safaridriver is shipped with Safari 10 for OS X El Capitan and
|
|
17
|
+
macOS Sierra. You will need to enable Remote Automation in the Develop menu of
|
|
18
|
+
Safari 10 before testing.
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
| Browser | Component |
|
|
@@ -24,8 +24,6 @@ Automation in the Develop menu of Safari 10 before testing.
|
|
|
24
24
|
| Internet Explorer | [IEDriverServer.exe][release] |
|
|
25
25
|
| Edge | [MicrosoftWebDriver.msi][edge] |
|
|
26
26
|
| Firefox | [geckodriver(.exe)][geckodriver] |
|
|
27
|
-
| PhantomJS | [phantomjs(.exe)][phantomjs] |
|
|
28
|
-
| Opera | [operadriver(.exe)][opera] |
|
|
29
27
|
| Safari | [safaridriver] |
|
|
30
28
|
|
|
31
29
|
## Usage
|
|
@@ -35,14 +33,16 @@ also find the tests for selenium-webdriver informative.
|
|
|
35
33
|
|
|
36
34
|
const {Builder, By, Key, until} = require('selenium-webdriver');
|
|
37
35
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
36
|
+
(async function example() {
|
|
37
|
+
let driver = await new Builder().forBrowser('firefox').build();
|
|
38
|
+
try {
|
|
39
|
+
await driver.get('http://www.google.com/ncr');
|
|
40
|
+
await driver.findElement(By.name('q'));.sendKeys('webdriver', Key.RETURN);
|
|
41
|
+
await driver.wait(until.titleIs('webdriver - Google Search'), 1000);
|
|
42
|
+
} finally {
|
|
43
|
+
await driver.quit();
|
|
44
|
+
}
|
|
45
|
+
})();
|
|
46
46
|
|
|
47
47
|
### Using the Builder API
|
|
48
48
|
|
|
@@ -51,11 +51,11 @@ instances. Rather than clutter your code with branches for the various browsers,
|
|
|
51
51
|
the builder lets you set all options in one flow. When you call
|
|
52
52
|
`Builder#build()`, all options irrelevant to the selected browser are dropped:
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
const webdriver = require('selenium-webdriver');
|
|
55
|
+
const chrome = require('selenium-webdriver/chrome');
|
|
56
|
+
const firefox = require('selenium-webdriver/firefox');
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
let driver = new webdriver.Builder()
|
|
59
59
|
.forBrowser('firefox')
|
|
60
60
|
.setChromeOptions(/* ... */)
|
|
61
61
|
.setFirefoxOptions(/* ... */)
|
|
@@ -92,7 +92,7 @@ server with
|
|
|
92
92
|
You may configure your tests to run against a remote server through the Builder
|
|
93
93
|
API:
|
|
94
94
|
|
|
95
|
-
|
|
95
|
+
let driver = new webdriver.Builder()
|
|
96
96
|
.forBrowser('firefox')
|
|
97
97
|
.usingServer('http://localhost:4444/wd/hub')
|
|
98
98
|
.build();
|
|
@@ -162,11 +162,11 @@ months, the support window for selenium-webdriver will be roughly:
|
|
|
162
162
|
|
|
163
163
|
| Date | LTS | Stable |
|
|
164
164
|
| --------- | ---: | -----: |
|
|
165
|
-
| (current) |
|
|
166
|
-
|
|
|
167
|
-
|
|
|
168
|
-
|
|
|
169
|
-
|
|
|
165
|
+
| (current) | 8.9 | 9.0 |
|
|
166
|
+
| 2018-04 | 8.x | 10.0 |
|
|
167
|
+
| 2018-10 | 10.x | 11.0 |
|
|
168
|
+
| 2019-04 | 10.x | 12.0 |
|
|
169
|
+
| 2019-10 | 12.x | 13.0 |
|
|
170
170
|
|
|
171
171
|
## Issues
|
|
172
172
|
|
|
@@ -216,8 +216,6 @@ under the License.
|
|
|
216
216
|
[chrome]: http://chromedriver.storage.googleapis.com/index.html
|
|
217
217
|
[gh]: https://github.com/SeleniumHQ/selenium/
|
|
218
218
|
[issues]: https://github.com/SeleniumHQ/selenium/issues
|
|
219
|
-
[opera]: https://github.com/operasoftware/operachromiumdriver/releases
|
|
220
|
-
[phantomjs]: http://phantomjs.org/
|
|
221
219
|
[edge]: http://go.microsoft.com/fwlink/?LinkId=619687
|
|
222
220
|
[geckodriver]: https://github.com/mozilla/geckodriver/releases/
|
|
223
221
|
[reduction]: http://www.webkit.org/quality/reduction.html
|
package/chrome.js
CHANGED
|
@@ -133,8 +133,9 @@ const util = require('util');
|
|
|
133
133
|
|
|
134
134
|
const http = require('./http');
|
|
135
135
|
const io = require('./io');
|
|
136
|
-
const {Capabilities, Capability} = require('./lib/capabilities');
|
|
136
|
+
const {Browser, Capabilities, Capability} = require('./lib/capabilities');
|
|
137
137
|
const command = require('./lib/command');
|
|
138
|
+
const error = require('./lib/error');
|
|
138
139
|
const logging = require('./lib/logging');
|
|
139
140
|
const promise = require('./lib/promise');
|
|
140
141
|
const Symbols = require('./lib/symbols');
|
|
@@ -159,7 +160,8 @@ const CHROMEDRIVER_EXE =
|
|
|
159
160
|
const Command = {
|
|
160
161
|
LAUNCH_APP: 'launchApp',
|
|
161
162
|
GET_NETWORK_CONDITIONS: 'getNetworkConditions',
|
|
162
|
-
SET_NETWORK_CONDITIONS: 'setNetworkConditions'
|
|
163
|
+
SET_NETWORK_CONDITIONS: 'setNetworkConditions',
|
|
164
|
+
SEND_DEVTOOLS_COMMAND: 'sendDevToolsCommand',
|
|
163
165
|
};
|
|
164
166
|
|
|
165
167
|
|
|
@@ -193,6 +195,21 @@ function configureExecutor(executor) {
|
|
|
193
195
|
Command.SET_NETWORK_CONDITIONS,
|
|
194
196
|
'POST',
|
|
195
197
|
'/session/:sessionId/chromium/network_conditions');
|
|
198
|
+
executor.defineCommand(
|
|
199
|
+
Command.SEND_DEVTOOLS_COMMAND,
|
|
200
|
+
'POST',
|
|
201
|
+
'/session/:sessionId/chromium/send_command');
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* _Synchronously_ attempts to locate the chromedriver executable on the current
|
|
207
|
+
* system.
|
|
208
|
+
*
|
|
209
|
+
* @return {?string} the located executable, or `null`.
|
|
210
|
+
*/
|
|
211
|
+
function locateSynchronously() {
|
|
212
|
+
return io.findInPath(CHROMEDRIVER_EXE, true);
|
|
196
213
|
}
|
|
197
214
|
|
|
198
215
|
|
|
@@ -210,7 +227,7 @@ class ServiceBuilder extends remote.DriverService.Builder {
|
|
|
210
227
|
* cannot be found on the PATH.
|
|
211
228
|
*/
|
|
212
229
|
constructor(opt_exe) {
|
|
213
|
-
let exe = opt_exe ||
|
|
230
|
+
let exe = opt_exe || locateSynchronously();
|
|
214
231
|
if (!exe) {
|
|
215
232
|
throw Error(
|
|
216
233
|
'The ChromeDriver could not be found on the current PATH. Please ' +
|
|
@@ -313,58 +330,19 @@ const OPTIONS_CAPABILITY_KEY = 'chromeOptions';
|
|
|
313
330
|
/**
|
|
314
331
|
* Class for managing ChromeDriver specific options.
|
|
315
332
|
*/
|
|
316
|
-
class Options {
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
/** @private {?logging.Preferences} */
|
|
325
|
-
this.logPrefs_ = null;
|
|
326
|
-
|
|
327
|
-
/** @private {?./lib/capabilities.ProxyConfig} */
|
|
328
|
-
this.proxy_ = null;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
/**
|
|
332
|
-
* Extracts the ChromeDriver specific options from the given capabilities
|
|
333
|
-
* object.
|
|
334
|
-
* @param {!Capabilities} caps The capabilities object.
|
|
335
|
-
* @return {!Options} The ChromeDriver options.
|
|
336
|
-
*/
|
|
337
|
-
static fromCapabilities(caps) {
|
|
338
|
-
let options = new Options();
|
|
339
|
-
|
|
340
|
-
let o = caps.get(OPTIONS_CAPABILITY_KEY);
|
|
341
|
-
if (o instanceof Options) {
|
|
342
|
-
options = o;
|
|
343
|
-
} else if (o) {
|
|
344
|
-
options.
|
|
345
|
-
addArguments(o.args || []).
|
|
346
|
-
addExtensions(o.extensions || []).
|
|
347
|
-
detachDriver(o.detach).
|
|
348
|
-
excludeSwitches(o.excludeSwitches || []).
|
|
349
|
-
setChromeBinaryPath(o.binary).
|
|
350
|
-
setChromeLogFile(o.logPath).
|
|
351
|
-
setChromeMinidumpPath(o.minidumpPath).
|
|
352
|
-
setLocalState(o.localState).
|
|
353
|
-
setMobileEmulation(o.mobileEmulation).
|
|
354
|
-
setUserPreferences(o.prefs).
|
|
355
|
-
setPerfLoggingPrefs(o.perfLoggingPrefs);
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
if (caps.has(Capability.PROXY)) {
|
|
359
|
-
options.setProxy(caps.get(Capability.PROXY));
|
|
360
|
-
}
|
|
333
|
+
class Options extends Capabilities {
|
|
334
|
+
/**
|
|
335
|
+
* @param {(Capabilities|Map<string, ?>|Object)=} other Another set of
|
|
336
|
+
* capabilities to initialize this instance from.
|
|
337
|
+
*/
|
|
338
|
+
constructor(other = undefined) {
|
|
339
|
+
super(other);
|
|
361
340
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
caps.get(Capability.LOGGING_PREFS));
|
|
365
|
-
}
|
|
341
|
+
/** @private {!Object} */
|
|
342
|
+
this.options_ = this.get(OPTIONS_CAPABILITY_KEY) || {};
|
|
366
343
|
|
|
367
|
-
|
|
344
|
+
this.setBrowserName(Browser.CHROME);
|
|
345
|
+
this.set(OPTIONS_CAPABILITY_KEY, this.options_);
|
|
368
346
|
}
|
|
369
347
|
|
|
370
348
|
/**
|
|
@@ -391,6 +369,12 @@ class Options {
|
|
|
391
369
|
* > in Chrome 60. Users are encouraged to set an initial window size with
|
|
392
370
|
* > the {@link #windowSize windowSize({width, height})} option.
|
|
393
371
|
*
|
|
372
|
+
* > __NOTE__: For security, Chrome disables downloads by default when
|
|
373
|
+
* > in headless mode (to prevent sites from silently downloading files to
|
|
374
|
+
* > your machine). After creating a session, you may call
|
|
375
|
+
* > {@link ./chrome.Driver#setDownloadPath setDownloadPath} to re-enable
|
|
376
|
+
* > downloads, saving files in the specified directory.
|
|
377
|
+
*
|
|
394
378
|
* @return {!Options} A self reference.
|
|
395
379
|
*/
|
|
396
380
|
headless() {
|
|
@@ -442,7 +426,8 @@ class Options {
|
|
|
442
426
|
* @return {!Options} A self reference.
|
|
443
427
|
*/
|
|
444
428
|
addExtensions(...args) {
|
|
445
|
-
|
|
429
|
+
let current = this.options_.extensions || [];
|
|
430
|
+
this.options_.extensions = current.concat(...args);
|
|
446
431
|
return this;
|
|
447
432
|
}
|
|
448
433
|
|
|
@@ -486,16 +471,6 @@ class Options {
|
|
|
486
471
|
return this;
|
|
487
472
|
}
|
|
488
473
|
|
|
489
|
-
/**
|
|
490
|
-
* Sets the logging preferences for the new session.
|
|
491
|
-
* @param {!logging.Preferences} prefs The logging preferences.
|
|
492
|
-
* @return {!Options} A self reference.
|
|
493
|
-
*/
|
|
494
|
-
setLoggingPrefs(prefs) {
|
|
495
|
-
this.logPrefs_ = prefs;
|
|
496
|
-
return this;
|
|
497
|
-
}
|
|
498
|
-
|
|
499
474
|
/**
|
|
500
475
|
* Sets the performance logging preferences. Options include:
|
|
501
476
|
*
|
|
@@ -673,54 +648,25 @@ class Options {
|
|
|
673
648
|
return this;
|
|
674
649
|
}
|
|
675
650
|
|
|
676
|
-
/**
|
|
677
|
-
* Sets the proxy settings for the new session.
|
|
678
|
-
* @param {./lib/capabilities.ProxyConfig} proxy The proxy configuration to
|
|
679
|
-
* use.
|
|
680
|
-
* @return {!Options} A self reference.
|
|
681
|
-
*/
|
|
682
|
-
setProxy(proxy) {
|
|
683
|
-
this.proxy_ = proxy;
|
|
684
|
-
return this;
|
|
685
|
-
}
|
|
686
|
-
|
|
687
|
-
/**
|
|
688
|
-
* Converts this options instance to a {@link Capabilities} object.
|
|
689
|
-
* @param {Capabilities=} opt_capabilities The capabilities to merge
|
|
690
|
-
* these options into, if any.
|
|
691
|
-
* @return {!Capabilities} The capabilities.
|
|
692
|
-
*/
|
|
693
|
-
toCapabilities(opt_capabilities) {
|
|
694
|
-
let caps = opt_capabilities || Capabilities.chrome();
|
|
695
|
-
caps.
|
|
696
|
-
set(Capability.PROXY, this.proxy_).
|
|
697
|
-
set(Capability.LOGGING_PREFS, this.logPrefs_).
|
|
698
|
-
set(OPTIONS_CAPABILITY_KEY, this);
|
|
699
|
-
return caps;
|
|
700
|
-
}
|
|
701
|
-
|
|
702
651
|
/**
|
|
703
652
|
* Converts this instance to its JSON wire protocol representation. Note this
|
|
704
653
|
* function is an implementation not intended for general use.
|
|
654
|
+
*
|
|
705
655
|
* @return {!Object} The JSON wire protocol representation of this instance.
|
|
656
|
+
* @suppress {checkTypes} Suppress [] access on a struct.
|
|
706
657
|
*/
|
|
707
658
|
[Symbols.serialize]() {
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
return extension.toString('base64');
|
|
718
|
-
}
|
|
719
|
-
return io.read(/** @type {string} */(extension))
|
|
720
|
-
.then(buffer => buffer.toString('base64'));
|
|
721
|
-
});
|
|
659
|
+
if (this.options_.extensions && this.options_.extensions.length) {
|
|
660
|
+
this.options_.extensions =
|
|
661
|
+
this.options_.extensions.map(function(extension) {
|
|
662
|
+
if (Buffer.isBuffer(extension)) {
|
|
663
|
+
return extension.toString('base64');
|
|
664
|
+
}
|
|
665
|
+
return io.read(/** @type {string} */(extension))
|
|
666
|
+
.then(buffer => buffer.toString('base64'));
|
|
667
|
+
});
|
|
722
668
|
}
|
|
723
|
-
return
|
|
669
|
+
return super[Symbols.serialize]();
|
|
724
670
|
}
|
|
725
671
|
}
|
|
726
672
|
|
|
@@ -739,11 +685,9 @@ class Driver extends webdriver.WebDriver {
|
|
|
739
685
|
* for an externally managed endpoint. If neither is provided, the
|
|
740
686
|
* {@linkplain ##getDefaultService default service} will be used by
|
|
741
687
|
* default.
|
|
742
|
-
* @param {promise.ControlFlow=} opt_flow The control flow to use, or `null`
|
|
743
|
-
* to use the currently active flow.
|
|
744
688
|
* @return {!Driver} A new driver instance.
|
|
745
689
|
*/
|
|
746
|
-
static createSession(opt_config, opt_serviceExecutor
|
|
690
|
+
static createSession(opt_config, opt_serviceExecutor) {
|
|
747
691
|
let executor;
|
|
748
692
|
if (opt_serviceExecutor instanceof http.Executor) {
|
|
749
693
|
executor = opt_serviceExecutor;
|
|
@@ -753,12 +697,19 @@ class Driver extends webdriver.WebDriver {
|
|
|
753
697
|
executor = createExecutor(service.start());
|
|
754
698
|
}
|
|
755
699
|
|
|
756
|
-
let caps =
|
|
757
|
-
|
|
758
|
-
|
|
700
|
+
let caps = opt_config || Capabilities.chrome();
|
|
701
|
+
|
|
702
|
+
// W3C spec requires noProxy value to be an array of strings, but Chrome
|
|
703
|
+
// expects a single host as a string.
|
|
704
|
+
let proxy = caps.get(Capability.PROXY);
|
|
705
|
+
if (proxy && Array.isArray(proxy.noProxy)) {
|
|
706
|
+
proxy.noProxy = proxy.noProxy[0];
|
|
707
|
+
if (!proxy.noProxy) {
|
|
708
|
+
proxy.noProxy = undefined;
|
|
709
|
+
}
|
|
710
|
+
}
|
|
759
711
|
|
|
760
|
-
return /** @type {!Driver} */(
|
|
761
|
-
super.createSession(executor, caps, opt_flow));
|
|
712
|
+
return /** @type {!Driver} */(super.createSession(executor, caps));
|
|
762
713
|
}
|
|
763
714
|
|
|
764
715
|
/**
|
|
@@ -771,24 +722,21 @@ class Driver extends webdriver.WebDriver {
|
|
|
771
722
|
/**
|
|
772
723
|
* Schedules a command to launch Chrome App with given ID.
|
|
773
724
|
* @param {string} id ID of the App to launch.
|
|
774
|
-
* @return {!
|
|
725
|
+
* @return {!Promise<void>} A promise that will be resolved
|
|
775
726
|
* when app is launched.
|
|
776
727
|
*/
|
|
777
728
|
launchApp(id) {
|
|
778
|
-
return this.
|
|
779
|
-
new command.Command(Command.LAUNCH_APP).setParameter('id', id)
|
|
780
|
-
'Driver.launchApp()');
|
|
729
|
+
return this.execute(
|
|
730
|
+
new command.Command(Command.LAUNCH_APP).setParameter('id', id));
|
|
781
731
|
}
|
|
782
732
|
|
|
783
733
|
/**
|
|
784
734
|
* Schedules a command to get Chrome network emulation settings.
|
|
785
|
-
* @return {!
|
|
786
|
-
*
|
|
735
|
+
* @return {!Promise} A promise that will be resolved when network
|
|
736
|
+
* emulation settings are retrievied.
|
|
787
737
|
*/
|
|
788
738
|
getNetworkConditions() {
|
|
789
|
-
return this.
|
|
790
|
-
new command.Command(Command.GET_NETWORK_CONDITIONS),
|
|
791
|
-
'Driver.getNetworkConditions()');
|
|
739
|
+
return this.execute(new command.Command(Command.GET_NETWORK_CONDITIONS));
|
|
792
740
|
}
|
|
793
741
|
|
|
794
742
|
/**
|
|
@@ -804,17 +752,54 @@ class Driver extends webdriver.WebDriver {
|
|
|
804
752
|
* });
|
|
805
753
|
*
|
|
806
754
|
* @param {Object} spec Defines the network conditions to set
|
|
807
|
-
* @return {!
|
|
808
|
-
*
|
|
755
|
+
* @return {!Promise<void>} A promise that will be resolved when network
|
|
756
|
+
* emulation settings are set.
|
|
809
757
|
*/
|
|
810
758
|
setNetworkConditions(spec) {
|
|
811
759
|
if (!spec || typeof spec !== 'object') {
|
|
812
760
|
throw TypeError('setNetworkConditions called with non-network-conditions parameter');
|
|
813
761
|
}
|
|
762
|
+
return this.execute(
|
|
763
|
+
new command.Command(Command.SET_NETWORK_CONDITIONS)
|
|
764
|
+
.setParameter('network_conditions', spec));
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
/**
|
|
768
|
+
* Sends an arbitrary devtools command to the browser.
|
|
769
|
+
*
|
|
770
|
+
* @param {string} cmd The name of the command to send.
|
|
771
|
+
* @param {Object=} params The command parameters.
|
|
772
|
+
* @return {!Promise<void>} A promise that will be resolved when the command
|
|
773
|
+
* has finished.
|
|
774
|
+
* @see <https://chromedevtools.github.io/devtools-protocol/>
|
|
775
|
+
*/
|
|
776
|
+
sendDevToolsCommand(cmd, params = {}) {
|
|
777
|
+
return this.execute(
|
|
778
|
+
new command.Command(Command.SEND_DEVTOOLS_COMMAND)
|
|
779
|
+
.setParameter('cmd', cmd)
|
|
780
|
+
.setParameter('params', params));
|
|
781
|
+
}
|
|
814
782
|
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
783
|
+
/**
|
|
784
|
+
* Sends a DevTools command to change Chrome's download directory.
|
|
785
|
+
*
|
|
786
|
+
* @param {string} path The desired download directory.
|
|
787
|
+
* @return {!Promise<void>} A promise that will be resolved when the command
|
|
788
|
+
* has finished.
|
|
789
|
+
* @see #sendDevToolsCommand
|
|
790
|
+
*/
|
|
791
|
+
async setDownloadPath(path) {
|
|
792
|
+
if (!path || typeof path !== 'string') {
|
|
793
|
+
throw new error.InvalidArgumentError('invalid download path');
|
|
794
|
+
}
|
|
795
|
+
const stat = await io.stat(path);
|
|
796
|
+
if (!stat.isDirectory()) {
|
|
797
|
+
throw new error.InvalidArgumentError('not a directory: ' + path);
|
|
798
|
+
}
|
|
799
|
+
return this.sendDevToolsCommand('Page.setDownloadBehavior', {
|
|
800
|
+
'behavior': 'allow',
|
|
801
|
+
'downloadPath': path
|
|
802
|
+
});
|
|
818
803
|
}
|
|
819
804
|
}
|
|
820
805
|
|
|
@@ -827,3 +812,4 @@ exports.Options = Options;
|
|
|
827
812
|
exports.ServiceBuilder = ServiceBuilder;
|
|
828
813
|
exports.getDefaultService = getDefaultService;
|
|
829
814
|
exports.setDefaultService = setDefaultService;
|
|
815
|
+
exports.locateSynchronously = locateSynchronously;
|