Skip to content

Commit

Permalink
[js] The http.Executor class now accepts a promised client. The build…
Browse files Browse the repository at this point in the history
…er will now

use this instead of command.DeferredExecutor when creating WebDriver instances,
so http.Executors.prototype.defineCommand is exposed for users to define
additional commands.

The executors module and command.DeferredExecutor class are no longer used
anywhere, so they have been removed.
  • Loading branch information
jleyba committed Aug 6, 2016
1 parent 7e144bb commit dcaf7b2
Show file tree
Hide file tree
Showing 12 changed files with 96 additions and 124 deletions.
12 changes: 10 additions & 2 deletions javascript/node/selenium-webdriver/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
* Fixed timeouts' URL
* Properly send HTTP requests when using a WebDriver server proxy
* Properly configure proxies when using the geckodriver
* `http.Executor` now accepts a promised client. The `builder.Builder` class
will now use this over a `command.DeferredExecutor` when creating WebDriver
instances.

### API Changes

Expand All @@ -21,13 +24,18 @@
* When adding cookies, the desired expiry must be provided as a Date or in
_seconds_ since epoch. When retrieving cookies, the expiration is always
returned in seconds.
* Renamed `firefox.Options#useMarionette` to `firefox.Options#useGeckoDriver`
* Renamed `firefox.Options#useMarionette` to `firefox.Options#useGeckoDriver`
* Removed deprecated modules:
- `selenium-webdriver/error` (use `selenium-webdriver/lib/error`,\
or the `error` property exported by `selenium-webdriver`)
- `selenium-webdriver/executors` — this was not previously deprecated, but
is no longer used.
* Removed deprecated types:
- `command.DeferredExecutor` — this was not previously deprecated, but is no
longer used. It can be trivially implemented by clients should it be
needed.
- `error.InvalidSessionIdError` (use `error.NoSuchSessionError`)
- `executors.DeferredExecutor` (use `command.DeferredExecutor`)
- `executors.DeferredExecutor`
- `until.Condition` (use `webdriver.Condition`)
- `until.WebElementCondition` (use `webdriver.WebElementCondition`)
- `webdriver.UnhandledAlertError` (use `error.UnexpectedAlertOpenError`)
Expand Down
6 changes: 4 additions & 2 deletions javascript/node/selenium-webdriver/builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@

const chrome = require('./chrome');
const edge = require('./edge');
const executors = require('./executors');
const firefox = require('./firefox');
const _http = require('./http');
const ie = require('./ie');
const capabilities = require('./lib/capabilities');
const webdriver = require('./lib/webdriver');
Expand Down Expand Up @@ -483,7 +483,9 @@ class Builder {
}

if (url) {
var executor = executors.createExecutor(url, this.agent_, this.proxy_);
let client = Promise.resolve(url)
.then(url => new _http.HttpClient(url, this.agent_, this.proxy_));
let executor = new _http.Executor(client);
return WebDriver.createSession(executor, capabilities, this.flow_);
}

Expand Down
17 changes: 7 additions & 10 deletions javascript/node/selenium-webdriver/chrome.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,7 @@
const fs = require('fs'),
util = require('util');

