// Licensed to the Software Freedom Conservancy (SFC) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The SFC licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. /** * @fileoverview Various HTTP utilities. */ 'use strict'; const Executor = require('./index').Executor, HttpClient = require('./index').HttpClient, HttpRequest = require('./index').Request, Command = require('../lib/command').Command, CommandName = require('../lib/command').Name, error = require('../lib/error'), promise = require('../lib/promise'); /** * Queries a WebDriver server for its current status. * @param {string} url Base URL of the server to query. * @return {!Promise} A promise that resolves with * a hash of the server status. */ function getStatus(url) { var client = new HttpClient(url); var executor = new Executor(client); var command = new Command(CommandName.GET_SERVER_STATUS); return executor.execute(command); } // PUBLIC API /** * Queries a WebDriver server for its current status. * @param {string} url Base URL of the server to query. * @return {!Promise} A promise that resolves with * a hash of the server status. */ exports.getStatus = getStatus; /** * Waits for a WebDriver server to be healthy and accepting requests. * @param {string} url Base URL of the server to query. * @param {number} timeout How long to wait for the server. * @param {Promise=} opt_cancelToken A promise used as a cancellation signal: * if resolved before the server is ready, the wait will be terminated * early with a {@link promise.CancellationError}. * @return {!Promise} A promise that will resolve when the server is ready, or * if the wait is cancelled. */ exports.waitForServer = function(url, timeout, opt_cancelToken) { return new Promise((onResolve, onReject) => { let start = Date.now(); let done = false; let resolve = (status) => { done = true; onResolve(status); }; let reject = (err) => { done = true; onReject(err); }; if (opt_cancelToken) { opt_cancelToken.then(_ => reject(new promise.CancellationError)); } checkServerStatus(); function checkServerStatus() { return getStatus(url).then(status => resolve(status), onError); } function onError(e) { // Some servers don't support the status command. If they are able to // response with an error, then can consider the server ready. if (e instanceof error.UnsupportedOperationError) { resolve({}); return; } if (Date.now() - start > timeout) { reject(Error('Timed out waiting for the WebDriver server at ' + url)); } else { setTimeout(function() { if (!done) { checkServerStatus(); } }, 50); } } }); }; /** * Polls a URL with GET requests until it returns a 2xx response or the * timeout expires. * @param {string} url The URL to poll. * @param {number} timeout How long to wait, in milliseconds. * @param {Promise=} opt_cancelToken A promise used as a cancellation signal: * if resolved before the a 2xx response is received, the wait will be * terminated early with a {@link promise.CancellationError}. * @return {!Promise} A promise that will resolve when a 2xx is received from * the given URL, or if the wait is cancelled. */ exports.waitForUrl = function(url, timeout, opt_cancelToken) { return new Promise((onResolve, onReject) => { let client = new HttpClient(url); let request = new HttpRequest('GET', ''); let start = Date.now(); let done = false; let resolve = () => { done = true; onResolve(); }; let reject = (err) => { done = true; onReject(err); }; if (opt_cancelToken) { opt_cancelToken.then(_ => reject(new promise.CancellationError)); } testUrl(); function testUrl() { client.send(request).then(onResponse, onError); } function onError() { if (Date.now() - start > timeout) { reject(Error('Timed out waiting for the URL to return 2xx: ' + url)); } else { setTimeout(function() { if (!done) { testUrl(); } }, 50); } } function onResponse(response) { if (done) { return; } if (response.status > 199 && response.status < 300) { resolve(); return; } onError(); } }); };