Skip to content

Commit

Permalink
[js] Reduce the API on promise.Thenable for compatibility with native…
Browse files Browse the repository at this point in the history
… Promises.

#2969
  • Loading branch information
jleyba committed Nov 2, 2016
1 parent ce01bba commit 7194756
Show file tree
Hide file tree
Showing 14 changed files with 338 additions and 266 deletions.
4 changes: 4 additions & 0 deletions javascript/node/selenium-webdriver/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
### API Changes

* Removed `safari.Options#useLegacyDriver()`
* Reduced the API on `promise.Thenable` for compatibility with native promises:
- Removed `#isPending()`
- Removed `#cancel()`
- Removed `#finally()`


## v3.0.0-beta-3
Expand Down
7 changes: 3 additions & 4 deletions javascript/node/selenium-webdriver/edge.js
Original file line number Diff line number Diff line change
Expand Up @@ -278,11 +278,10 @@ class Driver extends webdriver.WebDriver {
var driver = webdriver.WebDriver.createSession(executor, caps, opt_flow);
super(driver.getSession(), executor, driver.controlFlow());

var boundQuit = this.quit.bind(this);

/** @override */
this.quit = function() {
return boundQuit().finally(service.kill.bind(service));
this.quit = () => {
return /** @type {!promise.Thenable} */(
promise.finally(super.quit(), service.kill.bind(service)));
};
}

Expand Down
3 changes: 2 additions & 1 deletion javascript/node/selenium-webdriver/firefox/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -622,7 +622,8 @@ class Driver extends webdriver.WebDriver {

/** @override */
this.quit = () => {
return super.quit().finally(spec.onQuit);
return /** @type {!promise.Thenable} */(
promise.finally(super.quit(), spec.onQuit));
};
}

Expand Down
154 changes: 95 additions & 59 deletions javascript/node/selenium-webdriver/http/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,38 +61,54 @@ 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.
* @return {!promise.Promise} A promise that will resolve when the
* server is ready.
* @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) {
var ready = promise.defer(),
start = Date.now();
checkServerStatus();
return ready.promise;

function checkServerStatus() {
return getStatus(url).then(status => ready.fulfill(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) {
ready.fulfill();
return;
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));
}

if (Date.now() - start > timeout) {
ready.reject(
Error('Timed out waiting for the WebDriver server at ' + url));
} else {
setTimeout(function() {
if (ready.promise.isPending()) {
checkServerStatus();
}
}, 50);
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);
}
}
});
};


Expand All @@ -101,39 +117,59 @@ exports.waitForServer = function(url, timeout) {
* timeout expires.
* @param {string} url The URL to poll.
* @param {number} timeout How long to wait, in milliseconds.
* @return {!promise.Promise} A promise that will resolve when the
* URL responds with 2xx.
* @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) {
var client = new HttpClient(url),
request = new HttpRequest('GET', ''),
ready = promise.defer(),
start = Date.now();
testUrl();
return ready.promise;

function testUrl() {
client.send(request).then(onResponse, onError);
}

function onError() {
if (Date.now() - start > timeout) {
ready.reject(Error(
'Timed out waiting for the URL to return 2xx: ' + url));
} else {
setTimeout(function() {
if (ready.promise.isPending()) {
testUrl();
}
}, 50);
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 (!ready.promise.isPending()) return;
if (response.status > 199 && response.status < 300) {
return ready.fulfill();
function onResponse(response) {
if (done) {
return;
}
if (response.status > 199 && response.status < 300) {
resolve();
return;
}
onError();
}
onError();
}
});
};
7 changes: 3 additions & 4 deletions javascript/node/selenium-webdriver/ie.js
Original file line number Diff line number Diff line change
Expand Up @@ -420,11 +420,10 @@ class Driver extends webdriver.WebDriver {

super(driver.getSession(), executor, driver.controlFlow());

let boundQuit = this.quit.bind(this);

/** @override */
this.quit = function() {
return boundQuit().finally(service.kill.bind(service));
this.quit = () => {
return /** @type {!promise.Thenable} */(
promise.finally(super.quit(), service.kill.bind(service)));
};
}

Expand Down
Loading

0 comments on commit 7194756

Please sign in to comment.