selenium-webdriver 4.0.0-alpha.7 → 4.0.0-beta.3
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 +56 -0
- package/LICENSE +202 -0
- package/NOTICE +2 -0
- package/README.md +2 -0
- package/chrome.js +69 -79
- package/chromium.js +231 -164
- package/{lib/atoms/make-atoms-module.js → devtools/CDPConnection.js} +15 -9
- package/edge.js +104 -146
- package/example/chrome_android.js +45 -0
- package/example/chrome_mobile_emulation.js +46 -0
- package/example/firefox_channels.js +84 -0
- package/example/google_search.js +50 -0
- package/example/google_search_test.js +70 -0
- package/example/headless.js +63 -0
- package/example/logging.js +64 -0
- package/firefox.js +199 -200
- package/http/index.js +128 -116
- package/http/util.js +56 -64
- package/ie.js +180 -104
- package/index.js +246 -199
- package/io/exec.js +35 -40
- package/io/index.js +146 -157
- package/io/zip.js +75 -66
- package/lib/atoms/find-elements.js +123 -0
- package/lib/atoms/get-attribute.js +75 -59
- package/lib/atoms/is-displayed.js +72 -72
- package/lib/atoms/mutation-listener.js +55 -0
- package/lib/by.js +192 -65
- package/lib/capabilities.js +76 -86
- package/lib/command.js +19 -35
- package/lib/error.js +134 -168
- package/lib/http.js +308 -232
- package/lib/input.js +192 -453
- package/lib/logging.js +126 -137
- package/lib/promise.js +53 -71
- package/lib/proxy.js +31 -41
- package/lib/session.js +12 -15
- package/lib/symbols.js +3 -4
- package/lib/until.js +162 -160
- package/lib/webdriver.js +1014 -549
- package/net/index.js +30 -36
- package/net/portprober.js +30 -143
- package/opera.js +406 -0
- package/package.json +15 -7
- package/proxy.js +2 -2
- package/remote/index.js +189 -187
- package/safari.js +40 -49
- package/testing/index.js +504 -0
- package/lib/README +0 -5
- package/lib/actions.js +0 -609
package/http/index.js
CHANGED
|
@@ -20,14 +20,13 @@
|
|
|
20
20
|
* communicates with a remote end using HTTP + JSON.
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
|
-
'use strict'
|
|
23
|
+
'use strict'
|
|
24
24
|
|
|
25
|
-
const http = require('http')
|
|
26
|
-
const https = require('https')
|
|
27
|
-
const url = require('url')
|
|
28
|
-
|
|
29
|
-
const httpLib = require('../lib/http');
|
|
25
|
+
const http = require('http')
|
|
26
|
+
const https = require('https')
|
|
27
|
+
const url = require('url')
|
|
30
28
|
|
|
29
|
+
const httpLib = require('../lib/http')
|
|
31
30
|
|
|
32
31
|
/**
|
|
33
32
|
* @typedef {{protocol: (?string|undefined),
|
|
@@ -38,8 +37,7 @@ const httpLib = require('../lib/http');
|
|
|
38
37
|
* path: (?string|undefined),
|
|
39
38
|
* pathname: (?string|undefined)}}
|
|
40
39
|
*/
|
|
41
|
-
var RequestOptions
|
|
42
|
-
|
|
40
|
+
var RequestOptions // eslint-disable-line
|
|
43
41
|
|
|
44
42
|
/**
|
|
45
43
|
* @param {string} aUrl The request URL to parse.
|
|
@@ -47,26 +45,25 @@ var RequestOptions;
|
|
|
47
45
|
* @throws {Error} if the URL does not include a hostname.
|
|
48
46
|
*/
|
|
49
47
|
function getRequestOptions(aUrl) {
|
|
50
|
-
|
|
48
|
+
//eslint-disable-next-line node/no-deprecated-api
|
|
49
|
+
let options = url.parse(aUrl)
|
|
51
50
|
if (!options.hostname) {
|
|
52
|
-
throw new Error('Invalid URL: ' + aUrl)
|
|
51
|
+
throw new Error('Invalid URL: ' + aUrl)
|
|
53
52
|
}
|
|
54
53
|
// Delete the search and has portions as they are not used.
|
|
55
|
-
options.search = null
|
|
56
|
-
options.hash = null
|
|
57
|
-
options.path = options.pathname
|
|
58
|
-
return options
|
|
54
|
+
options.search = null
|
|
55
|
+
options.hash = null
|
|
56
|
+
options.path = options.pathname
|
|
57
|
+
return options
|
|
59
58
|
}
|
|
60
59
|
|
|
61
|
-
|
|
62
60
|
/** @const {string} */
|
|
63
|
-
const USER_AGENT = (function() {
|
|
64
|
-
const version = require('../package.json').version
|
|
61
|
+
const USER_AGENT = (function () {
|
|
62
|
+
const version = require('../package.json').version
|
|
65
63
|
const platform =
|
|
66
|
-
|
|
67
|
-
return `selenium/${version} (js ${platform})
|
|
68
|
-
})()
|
|
69
|
-
|
|
64
|
+
{ darwin: 'mac', win32: 'windows' }[process.platform] || 'linux'
|
|
65
|
+
return `selenium/${version} (js ${platform})`
|
|
66
|
+
})()
|
|
70
67
|
|
|
71
68
|
/**
|
|
72
69
|
* A basic HTTP client used to send messages to a remote end.
|
|
@@ -83,47 +80,48 @@ class HttpClient {
|
|
|
83
80
|
*/
|
|
84
81
|
constructor(serverUrl, opt_agent, opt_proxy) {
|
|
85
82
|
/** @private {http.Agent} */
|
|
86
|
-
this.agent_ = opt_agent || null
|
|
83
|
+
this.agent_ = opt_agent || null
|
|
87
84
|
|
|
88
85
|
/**
|
|
89
86
|
* Base options for each request.
|
|
90
87
|
* @private {RequestOptions}
|
|
91
88
|
*/
|
|
92
|
-
this.options_ = getRequestOptions(serverUrl)
|
|
89
|
+
this.options_ = getRequestOptions(serverUrl)
|
|
93
90
|
|
|
94
91
|
/**
|
|
95
92
|
* @private {?RequestOptions}
|
|
96
93
|
*/
|
|
97
|
-
this.proxyOptions_ = opt_proxy ? getRequestOptions(opt_proxy) : null
|
|
94
|
+
this.proxyOptions_ = opt_proxy ? getRequestOptions(opt_proxy) : null
|
|
98
95
|
}
|
|
99
96
|
|
|
100
97
|
/** @override */
|
|
101
98
|
send(httpRequest) {
|
|
102
|
-
let data
|
|
99
|
+
let data
|
|
103
100
|
|
|
104
|
-
let headers = {}
|
|
101
|
+
let headers = {}
|
|
105
102
|
|
|
106
103
|
if (httpRequest.headers) {
|
|
107
|
-
httpRequest.headers.forEach(function(value, name) {
|
|
108
|
-
headers[name] = value
|
|
109
|
-
})
|
|
104
|
+
httpRequest.headers.forEach(function (value, name) {
|
|
105
|
+
headers[name] = value
|
|
106
|
+
})
|
|
110
107
|
}
|
|
111
108
|
|
|
112
|
-
headers['User-Agent'] = USER_AGENT
|
|
113
|
-
headers['Content-Length'] = 0
|
|
109
|
+
headers['User-Agent'] = USER_AGENT
|
|
110
|
+
headers['Content-Length'] = 0
|
|
114
111
|
if (httpRequest.method == 'POST' || httpRequest.method == 'PUT') {
|
|
115
|
-
data = JSON.stringify(httpRequest.data)
|
|
116
|
-
headers['Content-Length'] = Buffer.byteLength(data, 'utf8')
|
|
117
|
-
headers['Content-Type'] = 'application/json;charset=UTF-8'
|
|
112
|
+
data = JSON.stringify(httpRequest.data)
|
|
113
|
+
headers['Content-Length'] = Buffer.byteLength(data, 'utf8')
|
|
114
|
+
headers['Content-Type'] = 'application/json;charset=UTF-8'
|
|
118
115
|
}
|
|
119
116
|
|
|
120
|
-
let path = this.options_.path
|
|
117
|
+
let path = this.options_.path
|
|
121
118
|
if (path.endsWith('/') && httpRequest.path.startsWith('/')) {
|
|
122
|
-
path += httpRequest.path.substring(1)
|
|
119
|
+
path += httpRequest.path.substring(1)
|
|
123
120
|
} else {
|
|
124
|
-
path += httpRequest.path
|
|
121
|
+
path += httpRequest.path
|
|
125
122
|
}
|
|
126
|
-
|
|
123
|
+
//eslint-disable-next-line node/no-deprecated-api
|
|
124
|
+
let parsedPath = url.parse(path)
|
|
127
125
|
|
|
128
126
|
let options = {
|
|
129
127
|
agent: this.agent_ || null,
|
|
@@ -140,15 +138,14 @@ class HttpClient {
|
|
|
140
138
|
hash: parsedPath.hash,
|
|
141
139
|
|
|
142
140
|
headers,
|
|
143
|
-
}
|
|
141
|
+
}
|
|
144
142
|
|
|
145
143
|
return new Promise((fulfill, reject) => {
|
|
146
|
-
sendRequest(options, fulfill, reject, data, this.proxyOptions_)
|
|
147
|
-
})
|
|
144
|
+
sendRequest(options, fulfill, reject, data, this.proxyOptions_)
|
|
145
|
+
})
|
|
148
146
|
}
|
|
149
147
|
}
|
|
150
148
|
|
|
151
|
-
|
|
152
149
|
/**
|
|
153
150
|
* Sends a single HTTP request.
|
|
154
151
|
* @param {!Object} options The request options.
|
|
@@ -160,118 +157,131 @@ class HttpClient {
|
|
|
160
157
|
* @param {number=} opt_retries The current number of retries.
|
|
161
158
|
*/
|
|
162
159
|
function sendRequest(options, onOk, onError, opt_data, opt_proxy, opt_retries) {
|
|
163
|
-
var hostname = options.hostname
|
|
164
|
-
var port = options.port
|
|
160
|
+
var hostname = options.hostname
|
|
161
|
+
var port = options.port
|
|
165
162
|
|
|
166
163
|
if (opt_proxy) {
|
|
167
|
-
let proxy = /** @type {RequestOptions} */(opt_proxy)
|
|
164
|
+
let proxy = /** @type {RequestOptions} */ (opt_proxy)
|
|
168
165
|
|
|
169
166
|
// RFC 2616, section 5.1.2:
|
|
170
167
|
// The absoluteURI form is REQUIRED when the request is being made to a
|
|
171
168
|
// proxy.
|
|
172
|
-
let absoluteUri = url.format(options)
|
|
169
|
+
let absoluteUri = url.format(options)
|
|
173
170
|
|
|
174
171
|
// RFC 2616, section 14.23:
|
|
175
172
|
// An HTTP/1.1 proxy MUST ensure that any request message it forwards does
|
|
176
173
|
// contain an appropriate Host header field that identifies the service
|
|
177
174
|
// being requested by the proxy.
|
|
178
|
-
let targetHost = options.hostname
|
|
175
|
+
let targetHost = options.hostname
|
|
179
176
|
if (options.port) {
|
|
180
|
-
targetHost += ':' + options.port
|
|
177
|
+
targetHost += ':' + options.port
|
|
181
178
|
}
|
|
182
179
|
|
|
183
180
|
// Update the request options with our proxy info.
|
|
184
|
-
options.headers['Host'] = targetHost
|
|
185
|
-
options.path = absoluteUri
|
|
186
|
-
options.host = proxy.host
|
|
187
|
-
options.hostname = proxy.hostname
|
|
188
|
-
options.port = proxy.port
|
|
181
|
+
options.headers['Host'] = targetHost
|
|
182
|
+
options.path = absoluteUri
|
|
183
|
+
options.host = proxy.host
|
|
184
|
+
options.hostname = proxy.hostname
|
|
185
|
+
options.port = proxy.port
|
|
189
186
|
|
|
190
187
|
// Update the protocol to avoid EPROTO errors when the webdriver proxy
|
|
191
188
|
// uses a different protocol from the remote selenium server.
|
|
192
|
-
options.protocol = opt_proxy.protocol
|
|
189
|
+
options.protocol = opt_proxy.protocol
|
|
193
190
|
|
|
194
191
|
if (proxy.auth) {
|
|
195
192
|
options.headers['Proxy-Authorization'] =
|
|
196
|
-
|
|
193
|
+
'Basic ' + Buffer.from(proxy.auth).toString('base64')
|
|
197
194
|
}
|
|
198
195
|
}
|
|
199
196
|
|
|
200
|
-
let requestFn = options.protocol === 'https:' ? https.request : http.request
|
|
197
|
+
let requestFn = options.protocol === 'https:' ? https.request : http.request
|
|
201
198
|
var request = requestFn(options, function onResponse(response) {
|
|
202
199
|
if (response.statusCode == 302 || response.statusCode == 303) {
|
|
203
200
|
try {
|
|
204
|
-
|
|
201
|
+
// eslint-disable-next-line node/no-deprecated-api
|
|
202
|
+
var location = url.parse(response.headers['location'])
|
|
205
203
|
} catch (ex) {
|
|
206
|
-
onError(
|
|
204
|
+
onError(
|
|
205
|
+
Error(
|
|
207
206
|
'Failed to parse "Location" header for server redirect: ' +
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
207
|
+
ex.message +
|
|
208
|
+
'\nResponse was: \n' +
|
|
209
|
+
new httpLib.Response(response.statusCode, response.headers, '')
|
|
210
|
+
)
|
|
211
|
+
)
|
|
212
|
+
return
|
|
211
213
|
}
|
|
212
214
|
|
|
213
215
|
if (!location.hostname) {
|
|
214
|
-
location.hostname = hostname
|
|
215
|
-
location.port = port
|
|
216
|
+
location.hostname = hostname
|
|
217
|
+
location.port = port
|
|
218
|
+
location.auth = options.auth
|
|
216
219
|
}
|
|
217
220
|
|
|
218
|
-
request.abort()
|
|
219
|
-
sendRequest(
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
221
|
+
request.abort()
|
|
222
|
+
sendRequest(
|
|
223
|
+
{
|
|
224
|
+
method: 'GET',
|
|
225
|
+
protocol: location.protocol || options.protocol,
|
|
226
|
+
hostname: location.hostname,
|
|
227
|
+
port: location.port,
|
|
228
|
+
path: location.path,
|
|
229
|
+
auth: location.auth,
|
|
230
|
+
pathname: location.pathname,
|
|
231
|
+
search: location.search,
|
|
232
|
+
hash: location.hash,
|
|
233
|
+
headers: {
|
|
234
|
+
Accept: 'application/json; charset=utf-8',
|
|
235
|
+
'User-Agent': USER_AGENT,
|
|
236
|
+
},
|
|
237
|
+
},
|
|
238
|
+
onOk,
|
|
239
|
+
onError,
|
|
240
|
+
undefined,
|
|
241
|
+
opt_proxy
|
|
242
|
+
)
|
|
243
|
+
return
|
|
234
244
|
}
|
|
235
245
|
|
|
236
|
-
var body = []
|
|
237
|
-
response.on('data', body.push.bind(body))
|
|
238
|
-
response.on('end', function() {
|
|
246
|
+
var body = []
|
|
247
|
+
response.on('data', body.push.bind(body))
|
|
248
|
+
response.on('end', function () {
|
|
239
249
|
var resp = new httpLib.Response(
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
250
|
+
/** @type {number} */ (response.statusCode),
|
|
251
|
+
/** @type {!Object<string>} */ (response.headers),
|
|
252
|
+
Buffer.concat(body).toString('utf8').replace(/\0/g, '')
|
|
253
|
+
)
|
|
254
|
+
onOk(resp)
|
|
255
|
+
})
|
|
256
|
+
})
|
|
257
|
+
|
|
258
|
+
request.on('error', function (e) {
|
|
248
259
|
if (typeof opt_retries === 'undefined') {
|
|
249
|
-
opt_retries = 0
|
|
260
|
+
opt_retries = 0
|
|
250
261
|
}
|
|
251
262
|
|
|
252
263
|
if (shouldRetryRequest(opt_retries, e)) {
|
|
253
|
-
opt_retries += 1
|
|
254
|
-
setTimeout(function() {
|
|
255
|
-
sendRequest(options, onOk, onError, opt_data, opt_proxy, opt_retries)
|
|
256
|
-
}, 15)
|
|
264
|
+
opt_retries += 1
|
|
265
|
+
setTimeout(function () {
|
|
266
|
+
sendRequest(options, onOk, onError, opt_data, opt_proxy, opt_retries)
|
|
267
|
+
}, 15)
|
|
257
268
|
} else {
|
|
258
|
-
var message = e.message
|
|
269
|
+
var message = e.message
|
|
259
270
|
if (e.code) {
|
|
260
|
-
message = e.code + ' ' + message
|
|
271
|
+
message = e.code + ' ' + message
|
|
261
272
|
}
|
|
262
|
-
onError(new Error(message))
|
|
273
|
+
onError(new Error(message))
|
|
263
274
|
}
|
|
264
|
-
})
|
|
275
|
+
})
|
|
265
276
|
|
|
266
277
|
if (opt_data) {
|
|
267
|
-
request.write(opt_data)
|
|
278
|
+
request.write(opt_data)
|
|
268
279
|
}
|
|
269
280
|
|
|
270
|
-
request.end()
|
|
281
|
+
request.end()
|
|
271
282
|
}
|
|
272
283
|
|
|
273
|
-
|
|
274
|
-
const MAX_RETRIES = 3;
|
|
284
|
+
const MAX_RETRIES = 3
|
|
275
285
|
|
|
276
286
|
/**
|
|
277
287
|
* A retry is sometimes needed on Windows where we may quickly run out of
|
|
@@ -283,7 +293,7 @@ const MAX_RETRIES = 3;
|
|
|
283
293
|
* @return {boolean}
|
|
284
294
|
*/
|
|
285
295
|
function shouldRetryRequest(retries, err) {
|
|
286
|
-
return retries < MAX_RETRIES && isRetryableNetworkError(err)
|
|
296
|
+
return retries < MAX_RETRIES && isRetryableNetworkError(err)
|
|
287
297
|
}
|
|
288
298
|
|
|
289
299
|
/**
|
|
@@ -292,21 +302,23 @@ function shouldRetryRequest(retries, err) {
|
|
|
292
302
|
*/
|
|
293
303
|
function isRetryableNetworkError(err) {
|
|
294
304
|
if (err && err.code) {
|
|
295
|
-
return
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
305
|
+
return (
|
|
306
|
+
err.code === 'ECONNABORTED' ||
|
|
307
|
+
err.code === 'ECONNRESET' ||
|
|
308
|
+
err.code === 'ECONNREFUSED' ||
|
|
309
|
+
err.code === 'EADDRINUSE' ||
|
|
310
|
+
err.code === 'EPIPE' ||
|
|
311
|
+
err.code === 'ETIMEDOUT'
|
|
312
|
+
)
|
|
300
313
|
}
|
|
301
314
|
|
|
302
|
-
return false
|
|
315
|
+
return false
|
|
303
316
|
}
|
|
304
317
|
|
|
305
|
-
|
|
306
318
|
// PUBLIC API
|
|
307
319
|
|
|
308
|
-
exports.Agent = http.Agent
|
|
309
|
-
exports.Executor = httpLib.Executor
|
|
310
|
-
exports.HttpClient = HttpClient
|
|
311
|
-
exports.Request = httpLib.Request
|
|
312
|
-
exports.Response = httpLib.Response
|
|
320
|
+
exports.Agent = http.Agent
|
|
321
|
+
exports.Executor = httpLib.Executor
|
|
322
|
+
exports.HttpClient = HttpClient
|
|
323
|
+
exports.Request = httpLib.Request
|
|
324
|
+
exports.Response = httpLib.Response
|
package/http/util.js
CHANGED
|
@@ -19,16 +19,14 @@
|
|
|
19
19
|
* @fileoverview Various HTTP utilities.
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
-
'use strict'
|
|
22
|
+
'use strict'
|
|
23
23
|
|
|
24
24
|
const Executor = require('./index').Executor,
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
25
|
+
HttpClient = require('./index').HttpClient,
|
|
26
|
+
HttpRequest = require('./index').Request,
|
|
27
|
+
Command = require('../lib/command').Command,
|
|
28
|
+
CommandName = require('../lib/command').Name,
|
|
29
|
+
error = require('../lib/error')
|
|
32
30
|
|
|
33
31
|
/**
|
|
34
32
|
* Queries a WebDriver server for its current status.
|
|
@@ -37,30 +35,25 @@ const Executor = require('./index').Executor,
|
|
|
37
35
|
* a hash of the server status.
|
|
38
36
|
*/
|
|
39
37
|
function getStatus(url) {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
return executor.execute(command)
|
|
38
|
+
const client = new HttpClient(url)
|
|
39
|
+
const executor = new Executor(client)
|
|
40
|
+
const command = new Command(CommandName.GET_SERVER_STATUS)
|
|
41
|
+
return executor.execute(command)
|
|
44
42
|
}
|
|
45
43
|
|
|
46
|
-
|
|
47
44
|
class CancellationError {}
|
|
48
45
|
|
|
49
|
-
|
|
50
46
|
// PUBLIC API
|
|
51
47
|
|
|
52
|
-
|
|
53
48
|
/**
|
|
54
49
|
* Queries a WebDriver server for its current status.
|
|
55
50
|
* @param {string} url Base URL of the server to query.
|
|
56
51
|
* @return {!Promise<!Object>} A promise that resolves with
|
|
57
52
|
* a hash of the server status.
|
|
58
53
|
*/
|
|
59
|
-
exports.getStatus = getStatus
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
exports.CancellationError = CancellationError;
|
|
54
|
+
exports.getStatus = getStatus
|
|
63
55
|
|
|
56
|
+
exports.CancellationError = CancellationError
|
|
64
57
|
|
|
65
58
|
/**
|
|
66
59
|
* Waits for a WebDriver server to be healthy and accepting requests.
|
|
@@ -72,50 +65,49 @@ exports.CancellationError = CancellationError;
|
|
|
72
65
|
* @return {!Promise} A promise that will resolve when the server is ready, or
|
|
73
66
|
* if the wait is cancelled.
|
|
74
67
|
*/
|
|
75
|
-
exports.waitForServer = function(url, timeout, opt_cancelToken) {
|
|
68
|
+
exports.waitForServer = function (url, timeout, opt_cancelToken) {
|
|
76
69
|
return new Promise((onResolve, onReject) => {
|
|
77
|
-
let start = Date.now()
|
|
70
|
+
let start = Date.now()
|
|
78
71
|
|
|
79
|
-
let done = false
|
|
72
|
+
let done = false
|
|
80
73
|
let resolve = (status) => {
|
|
81
|
-
done = true
|
|
82
|
-
onResolve(status)
|
|
83
|
-
}
|
|
74
|
+
done = true
|
|
75
|
+
onResolve(status)
|
|
76
|
+
}
|
|
84
77
|
let reject = (err) => {
|
|
85
|
-
done = true
|
|
86
|
-
onReject(err)
|
|
87
|
-
}
|
|
78
|
+
done = true
|
|
79
|
+
onReject(err)
|
|
80
|
+
}
|
|
88
81
|
|
|
89
82
|
if (opt_cancelToken) {
|
|
90
|
-
opt_cancelToken.then(_ => reject(new CancellationError))
|
|
83
|
+
opt_cancelToken.then((_) => reject(new CancellationError()))
|
|
91
84
|
}
|
|
92
85
|
|
|
93
|
-
checkServerStatus()
|
|
86
|
+
checkServerStatus()
|
|
94
87
|
function checkServerStatus() {
|
|
95
|
-
return getStatus(url).then(status => resolve(status), onError)
|
|
88
|
+
return getStatus(url).then((status) => resolve(status), onError)
|
|
96
89
|
}
|
|
97
90
|
|
|
98
91
|
function onError(e) {
|
|
99
92
|
// Some servers don't support the status command. If they are able to
|
|
100
93
|
// response with an error, then can consider the server ready.
|
|
101
94
|
if (e instanceof error.UnsupportedOperationError) {
|
|
102
|
-
resolve({})
|
|
103
|
-
return
|
|
95
|
+
resolve({})
|
|
96
|
+
return
|
|
104
97
|
}
|
|
105
98
|
|
|
106
99
|
if (Date.now() - start > timeout) {
|
|
107
|
-
reject(Error('Timed out waiting for the WebDriver server at ' + url))
|
|
100
|
+
reject(Error('Timed out waiting for the WebDriver server at ' + url))
|
|
108
101
|
} else {
|
|
109
|
-
setTimeout(function() {
|
|
102
|
+
setTimeout(function () {
|
|
110
103
|
if (!done) {
|
|
111
|
-
checkServerStatus()
|
|
104
|
+
checkServerStatus()
|
|
112
105
|
}
|
|
113
|
-
}, 50)
|
|
106
|
+
}, 50)
|
|
114
107
|
}
|
|
115
108
|
}
|
|
116
|
-
})
|
|
117
|
-
}
|
|
118
|
-
|
|
109
|
+
})
|
|
110
|
+
}
|
|
119
111
|
|
|
120
112
|
/**
|
|
121
113
|
* Polls a URL with GET requests until it returns a 2xx response or the
|
|
@@ -128,53 +120,53 @@ exports.waitForServer = function(url, timeout, opt_cancelToken) {
|
|
|
128
120
|
* @return {!Promise} A promise that will resolve when a 2xx is received from
|
|
129
121
|
* the given URL, or if the wait is cancelled.
|
|
130
122
|
*/
|
|
131
|
-
exports.waitForUrl = function(url, timeout, opt_cancelToken) {
|
|
123
|
+
exports.waitForUrl = function (url, timeout, opt_cancelToken) {
|
|
132
124
|
return new Promise((onResolve, onReject) => {
|
|
133
|
-
let client = new HttpClient(url)
|
|
134
|
-
let request = new HttpRequest('GET', '')
|
|
135
|
-
let start = Date.now()
|
|
125
|
+
let client = new HttpClient(url)
|
|
126
|
+
let request = new HttpRequest('GET', '')
|
|
127
|
+
let start = Date.now()
|
|
136
128
|
|
|
137
|
-
let done = false
|
|
129
|
+
let done = false
|
|
138
130
|
let resolve = () => {
|
|
139
|
-
done = true
|
|
140
|
-
onResolve()
|
|
141
|
-
}
|
|
131
|
+
done = true
|
|
132
|
+
onResolve()
|
|
133
|
+
}
|
|
142
134
|
let reject = (err) => {
|
|
143
|
-
done = true
|
|
144
|
-
onReject(err)
|
|
145
|
-
}
|
|
135
|
+
done = true
|
|
136
|
+
onReject(err)
|
|
137
|
+
}
|
|
146
138
|
|
|
147
139
|
if (opt_cancelToken) {
|
|
148
|
-
opt_cancelToken.then(_ => reject(new CancellationError))
|
|
140
|
+
opt_cancelToken.then((_) => reject(new CancellationError()))
|
|
149
141
|
}
|
|
150
142
|
|
|
151
|
-
testUrl()
|
|
143
|
+
testUrl()
|
|
152
144
|
|
|
153
145
|
function testUrl() {
|
|
154
|
-
client.send(request).then(onResponse, onError)
|
|
146
|
+
client.send(request).then(onResponse, onError)
|
|
155
147
|
}
|
|
156
148
|
|
|
157
149
|
function onError() {
|
|
158
150
|
if (Date.now() - start > timeout) {
|
|
159
|
-
reject(Error('Timed out waiting for the URL to return 2xx: ' + url))
|
|
151
|
+
reject(Error('Timed out waiting for the URL to return 2xx: ' + url))
|
|
160
152
|
} else {
|
|
161
|
-
setTimeout(function() {
|
|
153
|
+
setTimeout(function () {
|
|
162
154
|
if (!done) {
|
|
163
|
-
testUrl()
|
|
155
|
+
testUrl()
|
|
164
156
|
}
|
|
165
|
-
}, 50)
|
|
157
|
+
}, 50)
|
|
166
158
|
}
|
|
167
159
|
}
|
|
168
160
|
|
|
169
161
|
function onResponse(response) {
|
|
170
162
|
if (done) {
|
|
171
|
-
return
|
|
163
|
+
return
|
|
172
164
|
}
|
|
173
165
|
if (response.status > 199 && response.status < 300) {
|
|
174
|
-
resolve()
|
|
175
|
-
return
|
|
166
|
+
resolve()
|
|
167
|
+
return
|
|
176
168
|
}
|
|
177
|
-
onError()
|
|
169
|
+
onError()
|
|
178
170
|
}
|
|
179
|
-
})
|
|
180
|
-
}
|
|
171
|
+
})
|
|
172
|
+
}
|