selenium-webdriver
Version:
The official WebDriver JavaScript bindings from the Selenium project
1,737 lines (1,399 loc) • 67.6 kB
JavaScript
// Copyright 2014 Software Freedom Conservancy. All Rights Reserved.
//
// Licensed 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.
goog.require('bot.ErrorCode');
goog.require('goog.Promise');
goog.require('goog.functions');
goog.require('goog.json');
goog.require('goog.testing.PropertyReplacer');
goog.require('goog.testing.MockControl');
goog.require('goog.testing.jsunit');
goog.require('goog.userAgent');
goog.require('webdriver.Capabilities');
goog.require('webdriver.Command');
goog.require('webdriver.CommandExecutor');
goog.require('webdriver.CommandName');
goog.require('webdriver.FileDetector');
goog.require('webdriver.WebDriver');
goog.require('webdriver.Serializable');
goog.require('webdriver.Session');
goog.require('webdriver.logging');
goog.require('webdriver.promise');
goog.require('webdriver.promise.ControlFlow');
goog.require('webdriver.promise.Deferred');
goog.require('webdriver.promise.Promise');
goog.require('webdriver.test.testutil');
var SESSION_ID = 'test_session_id';
var STUB_DRIVER = {
controlFlow: goog.nullFunction
};
// Alias some long names that interfere with test readability.
var CName = webdriver.CommandName,
ECode = bot.ErrorCode,
StubError = webdriver.test.testutil.StubError,
throwStubError = webdriver.test.testutil.throwStubError,
assertIsStubError = webdriver.test.testutil.assertIsStubError;
// By is exported by webdriver.By, but IDEs don't recognize
// goog.exportSymbol. Explicitly define it here to make the
// IDE stop complaining.
var By = webdriver.By;
var driver;
var flow;
var mockControl;
var uncaughtExceptions;
function shouldRunTests() {
return !goog.userAgent.IE || goog.userAgent.isVersionOrHigher(10);
}
function setUp() {
mockControl = new goog.testing.MockControl();
flow = webdriver.promise.controlFlow();
uncaughtExceptions = [];
flow.on('uncaughtException', onUncaughtException);
}
function tearDown() {
return waitForIdle(flow).then(function() {
mockControl.$verifyAll();
mockControl.$tearDown();
assertArrayEquals('There were uncaught exceptions',
[], uncaughtExceptions);
flow.reset();
});
}
function onUncaughtException(e) {
uncaughtExceptions.push(e);
}
function waitForIdle(opt_flow) {
var theFlow = opt_flow || flow;
return new goog.Promise(function(fulfill, reject) {
if (!theFlow.activeFrame_ && !theFlow.yieldCount_) {
fulfill();
return;
}
theFlow.once('idle', fulfill);
theFlow.once('uncaughtException', reject);
});
}
function waitForAbort(opt_flow, opt_n) {
var n = opt_n || 1;
var theFlow = opt_flow || flow;
theFlow.removeAllListeners(
webdriver.promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION);
return new goog.Promise(function(fulfill, reject) {
theFlow.once('idle', function() {
reject(Error('expected flow to report an unhandled error'));
});
var errors = [];
theFlow.on('uncaughtException', onError);
function onError(e) {
errors.push(e);
if (errors.length === n) {
theFlow.removeListener('uncaughtException', onError);
fulfill(n === 1 ? errors[0] : errors);
}
}
});
}
function expectedError(code, message) {
return function(e) {
assertEquals('Wrong error message', message, e.message);
assertEquals('Wrong error code', code, e.code);
};
}
function createCommandMatcher(commandName, parameters) {
return new goog.testing.mockmatchers.ArgumentMatcher(function(actual) {
assertEquals('wrong name', commandName, actual.getName());
var differences = goog.testing.asserts.findDifferences(
parameters, actual.getParameters());
assertNull(
'Wrong parameters for "' + commandName + '"' +
'\n Expected: ' + goog.json.serialize(parameters) +
'\n Actual: ' + goog.json.serialize(actual.getParameters()),
differences);
return true;
}, commandName + '(' + goog.json.serialize(parameters) + ')');
}
TestHelper = function() {
this.executor = mockControl.createStrictMock(webdriver.CommandExecutor);
};
TestHelper.prototype.expect = function(commandName, opt_parameters) {
return new TestHelper.Command(this, commandName, opt_parameters);
};
TestHelper.prototype.replayAll = function() {
mockControl.$replayAll();
return this;
};
TestHelper.Command = function(testHelper, commandName, opt_parameters) {
this.helper_ = testHelper;
this.name_ = commandName;
this.toDo_ = null;
this.anyTimes_ = false;
this.times_ = 0;
this.sessionId_ = SESSION_ID;
this.withParameters(opt_parameters || {});
};
TestHelper.Command.prototype.withParameters = function(parameters) {
this.parameters_ = parameters;
if (this.name_ !== CName.NEW_SESSION) {
this.parameters_['sessionId'] = this.sessionId_;
}
return this;
};
TestHelper.Command.prototype.buildExpectation_ = function() {
var commandMatcher = createCommandMatcher(this.name_, this.parameters_);
assertNotNull(this.toDo_);
var expectation = this.helper_.executor.
execute(commandMatcher, goog.testing.mockmatchers.isFunction).
$does(this.toDo_);
if (this.anyTimes_) {
assertEquals(0, this.times_);
expectation.$anyTimes();
}
if (this.times_) {
assertFalse(this.anyTimes_);
expectation.$times(this.times_);
}
};
TestHelper.Command.prototype.andReturn = function(code, opt_value) {
this.toDo_ = function(command, callback) {
callback(null, {
'status': code,
'sessionId': {
'value': SESSION_ID
},
'value': goog.isDef(opt_value) ? opt_value : null
});
};
return this;
};
TestHelper.Command.prototype.anyTimes = function() {
this.anyTimes_ = true;
return this;
};
TestHelper.Command.prototype.times = function(n) {
this.times_ = n;
return this;
};
TestHelper.Command.prototype.andReturnSuccess = function(opt_returnValue) {
return this.andReturn(ECode.SUCCESS, opt_returnValue);
};
TestHelper.Command.prototype.andReturnError = function(errCode, opt_value) {
return this.andReturn(errCode, opt_value);
};
TestHelper.Command.prototype.replayAll = function() {
if (!this.toDo_) {
this.andReturnSuccess(null);
}
this.buildExpectation_();
return this.helper_.replayAll();
};
TestHelper.Command.prototype.expect = function(name, opt_parameters) {
if (!this.toDo_) {
this.andReturnSuccess(null);
}
this.buildExpectation_();
return this.helper_.expect(name, opt_parameters);
};
/**
* @param {!(webdriver.Session|webdriver.promise.Promise)=} opt_session The
* session to use.
* @return {!webdriver.WebDriver} A new driver instance.
*/
TestHelper.prototype.createDriver = function(opt_session) {
var session = opt_session || new webdriver.Session(SESSION_ID, {});
return new webdriver.WebDriver(session, this.executor);
};
//////////////////////////////////////////////////////////////////////////////
//
// Tests
//
//////////////////////////////////////////////////////////////////////////////
function testAttachToSession_sessionIsAvailable() {
var testHelper = new TestHelper().
expect(CName.DESCRIBE_SESSION).
withParameters({'sessionId': SESSION_ID}).
andReturnSuccess({'browserName': 'firefox'}).
replayAll();
var driver = webdriver.WebDriver.attachToSession(testHelper.executor,
SESSION_ID);
return driver.getSession().then(function(session) {
webdriver.test.testutil.assertObjectEquals({
'value':'test_session_id'
}, session.getId());
assertEquals('firefox', session.getCapability('browserName'));
});
}
function testAttachToSession_failsToGetSessionInfo() {
var testHelper = new TestHelper().
expect(CName.DESCRIBE_SESSION).
withParameters({'sessionId': SESSION_ID}).
andReturnError(ECode.UNKNOWN_ERROR, {'message': 'boom'}).
replayAll();
var driver = webdriver.WebDriver.attachToSession(testHelper.executor,
SESSION_ID);
return driver.getSession().then(fail, function(e) {
assertEquals(bot.ErrorCode.UNKNOWN_ERROR, e.code);
assertEquals('boom', e.message);
});
}
function testAttachToSession_usesActiveFlowByDefault() {
var testHelper = new TestHelper().
expect(CName.DESCRIBE_SESSION).
withParameters({'sessionId': SESSION_ID}).
andReturnSuccess({}).
replayAll();
var driver = webdriver.WebDriver.attachToSession(testHelper.executor,
SESSION_ID);
assertEquals(driver.controlFlow(), webdriver.promise.controlFlow());
return waitForIdle(driver.controlFlow());
}
function testAttachToSession_canAttachInCustomFlow() {
var testHelper = new TestHelper().
expect(CName.DESCRIBE_SESSION).
withParameters({'sessionId': SESSION_ID}).
andReturnSuccess({}).
replayAll();
var otherFlow = new webdriver.promise.ControlFlow();
var driver = webdriver.WebDriver.attachToSession(
testHelper.executor, SESSION_ID, otherFlow);
assertEquals(otherFlow, driver.controlFlow());
assertNotEquals(otherFlow, webdriver.promise.controlFlow());
return waitForIdle(otherFlow);
}
function testCreateSession_happyPathWithCapabilitiesHashObject() {
var testHelper = new TestHelper().
expect(CName.NEW_SESSION).
withParameters({
'desiredCapabilities': {'browserName': 'firefox'}
}).
andReturnSuccess({'browserName': 'firefox'}).
replayAll();
var driver = webdriver.WebDriver.createSession(testHelper.executor, {
'browserName': 'firefox'
});
return driver.getSession().then(function(session) {
webdriver.test.testutil.assertObjectEquals({
'value':'test_session_id'
}, session.getId());
assertEquals('firefox', session.getCapability('browserName'));
});
}
function testCreateSession_happyPathWithCapabilitiesInstance() {
var testHelper = new TestHelper().
expect(CName.NEW_SESSION).
withParameters({
'desiredCapabilities': {'browserName': 'firefox'}
}).
andReturnSuccess({'browserName': 'firefox'}).
replayAll();
var driver = webdriver.WebDriver.createSession(
testHelper.executor, webdriver.Capabilities.firefox());
return driver.getSession().then(function(session) {
webdriver.test.testutil.assertObjectEquals({
'value':'test_session_id'
}, session.getId());
assertEquals('firefox', session.getCapability('browserName'));
});
}
function testCreateSession_failsToCreateSession() {
var testHelper = new TestHelper().
expect(CName.NEW_SESSION).
withParameters({
'desiredCapabilities': {'browserName': 'firefox'}
}).
andReturnError(ECode.UNKNOWN_ERROR, {'message': 'boom'}).
replayAll();
var driver = webdriver.WebDriver.createSession(testHelper.executor, {
'browserName': 'firefox'
});
return driver.getSession().then(fail, function(e) {
assertEquals(bot.ErrorCode.UNKNOWN_ERROR, e.code);
assertEquals('boom', e.message);
});
}
function testCreateSession_usesActiveFlowByDefault() {
var testHelper = new TestHelper().
expect(CName.NEW_SESSION).
withParameters({'desiredCapabilities': {}}).
andReturnSuccess({}).
replayAll();
var driver = webdriver.WebDriver.createSession(testHelper.executor, {});
assertEquals(webdriver.promise.controlFlow(), driver.controlFlow());
return waitForIdle(driver.controlFlow());
}
function testCreateSession_canCreateInCustomFlow() {
var testHelper = new TestHelper().
expect(CName.NEW_SESSION).
withParameters({'desiredCapabilities': {}}).
andReturnSuccess({}).
replayAll();
var otherFlow = new webdriver.promise.ControlFlow(goog.global);
var driver = webdriver.WebDriver.createSession(
testHelper.executor, {}, otherFlow);
assertEquals(otherFlow, driver.controlFlow());
assertNotEquals(otherFlow, webdriver.promise.controlFlow());
return waitForIdle(otherFlow);
}
function testToWireValue_function() {
var fn = function() { return 'foo'; };
return webdriver.WebDriver.toWireValue_(fn).then(function(value) {
assertEquals(fn + '', value);
});
}
function testToWireValue_date() {
if (goog.userAgent.IE) {
return; // Because IE...
}
return webdriver.WebDriver.toWireValue_(new Date(605728511546)).
then(function(value) {
assertEquals('1989-03-12T17:55:11.546Z', value);
});
}
function testToWireValue_simpleObject() {
var expected = {'sessionId': 'foo'};
return webdriver.WebDriver.toWireValue_({
'sessionId': new webdriver.Session('foo', {})
}).then(function(actual) {
webdriver.test.testutil.assertObjectEquals(expected, actual);
});
}
function testToWireValue_nestedObject() {
var expected = {'sessionId': {'value': 'foo'}};
return webdriver.WebDriver.toWireValue_({
'sessionId': {
'value': new webdriver.Session('foo', {})
}
}).then(function(actual) {
webdriver.test.testutil.assertObjectEquals(expected, actual);
});
}
function testToWireValue_capabilities() {
var prefs = new webdriver.logging.Preferences();
prefs.setLevel(webdriver.logging.Type.BROWSER,
webdriver.logging.Level.DEBUG);
var caps = webdriver.Capabilities.chrome();
caps.set(webdriver.Capability.LOGGING_PREFS, prefs);
return webdriver.WebDriver.toWireValue_(caps).then(function(actual) {
webdriver.test.testutil.assertObjectEquals({
'browserName': 'chrome',
'loggingPrefs': {
'browser': 'DEBUG'
}
}, actual);
});
}
function testToWireValue_webElement() {
var expected = {};
expected[webdriver.WebElement.ELEMENT_KEY] = 'fefifofum';
var element = new webdriver.WebElement(STUB_DRIVER, expected);
return webdriver.WebDriver.toWireValue_(element).then(function(actual) {
webdriver.test.testutil.assertObjectEquals(expected, actual);
});
}
function testToWireValue_webElementPromise() {
var expected = {};
expected[webdriver.WebElement.ELEMENT_KEY] = 'fefifofum';
var element = new webdriver.WebElement(STUB_DRIVER, expected);
var elementPromise = new webdriver.WebElementPromise(STUB_DRIVER,
webdriver.promise.fulfilled(element));
return webdriver.WebDriver.toWireValue_(elementPromise).
then(function(actual) {
webdriver.test.testutil.assertObjectEquals(expected, actual);
});
}
function testToWireValue_domElement() {
assertThrows(
goog.partial(webdriver.WebDriver.toWireValue_, document.body));
}
function testToWireValue_serializableObject() {
/**
* @constructor
* @extends {webdriver.Serializable}
*/
var CustomSerializable = function () {
webdriver.Serializable.call(this);
};
goog.inherits(CustomSerializable, webdriver.Serializable);
/** @override */
CustomSerializable.prototype.serialize = function() {
return webdriver.promise.fulfilled({
name: webdriver.promise.fulfilled('bob'),
age: 30
});
};
var obj = new CustomSerializable();
return webdriver.WebDriver.toWireValue_(obj).
then(function(actual) {
webdriver.test.testutil.assertObjectEquals(
{name: 'bob', age: 30}, actual);
});
}
function testToWireValue_simpleArray() {
var expected = ['foo'];
return webdriver.WebDriver.toWireValue_([new webdriver.Session('foo', {})]).
then(function(actual) {
assertArrayEquals(expected, actual);
});
}
function testToWireValue_arrayWithWebElement() {
var elementJson = {};
elementJson[webdriver.WebElement.ELEMENT_KEY] = 'fefifofum';
var element = new webdriver.WebElement(STUB_DRIVER, elementJson);
return webdriver.WebDriver.toWireValue_([element]).
then(function(actual) {
assertTrue(goog.isArray(actual));
assertEquals(1, actual.length);
webdriver.test.testutil.assertObjectEquals(elementJson, actual[0]);
});
}
function testToWireValue_arrayWithWebElementPromise() {
var elementJson = {};
elementJson[webdriver.WebElement.ELEMENT_KEY] = 'fefifofum';
var element = new webdriver.WebElement(STUB_DRIVER, elementJson);
var elementPromise = new webdriver.WebElementPromise(STUB_DRIVER,
webdriver.promise.fulfilled(element));
return webdriver.WebDriver.toWireValue_([elementPromise]).
then(function(actual) {
assertTrue(goog.isArray(actual));
assertEquals(1, actual.length);
webdriver.test.testutil.assertObjectEquals(elementJson, actual[0]);
});
}
function testToWireValue_complexArray() {
var elementJson = {};
elementJson[webdriver.WebElement.ELEMENT_KEY] = 'fefifofum';
var expected = ['abc', 123, true, elementJson, [123, {'foo': 'bar'}]];
var element = new webdriver.WebElement(STUB_DRIVER, elementJson);
var input = ['abc', 123, true, element, [123, {'foo': 'bar'}]];
return webdriver.WebDriver.toWireValue_(input).
then(function(actual) {
webdriver.test.testutil.assertObjectEquals(expected, actual);
});
}
function testToWireValue_arrayWithNestedPromises() {
return webdriver.WebDriver.toWireValue_([
'abc',
webdriver.promise.fulfilled([
123,
webdriver.promise.fulfilled(true)
])
]).then(function(actual) {
assertEquals(2, actual.length);
assertEquals('abc', actual[0]);
assertArrayEquals([123, true], actual[1]);
});
}
function testToWireValue_complexHash() {
var elementJson = {};
elementJson[webdriver.WebElement.ELEMENT_KEY] = 'fefifofum';
var expected = {
'script': 'return 1',
'args': ['abc', 123, true, elementJson, [123, {'foo': 'bar'}]],
'sessionId': 'foo'
};
var element = new webdriver.WebElement(STUB_DRIVER, elementJson);
var parameters = {
'script': 'return 1',
'args':['abc', 123, true, element, [123, {'foo': 'bar'}]],
'sessionId': new webdriver.Session('foo', {})
};
return webdriver.WebDriver.toWireValue_(parameters).
then(function(actual) {
webdriver.test.testutil.assertObjectEquals(expected, actual);
});
}
function testFromWireValue_primitives() {
assertEquals(1, webdriver.WebDriver.fromWireValue_({}, 1));
assertEquals('', webdriver.WebDriver.fromWireValue_({}, ''));
assertEquals(true, webdriver.WebDriver.fromWireValue_({}, true));
assertUndefined(webdriver.WebDriver.fromWireValue_({}, undefined));
assertNull(webdriver.WebDriver.fromWireValue_({}, null));
}
function testFromWireValue_webElements() {
var json = {};
json[webdriver.WebElement.ELEMENT_KEY] = 'foo';
var element = webdriver.WebDriver.fromWireValue_(STUB_DRIVER, json);
assertEquals(STUB_DRIVER, element.getDriver());
return element.getId().then(function(id) {
webdriver.test.testutil.assertObjectEquals(json, id);
});
}
function testFromWireValue_simpleObject() {
var json = {'sessionId': 'foo'};
var out = webdriver.WebDriver.fromWireValue_({}, json);
webdriver.test.testutil.assertObjectEquals(json, out);
}
function testFromWireValue_nestedObject() {
var json = {'foo': {'bar': 123}};
var out = webdriver.WebDriver.fromWireValue_({}, json);
webdriver.test.testutil.assertObjectEquals(json, out);
}
function testFromWireValue_array() {
var json = [{'foo': {'bar': 123}}];
var out = webdriver.WebDriver.fromWireValue_({}, json);
webdriver.test.testutil.assertObjectEquals(json, out);
}
function testFromWireValue_passesThroughFunctionProperties() {
var json = [{'foo': {'bar': 123}, 'func': goog.nullFunction}];
var out = webdriver.WebDriver.fromWireValue_({}, json);
webdriver.test.testutil.assertObjectEquals(json, out);
}
function testDoesNotExecuteCommandIfSessionDoesNotResolve() {
var session = webdriver.promise.rejected(new StubError);
var testHelper = new TestHelper().replayAll();
testHelper.createDriver(session).getTitle();
return waitForAbort().then(assertIsStubError);
}
function testCommandReturnValuesArePassedToFirstCallback() {
var testHelper = new TestHelper().
expect(CName.GET_TITLE).andReturnSuccess('Google Search').
replayAll();
var driver = testHelper.createDriver();
return driver.getTitle().then(function(title) {
assertEquals('Google Search', title);
});
}
function testStopsCommandExecutionWhenAnErrorOccurs() {
var testHelper = new TestHelper().
expect(CName.SWITCH_TO_WINDOW).
withParameters({'name': 'foo'}).
andReturnError(ECode.NO_SUCH_WINDOW, {'message': 'window not found'}).
replayAll();
var driver = testHelper.createDriver();
driver.switchTo().window('foo');
driver.getTitle(); // mock should blow if this gets executed
return waitForAbort().
then(expectedError(ECode.NO_SUCH_WINDOW, 'window not found'));
}
function testCanSuppressCommandFailures() {
var testHelper = new TestHelper().
expect(CName.SWITCH_TO_WINDOW).
withParameters({'name': 'foo'}).
andReturnError(ECode.NO_SUCH_WINDOW, {'message': 'window not found'}).
expect(CName.GET_TITLE).
andReturnSuccess('Google Search').
replayAll();
var driver = testHelper.createDriver();
driver.switchTo().window('foo').thenCatch(function(e) {
assertEquals(ECode.NO_SUCH_WINDOW, e.code);
assertEquals('window not found', e.message);
});
driver.getTitle();
return waitForIdle();
}
function testErrorsPropagateUpToTheRunningApplication() {
var testHelper = new TestHelper().
expect(CName.SWITCH_TO_WINDOW).
withParameters({'name':'foo'}).
andReturnError(ECode.NO_SUCH_WINDOW, {'message': 'window not found'}).
replayAll();
testHelper.createDriver().switchTo().window('foo');
return waitForAbort().
then(expectedError(ECode.NO_SUCH_WINDOW, 'window not found'));
}
function testErrbacksThatReturnErrorsStillSwitchToCallbackChain() {
var testHelper = new TestHelper().
expect(CName.SWITCH_TO_WINDOW).
withParameters({'name':'foo'}).
andReturnError(ECode.NO_SUCH_WINDOW, {'message':'window not found'}).
replayAll();
var driver = testHelper.createDriver();
return driver.switchTo().window('foo').
thenCatch(function() { return new StubError; });
then(assertIsStubError);
}
function testErrbacksThrownCanOverrideOriginalError() {
var testHelper = new TestHelper().
expect(CName.SWITCH_TO_WINDOW, {'name': 'foo'}).
andReturnError(ECode.NO_SUCH_WINDOW, {'message':'window not found'}).
replayAll();
var driver = testHelper.createDriver();
driver.switchTo().window('foo').thenCatch(throwStubError);
return waitForAbort().then(assertIsStubError);
}
function testCannotScheduleCommandsIfTheSessionIdHasBeenDeleted() {
var testHelper = new TestHelper().replayAll();
var driver = testHelper.createDriver();
delete driver.session_;
assertThrows(goog.bind(driver.get, driver, 'http://www.google.com'));
}
function testDeletesSessionIdAfterQuitting() {
var driver;
var testHelper = new TestHelper().
expect(CName.QUIT).
replayAll();
driver = testHelper.createDriver();
return driver.quit().then(function() {
assertUndefined('Session ID should have been deleted', driver.session_);
});
}
function testReportsErrorWhenExecutingCommandsAfterExecutingAQuit() {
var testHelper = new TestHelper().
expect(CName.QUIT).
replayAll();
var driver = testHelper.createDriver();
driver.quit();
driver.get('http://www.google.com');
return waitForAbort().
then(expectedError(undefined,
'This driver instance does not have a valid session ID ' +
'(did you call WebDriver.quit()?) and may no longer be used.'));
}
function testCallbackCommandsExecuteBeforeNextCommand() {
var testHelper = new TestHelper().
expect(CName.GET_CURRENT_URL).
expect(CName.GET, {'url': 'http://www.google.com'}).
expect(CName.CLOSE).
expect(CName.GET_TITLE).
replayAll();
var driver = testHelper.createDriver();
driver.getCurrentUrl().then(function() {
driver.get('http://www.google.com').then(function() {
driver.close();
});
});
driver.getTitle();
return waitForIdle();
}
function testEachCallbackFrameRunsToCompletionBeforeTheNext() {
var testHelper = new TestHelper().
expect(CName.GET_TITLE).
expect(CName.GET_CURRENT_URL).
expect(CName.GET_CURRENT_WINDOW_HANDLE).
expect(CName.CLOSE).
expect(CName.QUIT).
replayAll();
var driver = testHelper.createDriver();
driver.getTitle().
// Everything in this callback...
then(function() {
driver.getCurrentUrl();
driver.getWindowHandle();
}).
// ...should execute before everything in this callback.
then(function() {
driver.close();
});
// This should execute after everything above
driver.quit();
return waitForIdle();
}
function testNestedCommandFailuresBubbleUpToGlobalHandlerIfUnsuppressed() {
var testHelper = new TestHelper().
expect(CName.GET_TITLE).
expect(CName.SWITCH_TO_WINDOW, {'name': 'foo'}).
andReturnError(ECode.NO_SUCH_WINDOW, {'message':'window not found'}).
replayAll();
var driver = testHelper.createDriver();
driver.getTitle().then(function() {
driver.switchTo().window('foo');
});
return waitForAbort().
then(expectedError(ECode.NO_SUCH_WINDOW, 'window not found'));
}
function testNestedCommandFailuresCanBeSuppressWhenTheyOccur() {
var testHelper = new TestHelper().
expect(CName.GET_TITLE).
expect(CName.SWITCH_TO_WINDOW, {'name':'foo'}).
andReturnError(ECode.NO_SUCH_WINDOW, {'message':'window not found'}).
expect(CName.CLOSE).
replayAll();
var driver = testHelper.createDriver();
driver.getTitle().then(function() {
driver.switchTo().window('foo').thenCatch(goog.nullFunction);
});
driver.close();
return waitForIdle();
}
function testNestedCommandFailuresBubbleUpThroughTheFrameStack() {
var testHelper = new TestHelper().
expect(CName.GET_TITLE).
expect(CName.SWITCH_TO_WINDOW, {'name':'foo'}).
andReturnError(ECode.NO_SUCH_WINDOW, {'message':'window not found'}).
replayAll();
var driver = testHelper.createDriver();
driver.getTitle().
then(function() {
return driver.switchTo().window('foo');
}).
thenCatch(function(e) {
assertEquals(ECode.NO_SUCH_WINDOW, e.code);
assertEquals('window not found', e.message);
});
return waitForIdle();
}
function testNestedCommandFailuresCanBeCaughtAndSuppressed() {
var testHelper = new TestHelper().
expect(CName.GET_TITLE).
expect(CName.GET_CURRENT_URL).
expect(CName.SWITCH_TO_WINDOW, {'name':'foo'}).
andReturnError(ECode.NO_SUCH_WINDOW, {'message':'window not found'}).
expect(CName.CLOSE).
replayAll();
var driver = testHelper.createDriver();
driver.getTitle().then(function() {
driver.getCurrentUrl().
then(function() {
return driver.switchTo().window('foo');
}).
thenCatch(goog.nullFunction);
driver.close();
});
return waitForIdle();
}
function testReturningADeferredResultFromACallback() {
var testHelper = new TestHelper().
expect(CName.GET_TITLE).
expect(CName.GET_CURRENT_URL).
andReturnSuccess('http://www.google.com').
replayAll();
var driver = testHelper.createDriver();
driver.getTitle().
then(function() {
return driver.getCurrentUrl();
}).
then(function(value) {
assertEquals('http://www.google.com', value);
});
return waitForIdle();
}
function testReturningADeferredResultFromAnErrbackSuppressesTheError() {
var count = 0;
var testHelper = new TestHelper().
expect(CName.SWITCH_TO_WINDOW, {'name':'foo'}).
andReturnError(ECode.NO_SUCH_WINDOW, {'message':'window not found'}).
expect(CName.GET_CURRENT_URL).
andReturnSuccess('http://www.google.com').
replayAll();
var driver = testHelper.createDriver();
driver.switchTo().window('foo').
thenCatch(function(e) {
assertEquals(ECode.NO_SUCH_WINDOW, e.code);
assertEquals('window not found', e.message);
count += 1;
return driver.getCurrentUrl();
}).
then(function(url) {
count += 1;
assertEquals('http://www.google.com', url);
});
return waitForIdle().then(function() {
assertEquals(2, count);
});
}
function testExecutingACustomFunctionThatReturnsANonDeferred() {
var testHelper = new TestHelper().replayAll();
var driver = testHelper.createDriver();
return driver.call(goog.functions.constant('abc123')).then(function(value) {
assertEquals('abc123', value);
});
}
function testExecutionOrderwithCustomFunctions() {
var msg = [];
var testHelper = new TestHelper().
expect(CName.GET_TITLE).andReturnSuccess('cheese ').
expect(CName.GET_CURRENT_URL).andReturnSuccess('tasty').
replayAll();
var driver = testHelper.createDriver();
var pushMsg = goog.bind(msg.push, msg);
driver.getTitle().then(pushMsg);
driver.call(goog.functions.constant('is ')).then(pushMsg);
driver.getCurrentUrl().then(pushMsg);
driver.call(goog.functions.constant('!')).then(pushMsg);
return waitForIdle().then(function() {
assertEquals('cheese is tasty!', msg.join(''));
});
}
function testPassingArgumentsToACustomFunction() {
var testHelper = new TestHelper().replayAll();
var add = function(a, b) {
return a + b;
};
var driver = testHelper.createDriver();
return driver.call(add, null, 1, 2).then(function(value) {
assertEquals(3, value);
});
}
function testPassingPromisedArgumentsToACustomFunction() {
var testHelper = new TestHelper().replayAll();
var promisedArg = webdriver.promise.fulfilled(2);
var add = function(a, b) {
return a + b;
};
var driver = testHelper.createDriver();
return driver.call(add, null, 1, promisedArg).then(function(value) {
assertEquals(3, value);
});
}
function testPassingArgumentsAndScopeToACustomFunction() {
function Foo(name) {
this.name = name;
}
Foo.prototype.getName = function() {
return this.name;
};
var foo = new Foo('foo');
var testHelper = new TestHelper().replayAll();
var driver = testHelper.createDriver();
return driver.call(foo.getName, foo).then(function(value) {
assertEquals('foo', value);
});
}
function testExecutingACustomFunctionThatThrowsAnError() {
var testHelper = new TestHelper().replayAll();
var driver = testHelper.createDriver();
return driver.call(goog.functions.error('bam!')).then(fail, function(e) {
assertTrue(e instanceof Error);
assertEquals('bam!', e.message);
});
}
function testExecutingACustomFunctionThatSchedulesCommands() {
var testHelper = new TestHelper().
expect(CName.GET_TITLE).
expect(CName.CLOSE).
expect(CName.QUIT).
replayAll();
var driver = testHelper.createDriver();
driver.call(function() {
driver.getTitle();
driver.close();
});
driver.quit();
return waitForIdle();
}
function testExecutingAFunctionThatReturnsATaskResultAfterSchedulingAnother() {
var testHelper = new TestHelper().
expect(CName.GET_TITLE).
andReturnSuccess('Google Search').
expect(CName.CLOSE).
replayAll();
var driver = testHelper.createDriver();
return driver.call(function() {
var title = driver.getTitle();
driver.close();
return title;
}).then(function(title) {
assertEquals('Google Search', title);
});
}
function testExecutingACustomFunctionWhoseNestedCommandFails() {
var testHelper = new TestHelper().
expect(CName.SWITCH_TO_WINDOW, {'name': 'foo'}).
andReturnError(ECode.NO_SUCH_WINDOW, {'message':'window not found'}).
replayAll();
var driver = testHelper.createDriver();
return driver.call(function() {
return driver.switchTo().window('foo');
}).then(fail, function(e) {
assertEquals(ECode.NO_SUCH_WINDOW, e.code);
assertEquals('window not found', e.message);
});
}
function testCustomFunctionDoesNotCompleteUntilReturnedPromiseIsResolved() {
var testHelper = new TestHelper().replayAll();
var order = [];
var driver = testHelper.createDriver();
var d = webdriver.promise.defer();
d.promise.then(function() {
order.push('b');
});
driver.call(function() {
order.push('a');
return d.promise;
});
driver.call(function() {
order.push('c');
});
// timeout to ensure the first function starts its execution before we
// trigger d's callbacks.
return webdriver.promise.delayed(0).then(function() {
assertArrayEquals(['a'], order);
d.fulfill();
return waitForIdle().then(function() {
assertArrayEquals(['a', 'b', 'c'], order);
});
});
}
function testNestedFunctionCommandExecutionOrder() {
var msg = [];
var testHelper = new TestHelper().replayAll();
var driver = testHelper.createDriver();
driver.call(msg.push, msg, 'a');
driver.call(function() {
driver.call(msg.push, msg, 'c');
driver.call(function() {
driver.call(msg.push, msg, 'e');
driver.call(msg.push, msg, 'f');
});
driver.call(msg.push, msg, 'd');
});
driver.call(msg.push, msg, 'b');
return waitForIdle().then(function() {
assertEquals('acefdb', msg.join(''));
});
}
function testExecutingNestedFunctionCommands() {
var msg = [];
var testHelper = new TestHelper().replayAll();
var driver = testHelper.createDriver();
var pushMsg = goog.bind(msg.push, msg);
driver.call(goog.functions.constant('cheese ')).then(pushMsg);
driver.call(function() {
driver.call(goog.functions.constant('is ')).then(pushMsg);
driver.call(goog.functions.constant('tasty')).then(pushMsg);
});
driver.call(goog.functions.constant('!')).then(pushMsg);
return waitForIdle().then(function() {
assertEquals('cheese is tasty!', msg.join(''));
});
}
function testReturnValuesFromNestedFunctionCommands() {
var testHelper = new TestHelper().replayAll();
var driver = testHelper.createDriver();
return driver.call(function() {
return driver.call(function() {
return driver.call(goog.functions.constant('foobar'));
});
}).then(function(value) {
assertEquals('foobar', value);
});
}
function testExecutingANormalCommandAfterNestedCommandsThatReturnsAnAction() {
var msg = [];
var testHelper = new TestHelper().
expect(CName.CLOSE).
replayAll();
var driver = testHelper.createDriver();
driver.call(function() {
return driver.call(function() {
msg.push('a');
return driver.call(goog.functions.constant('foobar'));
});
});
driver.close().then(function() {
msg.push('b');
});
return waitForIdle().then(function() {
assertEquals('ab', msg.join(''));
});
}
function testNestedCommandErrorsBubbleUp_caught() {
var testHelper = new TestHelper().replayAll();
var driver = testHelper.createDriver();
var result = driver.call(function() {
return driver.call(function() {
return driver.call(goog.functions.error('bam!'));
});
}).then(fail, expectedError(undefined, 'bam!'));
return goog.Promise.all([waitForIdle(), result]);
}
function testNestedCommandErrorsBubbleUp_uncaught() {
var testHelper = new TestHelper().replayAll();
var driver = testHelper.createDriver();
driver.call(function() {
return driver.call(function() {
return driver.call(goog.functions.error('bam!'));
});
});
return waitForAbort().then(expectedError(undefined, 'bam!'));
}
function testExecutingNestedCustomFunctionsThatSchedulesCommands() {
var testHelper = new TestHelper().
expect(CName.GET_TITLE).
expect(CName.CLOSE).
replayAll();
var driver = testHelper.createDriver();
driver.call(function() {
driver.call(function() {
driver.getTitle();
});
driver.close();
});
return waitForIdle();
}
function testExecutingACustomFunctionThatReturnsADeferredAction() {
var testHelper = new TestHelper().
expect(CName.GET_TITLE).andReturnSuccess('Google').
replayAll();
var driver = testHelper.createDriver();
driver.call(function() {
return driver.getTitle();
}).then(function(title) {
assertEquals('Google', title);
});
return waitForIdle();
}
function testWebElementPromise_resolvesWhenUnderlyingElementDoes() {
var el = new webdriver.WebElement(STUB_DRIVER, {'ELEMENT': 'foo'});
var promise = webdriver.promise.fulfilled(el);
return new webdriver.WebElementPromise(STUB_DRIVER, promise).
then(function(e) {
assertEquals(e, el);
});
}
function testWebElement_resolvesBeforeCallbacksOnWireValueTrigger() {
var el = new webdriver.promise.Deferred();
var element = new webdriver.WebElementPromise(STUB_DRIVER, el.promise);
var messages = [];
element.then(function() {
messages.push('element resolved');
});
element.getId().then(function() {
messages.push('wire value resolved');
});
assertArrayEquals([], messages);
el.fulfill(new webdriver.WebElement(STUB_DRIVER, {'ELEMENT': 'foo'}));
return waitForIdle().then(function() {
assertArrayEquals([
'element resolved',
'wire value resolved'
], messages);
});
}
function testWebElement_isRejectedIfUnderlyingIdIsRejected() {
var element = new webdriver.WebElementPromise(
STUB_DRIVER, webdriver.promise.rejected(new StubError));
return element.then(fail, assertIsStubError);
}
function testExecuteScript_nullReturnValue() {
var testHelper = new TestHelper().
expect(CName.EXECUTE_SCRIPT).
withParameters({
'script': 'return document.body;',
'args': []
}).
andReturnSuccess(null).
replayAll();
var driver = testHelper.createDriver();
return driver.executeScript('return document.body;').then(function(result) {
assertNull(result);
});
}
function testExecuteScript_primitiveReturnValue() {
var testHelper = new TestHelper().
expect(CName.EXECUTE_SCRIPT).
withParameters({
'script': 'return document.body;',
'args': []
}).
andReturnSuccess(123).
replayAll();
var driver = testHelper.createDriver();
return driver.executeScript('return document.body;').then(function(result) {
assertEquals(123, result);
});
}
function testExecuteScript_webElementReturnValue() {
var json = {};
json[webdriver.WebElement.ELEMENT_KEY] = 'foo';
var testHelper = new TestHelper().
expect(CName.EXECUTE_SCRIPT).
withParameters({
'script': 'return document.body;',
'args': []
}).
andReturnSuccess(json).
replayAll();
var driver = testHelper.createDriver();
return driver.executeScript('return document.body;').
then(function(webelement) {
return webdriver.promise.when(webelement.id_, function(id) {
webdriver.test.testutil.assertObjectEquals(id, json);
});
});
}
function testExecuteScript_arrayReturnValue() {
var json = [{}];
json[0][webdriver.WebElement.ELEMENT_KEY] = 'foo';
var testHelper = new TestHelper().
expect(CName.EXECUTE_SCRIPT).
withParameters({
'script': 'return document.body;',
'args': []
}).
andReturnSuccess(json).
replayAll();
var driver = testHelper.createDriver();
return driver.executeScript('return document.body;').
then(function(array) {
return webdriver.promise.when(array[0].id_, function(id) {
webdriver.test.testutil.assertObjectEquals(id, json[0]);
});
});
}
function testExecuteScript_objectReturnValue() {
var json = {'foo':{}};
json['foo'][webdriver.WebElement.ELEMENT_KEY] = 'foo';
var testHelper = new TestHelper().
expect(CName.EXECUTE_SCRIPT).
withParameters({
'script': 'return document.body;',
'args': []
}).
andReturnSuccess(json).
replayAll();
var driver = testHelper.createDriver();
var callback;
return driver.executeScript('return document.body;').
then(function(obj) {
return webdriver.promise.when(obj['foo'].id_, function(id) {
webdriver.test.testutil.assertObjectEquals(id, json['foo']);
});
});
}
function testExecuteScript_scriptAsFunction() {
var testHelper = new TestHelper().
expect(CName.EXECUTE_SCRIPT).
withParameters({
'script': 'return (' + goog.nullFunction +
').apply(null, arguments);',
'args': []
}).
andReturnSuccess(null).
replayAll();
var driver = testHelper.createDriver();
return driver.executeScript(goog.nullFunction);
}
function testExecuteScript_simpleArgumentConversion() {
var testHelper = new TestHelper().
expect(CName.EXECUTE_SCRIPT).
withParameters({
'script': 'return 1;',
'args': ['abc', 123, true, [123, {'foo': 'bar'}]]
}).
andReturnSuccess(null).
replayAll();
var driver = testHelper.createDriver();
return driver.executeScript(
'return 1;', 'abc', 123, true, [123, {'foo': 'bar'}]);
}
function testExecuteScript_webElementArgumentConversion() {
var elementJson = {};
elementJson[webdriver.WebElement.ELEMENT_KEY] = 'fefifofum';
var testHelper = new TestHelper().
expect(CName.EXECUTE_SCRIPT).
withParameters({
'script': 'return 1;',
'args': [elementJson]
}).
andReturnSuccess(null).
replayAll();
var driver = testHelper.createDriver();
return driver.executeScript('return 1;',
new webdriver.WebElement(driver, elementJson));
}
function testExecuteScript_webElementPromiseArgumentConversion() {
var elementJson = {'ELEMENT':'bar'};
var testHelper = new TestHelper().
expect(CName.FIND_ELEMENT, {'using':'id', 'value':'foo'}).
andReturnSuccess(elementJson).
expect(CName.EXECUTE_SCRIPT).
withParameters({
'script': 'return 1;',
'args': [elementJson]
}).
andReturnSuccess(null).
replayAll();
var driver = testHelper.createDriver();
var element = driver.findElement(By.id('foo'));
return driver.executeScript('return 1;', element);
}
function testExecuteScript_argumentConversion() {
var elementJson = {};
elementJson[webdriver.WebElement.ELEMENT_KEY] = 'fefifofum';
var testHelper = new TestHelper().
expect(CName.EXECUTE_SCRIPT).
withParameters({
'script': 'return 1;',
'args': ['abc', 123, true, elementJson, [123, {'foo': 'bar'}]]
}).
andReturnSuccess(null).
replayAll();
var driver = testHelper.createDriver();
var element = new webdriver.WebElement(driver, elementJson);
return driver.executeScript('return 1;',
'abc', 123, true, element, [123, {'foo': 'bar'}]);
}
function testExecuteScript_scriptReturnsAnError() {
var testHelper = new TestHelper().
expect(CName.EXECUTE_SCRIPT).
withParameters({
'script': 'throw Error(arguments[0]);',
'args': ['bam']
}).
andReturnError(ECode.UNKNOWN_ERROR, {'message':'bam'}).
replayAll();
var driver = testHelper.createDriver();
return driver.executeScript('throw Error(arguments[0]);', 'bam').
then(fail, expectedError(ECode.UNKNOWN_ERROR, 'bam'));
}
function testExecuteScript_failsIfArgumentIsARejectedPromise() {
var testHelper = new TestHelper().replayAll();
var arg = webdriver.promise.rejected(new StubError);
arg.thenCatch(goog.nullFunction); // Suppress default handler.
var driver = testHelper.createDriver();
return driver.executeScript(goog.nullFunction, arg).
then(fail, assertIsStubError);
}
function testExecuteAsyncScript_failsIfArgumentIsARejectedPromise() {
var testHelper = new TestHelper().replayAll();
var arg = webdriver.promise.rejected(new StubError);
arg.thenCatch(goog.nullFunction); // Suppress default handler.
var driver = testHelper.createDriver();
return driver.executeAsyncScript(goog.nullFunction, arg).
then(fail, assertIsStubError);
}
function testFindElement_elementNotFound() {
var testHelper = new TestHelper().
expect(CName.FIND_ELEMENT, {'using':'id', 'value':'foo'}).
andReturnError(ECode.NO_SUCH_ELEMENT, {
'message':'Unable to find element'
}).
replayAll();
var driver = testHelper.createDriver();
var element = driver.findElement(By.id('foo'));
element.click(); // This should never execute.
return waitForAbort().then(
expectedError(ECode.NO_SUCH_ELEMENT, 'Unable to find element'));
}
function testFindElement_elementNotFoundInACallback() {
var testHelper = new TestHelper().
expect(CName.FIND_ELEMENT, {'using':'id', 'value':'foo'}).
andReturnError(
ECode.NO_SUCH_ELEMENT, {'message':'Unable to find element'}).
replayAll();
var driver = testHelper.createDriver();
webdriver.promise.fulfilled().then(function() {
var element = driver.findElement(By.id('foo'));
return element.click(); // Should not execute.
});
return waitForAbort().then(
expectedError(ECode.NO_SUCH_ELEMENT, 'Unable to find element'));
}
function testFindElement_elementFound() {
var testHelper = new TestHelper().
expect(CName.FIND_ELEMENT, {'using':'id', 'value':'foo'}).
andReturnSuccess({'ELEMENT':'bar'}).
expect(CName.CLICK_ELEMENT, {'id':{'ELEMENT':'bar'}}).
andReturnSuccess().
replayAll();
var driver = testHelper.createDriver();
var element = driver.findElement(By.id('foo'));
element.click();
return waitForIdle();
}
function testFindElement_canUseElementInCallback() {
var testHelper = new TestHelper().
expect(CName.FIND_ELEMENT, {'using':'id', 'value':'foo'}).
andReturnSuccess({'ELEMENT':'bar'}).
expect(CName.CLICK_ELEMENT, {'id':{'ELEMENT':'bar'}}).
andReturnSuccess().
replayAll();
var driver = testHelper.createDriver();
driver.findElement(By.id('foo')).then(function(element) {
element.click();
});
return waitForIdle();
}
function testFindElement_byJs() {
var testHelper = new TestHelper().
expect(CName.EXECUTE_SCRIPT, {
'script': 'return document.body',
'args': []
}).
andReturnSuccess({'ELEMENT':'bar'}).
expect(CName.CLICK_ELEMENT, {'id':{'ELEMENT':'bar'}}).
replayAll();
var driver = testHelper.createDriver();
var element = driver.findElement(By.js('return document.body'));
element.click(); // just to make sure
return waitForIdle();
}
function testFindElement_byJs_returnsNonWebElementValue() {
var testHelper = new TestHelper().
expect(CName.EXECUTE_SCRIPT, {'script': 'return 123', 'args': []}).
andReturnSuccess(123).
replayAll();
var driver = testHelper.createDriver();
var element = driver.findElement(By.js('return 123'));
element.click(); // Should not execute.
return waitForAbort().then(function(e) {
assertEquals(
'Not the expected error message',
'Custom locator did not return a WebElement', e.message);
});
}
function testFindElement_byJs_canPassArguments() {
var script = 'return document.getElementsByTagName(arguments[0]);';
var testHelper = new TestHelper().
expect(CName.EXECUTE_SCRIPT, {
'script': script,
'args': ['div']
}).
andReturnSuccess({'ELEMENT':'one'}).
replayAll();
var driver = testHelper.createDriver();
driver.findElement(By.js(script, 'div'));
return waitForIdle();
}
function testFindElement_customLocator() {
var testHelper = new TestHelper().
expect(CName.FIND_ELEMENTS, {'using':'tag name', 'value':'a'}).
andReturnSuccess([{'ELEMENT':'foo'}, {'ELEMENT':'bar'}]).
expect(CName.CLICK_ELEMENT, {'id':{'ELEMENT':'foo'}}).
andReturnSuccess().
replayAll();
var driver = testHelper.createDriver();
var element = driver.findElement(function(d) {
assertEquals(driver, d);
return d.findElements(By.tagName('a'));
});
element.click();
return waitForIdle();
}
function testFindElement_customLocatorThrowsIfResultIsNotAWebElement() {
var testHelper = new TestHelper().replayAll();
var driver = testHelper.createDriver();
driver.findElement(function() {
return 1;
});
return waitForAbort().then(function(e) {
assertEquals(
'Not the expected error message',
'Custom locator did not return a WebElement', e.message);
});
}
function testIsElementPresent_elementNotFound() {
var testHelper = new TestHelper().
expect(CName.FIND_ELEMENTS, {'using':'id', 'value':'foo'}).
andReturnSuccess([]).
replayAll();
var driver = testHelper.createDriver();
return driver.isElementPresent(By.id('foo')).then(assertFalse);
}
function testIsElementPresent_elementFound() {
var testHelper = new TestHelper().
expect(CName.FIND_ELEMENTS, {'using':'id', 'value':'foo'}).
andReturnSuccess([{'ELEMENT':'bar'}]).
replayAll();
var driver = testHelper.createDriver();
return driver.isElementPresent(By.id('foo')).then(assertTrue);
}
function testIsElementPresent_letsErrorsPropagate() {
var testHelper = new TestHelper().
expect(CName.FIND_ELEMENTS, {'using':'id', 'value':'foo'}).
andReturnError(ECode.UNKNOWN_ERROR, {'message':'There is no spoon'}).
replayAll();
var driver = testHelper.createDriver();
driver.isElementPresent(By.id('foo'));
return waitForAbort().then(
expectedError(ECode.UNKNOWN_ERROR, 'There is