UNPKG

5.1 kBJavaScriptView Raw
1// Licensed to the Software Freedom Conservancy (SFC) under one
2// or more contributor license agreements. See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership. The SFC licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License. You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied. See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18/**
19 * @fileoverview Various HTTP utilities.
20 */
21
22'use strict'
23
24const Executor = require('./index').Executor,
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')
30
31/**
32 * Queries a WebDriver server for its current status.
33 * @param {string} url Base URL of the server to query.
34 * @return {!Promise<!Object>} A promise that resolves with
35 * a hash of the server status.
36 */
37function getStatus(url) {
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)
42}
43
44class CancellationError {}
45
46// PUBLIC API
47
48/**
49 * Queries a WebDriver server for its current status.
50 * @param {string} url Base URL of the server to query.
51 * @return {!Promise<!Object>} A promise that resolves with
52 * a hash of the server status.
53 */
54exports.getStatus = getStatus
55
56exports.CancellationError = CancellationError
57
58/**
59 * Waits for a WebDriver server to be healthy and accepting requests.
60 * @param {string} url Base URL of the server to query.
61 * @param {number} timeout How long to wait for the server.
62 * @param {Promise=} opt_cancelToken A promise used as a cancellation signal:
63 * if resolved before the server is ready, the wait will be terminated
64 * early with a {@link CancellationError}.
65 * @return {!Promise} A promise that will resolve when the server is ready, or
66 * if the wait is cancelled.
67 */
68exports.waitForServer = function (url, timeout, opt_cancelToken) {
69 return new Promise((onResolve, onReject) => {
70 let start = Date.now()
71
72 let done = false
73 let resolve = (status) => {
74 done = true
75 onResolve(status)
76 }
77 let reject = (err) => {
78 done = true
79 onReject(err)
80 }
81
82 if (opt_cancelToken) {
83 opt_cancelToken.then((_) => reject(new CancellationError()))
84 }
85
86 checkServerStatus()
87 function checkServerStatus() {
88 return getStatus(url).then((status) => resolve(status), onError)
89 }
90
91 function onError(e) {
92 // Some servers don't support the status command. If they are able to
93 // response with an error, then can consider the server ready.
94 if (e instanceof error.UnsupportedOperationError) {
95 resolve({})
96 return
97 }
98
99 if (Date.now() - start > timeout) {
100 reject(Error('Timed out waiting for the WebDriver server at ' + url))
101 } else {
102 setTimeout(function () {
103 if (!done) {
104 checkServerStatus()
105 }
106 }, 50)
107 }
108 }
109 })
110}
111
112/**
113 * Polls a URL with GET requests until it returns a 2xx response or the
114 * timeout expires.
115 * @param {string} url The URL to poll.
116 * @param {number} timeout How long to wait, in milliseconds.
117 * @param {Promise=} opt_cancelToken A promise used as a cancellation signal:
118 * if resolved before the a 2xx response is received, the wait will be
119 * terminated early with a {@link CancellationError}.
120 * @return {!Promise} A promise that will resolve when a 2xx is received from
121 * the given URL, or if the wait is cancelled.
122 */
123exports.waitForUrl = function (url, timeout, opt_cancelToken) {
124 return new Promise((onResolve, onReject) => {
125 let client = new HttpClient(url)
126 let request = new HttpRequest('GET', '')
127 let start = Date.now()
128
129 let done = false
130 let resolve = () => {
131 done = true
132 onResolve()
133 }
134 let reject = (err) => {
135 done = true
136 onReject(err)
137 }
138
139 if (opt_cancelToken) {
140 opt_cancelToken.then((_) => reject(new CancellationError()))
141 }
142
143 testUrl()
144
145 function testUrl() {
146 client.send(request).then(onResponse, onError)
147 }
148
149 function onError() {
150 if (Date.now() - start > timeout) {
151 reject(Error('Timed out waiting for the URL to return 2xx: ' + url))
152 } else {
153 setTimeout(function () {
154 if (!done) {
155 testUrl()
156 }
157 }, 50)
158 }
159 }
160
161 function onResponse(response) {
162 if (done) {
163 return
164 }
165 if (response.status > 199 && response.status < 300) {
166 resolve()
167 return
168 }
169 onError()
170 }
171 })
172}