const executors = require('./executors'),
http = require('./http'),
const http = require('./http'),
io = require('./io'),
Capabilities = require('./lib/capabilities').Capabilities,
Capability = require('./lib/capabilities').Capability,
Expand Down Expand Up @@ -155,14 +154,12 @@ const Command = {
* @return {!command.Executor} The new command executor.
*/
function createExecutor(url) {
return new command.DeferredExecutor(url.then(url => {
let client = new http.HttpClient(url);
let executor = new http.Executor(client);
executor.defineCommand(
Command.LAUNCH_APP,
'POST', '/session/:sessionId/chromium/launch_app');
return executor;
}));
let client = url.then(url => new http.HttpClient(url));
let executor = new http.Executor(client);
executor.defineCommand(
Command.LAUNCH_APP,
'POST', '/session/:sessionId/chromium/launch_app');
return executor;
}


Expand Down
5 changes: 3 additions & 2 deletions javascript/node/selenium-webdriver/edge.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
const fs = require('fs'),
util = require('util');

const executors = require('./executors'),
const http = require('./http'),
io = require('./io'),
capabilities = require('./lib/capabilities'),
promise = require('./lib/promise'),
Expand Down Expand Up @@ -342,7 +342,8 @@ class Driver extends webdriver.WebDriver {
*/
constructor(opt_config, opt_service, opt_flow) {
var service = opt_service || getDefaultService();
var executor = executors.createExecutor(service.start());
var client = service.start().then(url => new http.HttpClient(url));
var executor = new http.Executor(client);

var caps =
opt_config instanceof Options ? opt_config.toCapabilities() :
Expand Down
49 changes: 0 additions & 49 deletions javascript/node/selenium-webdriver/executors.js

This file was deleted.

33 changes: 15 additions & 18 deletions javascript/node/selenium-webdriver/firefox/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ const url = require('url');
const Binary = require('./binary').Binary,
Profile = require('./profile').Profile,
decodeProfile = require('./profile').decode,
executors = require('../executors'),
http = require('../http'),
httpUtil = require('../http/util'),
io = require('../io'),
Expand Down Expand Up @@ -393,25 +392,23 @@ const ExtensionCommand = {

/**
* Creates a command executor with support for Marionette's custom commands.
* @param {!Promise<string>} url The server's URL.
* @param {!Promise<string>} serverUrl The server's URL.
* @return {!command.Executor} The new command executor.
*/
function createExecutor(url) {
return new command.DeferredExecutor(url.then(url => {
let client = new http.HttpClient(url);
let executor = new http.Executor(client);

executor.defineCommand(
ExtensionCommand.GET_CONTEXT,
'GET',
'/session/:sessionId/moz/context');
executor.defineCommand(
ExtensionCommand.SET_CONTEXT,
'POST',
'/session/:sessionId/moz/context');

return executor;
}));
function createExecutor(serverUrl) {
let client = serverUrl.then(url => new http.HttpClient(url));
let executor = new http.Executor(client);

executor.defineCommand(
ExtensionCommand.GET_CONTEXT,
'GET',
'/session/:sessionId/moz/context');
executor.defineCommand(
ExtensionCommand.SET_CONTEXT,
'POST',
'/session/:sessionId/moz/context');

return executor;
}

/**
Expand Down
5 changes: 3 additions & 2 deletions javascript/node/selenium-webdriver/ie.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
const fs = require('fs'),
util = require('util');

const executors = require('./executors'),
const http = require('./http'),
io = require('./io'),
capabilities = require('./lib/capabilities'),
promise = require('./lib/promise'),
Expand Down Expand Up @@ -414,7 +414,8 @@ class Driver extends webdriver.WebDriver {
(opt_config || capabilities.Capabilities.ie());

var service = createServiceFromCapabilities(caps);
var executor = executors.createExecutor(service.start());
var client = service.start().then(url => new http.HttpClient(url));
var executor = new http.Executor(client);
var driver = webdriver.WebDriver.createSession(executor, caps, opt_flow);

super(driver.getSession(), executor, driver.controlFlow());
Expand Down
23 changes: 1 addition & 22 deletions javascript/node/selenium-webdriver/lib/command.js
Original file line number Diff line number Diff line change
Expand Up @@ -232,33 +232,12 @@ class Executor {
}


/**
* Wraps a promised {@link Executor}, ensuring no commands are executed until
* the wrapped executor has been fully resolved.
* @implements {Executor}
*/
class DeferredExecutor {
/**
* @param {!Promise<Executor>} delegate The promised delegate, which
* may be provided by any promise-like thenable object.
*/
constructor(delegate) {

/** @override */
this.execute = function(command) {
return delegate.then(executor => executor.execute(command));
};
}
}



// PUBLIC API


module.exports = {
Command: Command,
Name: Name,
Executor: Executor,
DeferredExecutor: DeferredExecutor
Executor: Executor
};
34 changes: 29 additions & 5 deletions javascript/node/selenium-webdriver/lib/http.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
const cmd = require('./command');
const error = require('./error');
const logging = require('./logging');
const promise = require('./promise');
const Session = require('./session').Session;
const WebElement = require('./webdriver').WebElement;

Expand Down Expand Up @@ -222,6 +223,29 @@ class Client {
}


const CLIENTS =
/** !WeakMap<!Executor, !(Client|IThenable<!Client>)> */new WeakMap;


/**
* Sends a request using the given executor.
* @param {!Executor} executor
* @param {!Request} request
* @return {!Promise<Response>}
*/
function doSend(executor, request) {
const client = CLIENTS.get(executor);
if (promise.isPromise(client)) {
return client.then(client => {
CLIENTS.set(executor, client);
return client.send(request);
});
} else {
return client.send(request);
}
}


/**
* A command executor that communicates with the server using JSON over HTTP.
*
Expand All @@ -237,12 +261,12 @@ class Client {
*/
class Executor {
/**
* @param {!Client} client The client to use for sending requests to the
* server.
* @param {!(Client|IThenable<!Client>)} client The client to use for sending
* requests to the server, or a promise-like object that will resolve to
* to the client.
*/
constructor(client) {
/** @private {!Client} */
this.client_ = client;
CLIENTS.set(this, client);

/**
* Whether this executor should use the W3C wire protocol. The executor
Expand Down Expand Up @@ -297,7 +321,7 @@ class Executor {

let log = this.log_;
log.finer(() => '>>>\n' + request);
return this.client_.send(request).then(response => {
return doSend(this, request).then(response => {
log.finer(() => '<<<\n' + response);

let parsed =
Expand Down
5 changes: 3 additions & 2 deletions javascript/node/selenium-webdriver/opera.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@

const fs = require('fs');

const executors = require('./executors'),
const http = require('./http'),
io = require('./io'),
capabilities = require('./lib/capabilities'),
promise = require('./lib/promise'),
Expand Down Expand Up @@ -436,7 +436,8 @@ class Driver extends webdriver.WebDriver {
*/
constructor(opt_config, opt_service, opt_flow) {
var service = opt_service || getDefaultService();
var executor = executors.createExecutor(service.start());
var client = service.start().then(url => new http.HttpClient(url));
var executor = new http.Executor(client);

var caps =
opt_config instanceof Options ? opt_config.toCapabilities() :
Expand Down
17 changes: 7 additions & 10 deletions javascript/node/selenium-webdriver/phantomjs.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@

const fs = require('fs');

const executors = require('./executors'),
http = require('./http'),
const http = require('./http'),
io = require('./io'),
capabilities = require('./lib/capabilities'),
command = require('./lib/command'),
Expand Down Expand Up @@ -134,16 +133,14 @@ const WEBDRIVER_TO_PHANTOMJS_LEVEL = new Map([
* @return {!command.Executor} The new command executor.
*/
function createExecutor(url) {
return new command.DeferredExecutor(url.then(url => {
var client = new http.HttpClient(url);
var executor = new http.Executor(client);
let client = url.then(url => new http.HttpClient(url));
let executor = new http.Executor(client);

executor.defineCommand(
Command.EXECUTE_PHANTOM_SCRIPT,
'POST', '/session/:sessionId/phantom/execute');
executor.defineCommand(
Command.EXECUTE_PHANTOM_SCRIPT,
'POST', '/session/:sessionId/phantom/execute');

return executor;
}));
return executor;
}

/**
Expand Down
14 changes: 14 additions & 0 deletions javascript/node/selenium-webdriver/test/lib/http_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,20 @@ describe('http', function() {
});
});

it('accepts promised http clients', function() {
executor = new http.Executor(Promise.resolve(client));

var resp = JSON.stringify({sessionId: 'abc123'});
send.returns(Promise.resolve(new http.Response(200, {}, resp)));

let command = new Command(CommandName.NEW_SESSION);
return executor.execute(command).then(response => {
assertSent(
'POST', '/session', {},
[['Accept', 'application/json; charset=utf-8']]);
});
});

function entries(map) {
let entries = [];
for (let e of map.entries()) {
Expand Down

0 comments on commit dcaf7b2

Please sign in to comment.