1 | // Copyright 2013 Selenium committers |
2 | // Copyright 2013 Software Freedom Conservancy |
3 | // |
4 | // Licensed under the Apache License, Version 2.0 (the "License"); |
5 | // you may not use this file except in compliance with the License. |
6 | // You may obtain a copy of the License at |
7 | // |
8 | // http://www.apache.org/licenses/LICENSE-2.0 |
9 | // |
10 | // Unless required by applicable law or agreed to in writing, software |
11 | // distributed under the License is distributed on an "AS IS" BASIS, |
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | // See the License for the specific language governing permissions and |
14 | // limitations under the License. |
15 | |
16 | /** |
17 | * @fileoverview Various HTTP utilities. |
18 | */ |
19 | |
20 | var base = require('../_base'), |
21 | HttpClient = require('./index').HttpClient, |
22 | checkResponse = base.require('bot.response').checkResponse, |
23 | Executor = base.require('webdriver.http.Executor'), |
24 | HttpRequest = base.require('webdriver.http.Request'), |
25 | Command = base.require('webdriver.Command'), |
26 | CommandName = base.require('webdriver.CommandName'), |
27 | promise = base.require('webdriver.promise'); |
28 | |
29 | |
30 | |
31 | /** |
32 | * Queries a WebDriver server for its current status. |
33 | * @param {string} url Base URL of the server to query. |
34 | * @param {function(Error, *=)} callback The function to call with the |
35 | * response. |
36 | */ |
37 | function getStatus(url, callback) { |
38 | var client = new HttpClient(url); |
39 | var executor = new Executor(client); |
40 | var command = new Command(CommandName.GET_SERVER_STATUS); |
41 | executor.execute(command, function(err, responseObj) { |
42 | if (err) return callback(err); |
43 | try { |
44 | checkResponse(responseObj); |
45 | } catch (ex) { |
46 | return callback(ex); |
47 | } |
48 | callback(null, responseObj['value']); |
49 | }); |
50 | } |
51 | |
52 | |
53 | // PUBLIC API |
54 | |
55 | |
56 | /** |
57 | * Queries a WebDriver server for its current status. |
58 | * @param {string} url Base URL of the server to query. |
59 | * @return {!webdriver.promise.Promise.<!Object>} A promise that resolves with |
60 | * a hash of the server status. |
61 | */ |
62 | exports.getStatus = function(url) { |
63 | return promise.checkedNodeCall(getStatus.bind(null, url)); |
64 | }; |
65 | |
66 | |
67 | /** |
68 | * Waits for a WebDriver server to be healthy and accepting requests. |
69 | * @param {string} url Base URL of the server to query. |
70 | * @param {number} timeout How long to wait for the server. |
71 | * @return {!webdriver.promise.Promise} A promise that will resolve when the |
72 | * server is ready. |
73 | */ |
74 | exports.waitForServer = function(url, timeout) { |
75 | var ready = promise.defer(), |
76 | start = Date.now(), |
77 | checkServerStatus = getStatus.bind(null, url, onResponse); |
78 | checkServerStatus(); |
79 | return ready.promise; |
80 | |
81 | function onResponse(err) { |
82 | if (!ready.isPending()) return; |
83 | if (!err) return ready.fulfill(); |
84 | |
85 | if (Date.now() - start > timeout) { |
86 | ready.reject( |
87 | Error('Timed out waiting for the WebDriver server at ' + url)); |
88 | } else { |
89 | setTimeout(function() { |
90 | if (ready.isPending()) { |
91 | checkServerStatus(); |
92 | } |
93 | }, 50); |
94 | } |
95 | } |
96 | }; |
97 | |
98 | |
99 | /** |
100 | * Polls a URL with GET requests until it returns a 2xx response or the |
101 | * timeout expires. |
102 | * @param {string} url The URL to poll. |
103 | * @param {number} timeout How long to wait, in milliseconds. |
104 | * @return {!webdriver.promise.Promise} A promise that will resolve when the |
105 | * URL responds with 2xx. |
106 | */ |
107 | exports.waitForUrl = function(url, timeout) { |
108 | var client = new HttpClient(url), |
109 | request = new HttpRequest('GET', ''), |
110 | testUrl = client.send.bind(client, request, onResponse), |
111 | ready = promise.defer(), |
112 | start = Date.now(); |
113 | testUrl(); |
114 | return ready.promise; |
115 | |
116 | function onResponse(err, response) { |
117 | if (!ready.isPending()) return; |
118 | if (!err && response.status > 199 && response.status < 300) { |
119 | return ready.fulfill(); |
120 | } |
121 | |
122 | if (Date.now() - start > timeout) { |
123 | ready.reject(Error( |
124 | 'Timed out waiting for the URL to return 2xx: ' + url)); |
125 | } else { |
126 | setTimeout(function() { |
127 | if (ready.isPending()) { |
128 | testUrl(); |
129 | } |
130 | }, 50); |
131 | } |
132 | } |
133 | }; |