selenium-webdriver 4.0.0-alpha.5 → 4.0.0-beta.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 +35 -1
- package/LICENSE +1 -1
- package/NOTICE +1 -1
- package/README.md +4 -4
- package/chrome.js +72 -592
- package/chromium.js +829 -0
- package/devtools/CDPConnection.js +37 -0
- package/edge.js +124 -86
- package/example/chrome_android.js +16 -13
- package/example/chrome_mobile_emulation.js +18 -14
- package/example/firefox_channels.js +35 -28
- package/example/google_search.js +9 -9
- package/example/google_search_test.js +20 -22
- package/example/headless.js +27 -19
- package/example/logging.js +34 -38
- package/firefox.js +200 -200
- package/http/index.js +131 -115
- package/http/util.js +56 -64
- package/ie.js +180 -104
- package/index.js +246 -199
- package/io/exec.js +34 -39
- package/io/index.js +142 -152
- package/io/zip.js +75 -65
- package/lib/actions.js +140 -122
- package/lib/atoms/find-elements.js +124 -0
- package/lib/atoms/get-attribute.js +79 -59
- package/lib/atoms/is-displayed.js +72 -73
- package/lib/atoms/mutation-listener.js +38 -0
- package/lib/by.js +192 -65
- package/lib/capabilities.js +82 -78
- package/lib/command.js +20 -20
- package/lib/error.js +134 -168
- package/lib/http.js +337 -230
- package/lib/input.js +325 -302
- package/lib/logging.js +127 -138
- package/lib/promise.js +60 -66
- 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 +1024 -541
- package/net/index.js +30 -36
- package/net/portprober.js +31 -144
- package/opera.js +406 -0
- package/package.json +19 -12
- package/proxy.js +2 -2
- package/remote/index.js +190 -187
- package/safari.js +40 -49
- package/testing/index.js +166 -155
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,114 +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
|
|
186
|
+
|
|
187
|
+
// Update the protocol to avoid EPROTO errors when the webdriver proxy
|
|
188
|
+
// uses a different protocol from the remote selenium server.
|
|
189
|
+
options.protocol = opt_proxy.protocol
|
|
189
190
|
|
|
190
191
|
if (proxy.auth) {
|
|
191
192
|
options.headers['Proxy-Authorization'] =
|
|
192
|
-
|
|
193
|
+
'Basic ' + Buffer.from(proxy.auth).toString('base64')
|
|
193
194
|
}
|
|
194
195
|
}
|
|
195
196
|
|
|
196
|
-
let requestFn = options.protocol === 'https:' ? https.request : http.request
|
|
197
|
+
let requestFn = options.protocol === 'https:' ? https.request : http.request
|
|
197
198
|
var request = requestFn(options, function onResponse(response) {
|
|
198
199
|
if (response.statusCode == 302 || response.statusCode == 303) {
|
|
199
200
|
try {
|
|
200
|
-
|
|
201
|
+
// eslint-disable-next-line node/no-deprecated-api
|
|
202
|
+
var location = url.parse(response.headers['location'])
|
|
201
203
|
} catch (ex) {
|
|
202
|
-
onError(
|
|
204
|
+
onError(
|
|
205
|
+
Error(
|
|
203
206
|
'Failed to parse "Location" header for server redirect: ' +
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
+
ex.message +
|
|
208
|
+
'\nResponse was: \n' +
|
|
209
|
+
new httpLib.Response(response.statusCode, response.headers, '')
|
|
210
|
+
)
|
|
211
|
+
)
|
|
212
|
+
return
|
|
207
213
|
}
|
|
208
214
|
|
|
209
215
|
if (!location.hostname) {
|
|
210
|
-
location.hostname = hostname
|
|
211
|
-
location.port = port
|
|
216
|
+
location.hostname = hostname
|
|
217
|
+
location.port = port
|
|
218
|
+
location.auth = options.auth
|
|
212
219
|
}
|
|
213
220
|
|
|
214
|
-
request.abort()
|
|
215
|
-
sendRequest(
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
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
|
|
230
244
|
}
|
|
231
245
|
|
|
232
|
-
var body = []
|
|
233
|
-
response.on('data', body.push.bind(body))
|
|
234
|
-
response.on('end', function() {
|
|
246
|
+
var body = []
|
|
247
|
+
response.on('data', body.push.bind(body))
|
|
248
|
+
response.on('end', function () {
|
|
235
249
|
var resp = new httpLib.Response(
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
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) {
|
|
244
259
|
if (typeof opt_retries === 'undefined') {
|
|
245
|
-
opt_retries = 0
|
|
260
|
+
opt_retries = 0
|
|
246
261
|
}
|
|
247
262
|
|
|
248
263
|
if (shouldRetryRequest(opt_retries, e)) {
|
|
249
|
-
opt_retries += 1
|
|
250
|
-
setTimeout(function() {
|
|
251
|
-
sendRequest(options, onOk, onError, opt_data, opt_proxy, opt_retries)
|
|
252
|
-
}, 15)
|
|
264
|
+
opt_retries += 1
|
|
265
|
+
setTimeout(function () {
|
|
266
|
+
sendRequest(options, onOk, onError, opt_data, opt_proxy, opt_retries)
|
|
267
|
+
}, 15)
|
|
253
268
|
} else {
|
|
254
|
-
var message = e.message
|
|
269
|
+
var message = e.message
|
|
255
270
|
if (e.code) {
|
|
256
|
-
message = e.code + ' ' + message
|
|
271
|
+
message = e.code + ' ' + message
|
|
257
272
|
}
|
|
258
|
-
onError(new Error(message))
|
|
273
|
+
onError(new Error(message))
|
|
259
274
|
}
|
|
260
|
-
})
|
|
275
|
+
})
|
|
261
276
|
|
|
262
277
|
if (opt_data) {
|
|
263
|
-
request.write(opt_data)
|
|
278
|
+
request.write(opt_data)
|
|
264
279
|
}
|
|
265
280
|
|
|
266
|
-
request.end()
|
|
281
|
+
request.end()
|
|
267
282
|
}
|
|
268
283
|
|
|
269
|
-
|
|
270
|
-
const MAX_RETRIES = 3;
|
|
284
|
+
const MAX_RETRIES = 3
|
|
271
285
|
|
|
272
286
|
/**
|
|
273
287
|
* A retry is sometimes needed on Windows where we may quickly run out of
|
|
@@ -279,7 +293,7 @@ const MAX_RETRIES = 3;
|
|
|
279
293
|
* @return {boolean}
|
|
280
294
|
*/
|
|
281
295
|
function shouldRetryRequest(retries, err) {
|
|
282
|
-
return retries < MAX_RETRIES && isRetryableNetworkError(err)
|
|
296
|
+
return retries < MAX_RETRIES && isRetryableNetworkError(err)
|
|
283
297
|
}
|
|
284
298
|
|
|
285
299
|
/**
|
|
@@ -288,21 +302,23 @@ function shouldRetryRequest(retries, err) {
|
|
|
288
302
|
*/
|
|
289
303
|
function isRetryableNetworkError(err) {
|
|
290
304
|
if (err && err.code) {
|
|
291
|
-
return
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
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
|
+
)
|
|
296
313
|
}
|
|
297
314
|
|
|
298
|
-
return false
|
|
315
|
+
return false
|
|
299
316
|
}
|
|
300
317
|
|
|
301
|
-
|
|
302
318
|
// PUBLIC API
|
|
303
319
|
|
|
304
|
-
exports.Agent = http.Agent
|
|
305
|
-
exports.Executor = httpLib.Executor
|
|
306
|
-
exports.HttpClient = HttpClient
|
|
307
|
-
exports.Request = httpLib.Request
|
|
308
|
-
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
|
+
}
|