UNPKG

selenium-webdriver

Version:

The official WebDriver JavaScript bindings from the Selenium project

1,732 lines (1,414 loc) 70.8 kB
// 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.functions'); goog.require('goog.json'); goog.require('goog.testing.PropertyReplacer'); goog.require('goog.testing.MockControl'); goog.require('goog.testing.jsunit'); goog.require('webdriver.Capabilities'); goog.require('webdriver.Command'); goog.require('webdriver.CommandExecutor'); goog.require('webdriver.CommandName'); goog.require('webdriver.WebDriver'); 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'); goog.require('webdriver.testing.promise.FlowTester'); 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, STUB_ERROR = webdriver.test.testutil.STUB_ERROR, throwStubError = webdriver.test.testutil.throwStubError, assertIsStubError = webdriver.test.testutil.assertIsStubError, callbackHelper = webdriver.test.testutil.callbackHelper, callbackPair = webdriver.test.testutil.callbackPair; // 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 clock; var driver; var flowTester; var mockControl; var verifyAll; function setUp() { clock = webdriver.test.testutil.createMockClock(); flowTester = new webdriver.testing.promise.FlowTester(clock, goog.global); mockControl = new goog.testing.MockControl(); verifyAll = callbackHelper(goog.bind(mockControl.$verifyAll, mockControl)); } function tearDown() { flowTester.dispose(); verifyAll.assertCalled('Never verified mocks'); clock.uninstall(); mockControl.$tearDown(); } 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); this.execute = function() { fail('Expectations not set!'); }; }; TestHelper.expectingFailure = function(opt_errback) { var helper = new TestHelper(); helper.execute = function() { flowTester.run(); flowTester.verifyFailure(); verifyAll(); if (opt_errback) { opt_errback(flowTester.getFailure()); } }; return helper; }; TestHelper.expectingSuccess = function(opt_callback) { var helper = new TestHelper(); helper.execute = function() { flowTester.run(); flowTester.verifySuccess(); verifyAll(); if (opt_callback) { opt_callback(); } }; return helper; }; 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.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_); this.helper_.executor. execute(commandMatcher, goog.testing.mockmatchers.isFunction). $does(this.toDo_); }; 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.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 = TestHelper.expectingSuccess(). expect(CName.DESCRIBE_SESSION). withParameters({'sessionId': SESSION_ID}). andReturnSuccess({'browserName': 'firefox'}). replayAll(); var callback; var driver = webdriver.WebDriver.attachToSession(testHelper.executor, SESSION_ID); driver.getSession().then(callback = callbackHelper(function(session) { webdriver.test.testutil.assertObjectEquals({ 'value':'test_session_id' }, session.getId()); assertEquals('firefox', session.getCapability('browserName')); })); testHelper.execute(); callback.assertCalled(); } function testAttachToSession_failsToGetSessionInfo() { var testHelper = TestHelper.expectingSuccess(). expect(CName.DESCRIBE_SESSION). withParameters({'sessionId': SESSION_ID}). andReturnError(ECode.UNKNOWN_ERROR, {'message': 'boom'}). replayAll(); var errback; var driver = webdriver.WebDriver.attachToSession(testHelper.executor, SESSION_ID); driver.getSession().then(null, errback = callbackHelper(function(e) { assertEquals(bot.ErrorCode.UNKNOWN_ERROR, e.code); assertEquals('boom', e.message); })); testHelper.execute(); errback.assertCalled(); } function testAttachToSession_usesActiveFlowByDefault() { var testHelper = TestHelper.expectingSuccess(). 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()); testHelper.execute(); } function testAttachToSession_canAttachInCustomFlow() { var testHelper = TestHelper.expectingSuccess(). expect(CName.DESCRIBE_SESSION). withParameters({'sessionId': SESSION_ID}). andReturnSuccess({}). replayAll(); var otherFlow = new webdriver.promise.ControlFlow(goog.global); var driver = webdriver.WebDriver.attachToSession(testHelper.executor, SESSION_ID, otherFlow); assertEquals(otherFlow, driver.controlFlow()); assertNotEquals(otherFlow, webdriver.promise.controlFlow()); testHelper.execute(); } function testCreateSession_happyPathWithCapabilitiesHashObject() { var testHelper = TestHelper.expectingSuccess(). expect(CName.NEW_SESSION). withParameters({ 'desiredCapabilities': {'browserName': 'firefox'} }). andReturnSuccess({'browserName': 'firefox'}). replayAll(); var callback; var driver = webdriver.WebDriver.createSession(testHelper.executor, { 'browserName': 'firefox' }); driver.getSession().then(callback = callbackHelper(function(session) { webdriver.test.testutil.assertObjectEquals({ 'value':'test_session_id' }, session.getId()); assertEquals('firefox', session.getCapability('browserName')); })); testHelper.execute(); callback.assertCalled(); } function testCreateSession_happyPathWithCapabilitiesInstance() { var testHelper = TestHelper.expectingSuccess(). expect(CName.NEW_SESSION). withParameters({ 'desiredCapabilities': {'browserName': 'firefox'} }). andReturnSuccess({'browserName': 'firefox'}). replayAll(); var callback; var driver = webdriver.WebDriver.createSession( testHelper.executor, webdriver.Capabilities.firefox()); driver.getSession().then(callback = callbackHelper(function(session) { webdriver.test.testutil.assertObjectEquals({ 'value':'test_session_id' }, session.getId()); assertEquals('firefox', session.getCapability('browserName')); })); testHelper.execute(); callback.assertCalled(); } function testCreateSession_failsToCreateSession() { var testHelper = TestHelper.expectingSuccess(). expect(CName.NEW_SESSION). withParameters({ 'desiredCapabilities': {'browserName': 'firefox'} }). andReturnError(ECode.UNKNOWN_ERROR, {'message': 'boom'}). replayAll(); var errback; var driver = webdriver.WebDriver.createSession(testHelper.executor, { 'browserName': 'firefox' }); driver.getSession().then(null, errback = callbackHelper(function(e) { assertEquals(bot.ErrorCode.UNKNOWN_ERROR, e.code); assertEquals('boom', e.message); })); testHelper.execute(); errback.assertCalled(); } function testCreateSession_usesActiveFlowByDefault() { var testHelper = TestHelper.expectingSuccess(). expect(CName.NEW_SESSION). withParameters({'desiredCapabilities': {}}). andReturnSuccess({}). replayAll(); var driver = webdriver.WebDriver.createSession(testHelper.executor, {}); assertEquals(webdriver.promise.controlFlow(), driver.controlFlow()); testHelper.execute(); } function testCreateSession_canCreateInCustomFlow() { var testHelper = TestHelper.expectingSuccess(). 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()); testHelper.execute(); } function testToWireValue_function() { var fn = function() { return 'foo'; }; var callback; webdriver.WebDriver.toWireValue_(fn). then(callback = callbackHelper(function(value) { assertEquals(fn + '', value); })); callback.assertCalled(); verifyAll(); // Expected by tear down. } function testToWireValue_simpleObject() { var expected = {'sessionId': 'foo'}; var callback; webdriver.WebDriver.toWireValue_({ 'sessionId': new webdriver.Session('foo', {}) }).then(callback = callbackHelper(function(actual) { webdriver.test.testutil.assertObjectEquals(expected, actual); })); callback.assertCalled(); verifyAll(); // Expected by tear down. } function testToWireValue_nestedObject() { var expected = {'sessionId': {'value': 'foo'}}; var callback; webdriver.WebDriver.toWireValue_({ 'sessionId': { 'value': new webdriver.Session('foo', {}) } }).then(callback = callbackHelper(function(actual) { webdriver.test.testutil.assertObjectEquals(expected, actual); })); callback.assertCalled(); verifyAll(); // Expected by tear down. } function testToWireValue_webElement() { var expected = {}; expected[webdriver.WebElement.ELEMENT_KEY] = 'fefifofum'; var element = new webdriver.WebElement(STUB_DRIVER, expected); var callback; webdriver.WebDriver.toWireValue_(element). then(callback = callbackHelper(function(actual) { webdriver.test.testutil.assertObjectEquals(expected, actual); })); callback.assertCalled(); verifyAll(); // Expected by tear down. } 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)); var callback; webdriver.WebDriver.toWireValue_(elementPromise). then(callback = callbackHelper(function(actual) { webdriver.test.testutil.assertObjectEquals(expected, actual); })); callback.assertCalled(); verifyAll(); // Expected by tear down. } function testToWireValue_domElement() { assertThrows( goog.partial(webdriver.WebDriver.toWireValue_, document.body)); verifyAll(); // Expected by tear down. } function testToWireValue_simpleArray() { var expected = ['foo']; var callback; webdriver.WebDriver.toWireValue_([new webdriver.Session('foo', {})]).then( callback = callbackHelper(function(actual) { assertArrayEquals(expected, actual); })); callback.assertCalled(); verifyAll(); // Expected by tear down. } function testToWireValue_arrayWithWebElement() { var elementJson = {}; elementJson[webdriver.WebElement.ELEMENT_KEY] = 'fefifofum'; var element = new webdriver.WebElement(STUB_DRIVER, elementJson); var callback; webdriver.WebDriver.toWireValue_([element]). then(callback = callbackHelper(function(actual) { assertTrue(goog.isArray(actual)); assertEquals(1, actual.length); webdriver.test.testutil.assertObjectEquals(elementJson, actual[0]); })); callback.assertCalled(); verifyAll(); // Expected by tear down. } 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'}]]; var callback; webdriver.WebDriver.toWireValue_(input). then(callback = callbackHelper(function(actual) { webdriver.test.testutil.assertObjectEquals(expected, actual); })); callback.assertCalled(); verifyAll(); // Expected by tear down. } function testToWireValue_arrayWithNestedPromises() { var callback; webdriver.WebDriver.toWireValue_([ 'abc', webdriver.promise.fulfilled([ 123, webdriver.promise.fulfilled(true) ]) ]).then(callback = callbackHelper(function(actual) { assertEquals(2, actual.length); assertEquals('abc', actual[0]); assertArrayEquals([123, true], actual[1]); })); callback.assertCalled(); verifyAll(); // Expected by tear down. } 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', {}) }; var callback; webdriver.WebDriver.toWireValue_(parameters). then(callback = callbackHelper(function(actual) { webdriver.test.testutil.assertObjectEquals(expected, actual); })); callback.assertCalled(); verifyAll(); // Expected by tear down. } 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)); verifyAll(); // Expected by tear down. } function testFromWireValue_webElements() { var json = {}; json[webdriver.WebElement.ELEMENT_KEY] = 'foo'; var element = webdriver.WebDriver.fromWireValue_(STUB_DRIVER, json); assertEquals(STUB_DRIVER, element.getDriver()); var callback; webdriver.promise.when(element.id_, callback = callbackHelper(function(id) { webdriver.test.testutil.assertObjectEquals(json, id); })); callback.assertCalled(); verifyAll(); // Expected by tear down. } function testFromWireValue_simpleObject() { var json = {'sessionId': 'foo'}; var out = webdriver.WebDriver.fromWireValue_({}, json); webdriver.test.testutil.assertObjectEquals(json, out); verifyAll(); // Expected by tear down. } function testFromWireValue_nestedObject() { var json = {'foo': {'bar': 123}}; var out = webdriver.WebDriver.fromWireValue_({}, json); webdriver.test.testutil.assertObjectEquals(json, out); verifyAll(); // Expected by tear down. } function testFromWireValue_array() { var json = [{'foo': {'bar': 123}}]; var out = webdriver.WebDriver.fromWireValue_({}, json); webdriver.test.testutil.assertObjectEquals(json, out); verifyAll(); // Expected by tear down. } function testFromWireValue_passesThroughFunctionProperties() { var json = [{'foo': {'bar': 123}, 'func': goog.nullFunction}]; var out = webdriver.WebDriver.fromWireValue_({}, json); webdriver.test.testutil.assertObjectEquals(json, out); verifyAll(); // Expected by tear down. } function testDoesNotExecuteCommandIfSessionDoesNotResolve() { var session = webdriver.promise.rejected(STUB_ERROR); var testHelper = TestHelper. expectingFailure(assertIsStubError). replayAll(); testHelper.createDriver(session).getTitle(); testHelper.execute(); } function testCommandReturnValuesArePassedToFirstCallback() { var testHelper = TestHelper.expectingSuccess(). expect(CName.GET_TITLE). andReturnSuccess('Google Search'). replayAll(); var driver = testHelper.createDriver(); var callback; driver.getTitle().then(callback = callbackHelper(function(title) { assertEquals('Google Search', title); })); testHelper.execute(); callback.assertCalled(); } function testStopsCommandExecutionWhenAnErrorOccurs() { var testHelper = TestHelper. expectingFailure(expectedError(ECode.NO_SUCH_WINDOW, 'window not found')). 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 testHelper.execute(); } function testCanSuppressCommandFailures() { var callback; var testHelper = TestHelper. expectingSuccess(function() { callback.assertCalled(); }). 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(callback = callbackHelper(function(e) { assertEquals(ECode.NO_SUCH_WINDOW, e.code); assertEquals('window not found', e.message); return true; // suppress expected failure })); driver.getTitle(); // The mock will verify that getTitle was executed, which is what we want. testHelper.execute(); } function testErrorsPropagateUpToTheRunningApplication() { var testHelper = TestHelper. expectingFailure(expectedError(ECode.NO_SUCH_WINDOW, 'window not found')). expect(CName.SWITCH_TO_WINDOW). withParameters({'name':'foo'}). andReturnError(ECode.NO_SUCH_WINDOW, {'message': 'window not found'}). replayAll(); testHelper.createDriver().switchTo().window('foo'); testHelper.execute(); } function testErrbacksThatReturnErrorsStillSwitchToCallbackChain() { var callback; var testHelper = TestHelper. expectingSuccess(function() { callback.assertCalled(); }). 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'). thenCatch(function() { return STUB_ERROR; }). then(callback = callbackHelper(assertIsStubError)); testHelper.execute(); } function testErrbacksThrownCanOverrideOriginalError() { var testHelper = TestHelper. expectingFailure(assertIsStubError). 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); testHelper.execute(); } function testCannotScheduleCommandsIfTheSessionIdHasBeenDeleted() { var testHelper = TestHelper.expectingSuccess().replayAll(); var driver = testHelper.createDriver(); delete driver.session_; assertThrows(goog.bind(driver.get, driver, 'http://www.google.com')); verifyAll(); } function testDeletesSessionIdAfterQuitting() { var driver; var testHelper = TestHelper. expectingSuccess(function() { assertUndefined('Session ID should have been deleted', driver.session_); }). expect(CName.QUIT). replayAll(); driver = testHelper.createDriver(); driver.quit(); testHelper.execute(); } function testReportsErrorWhenExecutingCommandsAfterExecutingAQuit() { var testHelper = TestHelper. expectingFailure(expectedError(undefined, 'This driver instance does not have a valid session ID ' + '(did you call WebDriver.quit()?) and may no longer be used.')). expect(CName.QUIT). replayAll(); var driver = testHelper.createDriver(); driver.quit(); driver.get('http://www.google.com'); testHelper.execute(); } function testCallbackCommandsExecuteBeforeNextCommand() { var testHelper = TestHelper.expectingSuccess(). 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(); testHelper.execute(); } function testEachCallbackFrameRunsToCompletionBeforeTheNext() { var testHelper = TestHelper.expectingSuccess(). 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(); testHelper.execute(); } function testNestedCommandFailuresBubbleUpToGlobalHandlerIfUnsuppressed() { var testHelper = TestHelper. expectingFailure(expectedError(ECode.NO_SUCH_WINDOW, 'window not found')). 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'); }); testHelper.execute(); } function testNestedCommandFailuresCanBeSuppressWhenTheyOccur() { var testHelper = TestHelper.expectingSuccess(). 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.functions.TRUE); }); driver.close(); testHelper.execute(); } function testNestedCommandFailuresBubbleUpThroughTheFrameStack() { var callback; var testHelper = TestHelper. expectingSuccess(function() { callback.assertCalled('Error did not bubble up'); }). 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(callback = callbackHelper(function(e) { assertEquals(ECode.NO_SUCH_WINDOW, e.code); assertEquals('window not found', e.message); return true; // Suppress the error. })); testHelper.execute(); } function testNestedCommandFailuresCanBeCaughtAndSuppressed() { var testHelper = TestHelper.expectingSuccess(). 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.functions.TRUE); driver.close(); }); // Let the mock verify everything. testHelper.execute(); } function testReturningADeferredResultFromACallback() { var testHelper = TestHelper.expectingSuccess(). 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); }); testHelper.execute(); } function testReturningADeferredResultFromAnErrbackSuppressesTheError() { var count = 0; var testHelper = TestHelper.expectingSuccess(function() { assertEquals(2, count); }). 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); }); testHelper.execute(); } function testExecutingACustomFunctionThatReturnsANonDeferred() { var called = false; var testHelper = TestHelper.expectingSuccess(function() { assertTrue('Callback not called', called); }). replayAll(); var driver = testHelper.createDriver(); driver.call(goog.functions.constant('abc123')).then(function(value) { called = true; assertEquals('abc123', value); }); testHelper.execute(); } function testExecutionOrderwithCustomFunctions() { var msg = []; var testHelper = TestHelper.expectingSuccess(function() { assertEquals('cheese is tasty!', msg.join('')); }). 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); testHelper.execute(); } function testPassingArgumentsToACustomFunction() { var testHelper = TestHelper.expectingSuccess().replayAll(); var add = callbackHelper(function(a, b) { return a + b; }); var driver = testHelper.createDriver(); driver.call(add, null, 1, 2). then(function(value) { assertEquals(3, value); }); testHelper.execute(); add.assertCalled(); } function testPassingPromisedArgumentsToACustomFunction() { var testHelper = TestHelper.expectingSuccess().replayAll(); var promisedArg = new webdriver.promise.Deferred; var add = callbackHelper(function(a, b) { return a + b; }); var driver = testHelper.createDriver(); driver.call(add, null, 1, promisedArg). then(function(value) { assertEquals(3, value); }); flowTester.turnEventLoop(); add.assertNotCalled(); promisedArg.fulfill(2); add.assertCalled(); testHelper.execute(); } function testPassingArgumentsAndScopeToACustomFunction() { function Foo(name) { this.name = name; } Foo.prototype.getName = function() { return this.name; }; var foo = new Foo('foo'); var called = false; var testHelper = TestHelper.expectingSuccess(function() { assertTrue('Callback not called', called); }). replayAll(); var driver = testHelper.createDriver(); driver.call(foo.getName, foo).then(function(value) { assertEquals('foo', value); called = true; }); testHelper.execute(); } function testExecutingACustomFunctionThatThrowsAnError() { var called = false; var testHelper = TestHelper.expectingSuccess(function() { assertTrue('Callback not called', called); }). replayAll(); var driver = testHelper.createDriver(); driver.call(goog.functions.error('bam!')).thenCatch(function(e) { assertTrue(e instanceof Error); assertEquals('bam!', e.message); called = true; return true; // suppress the error. }); testHelper.execute(); } function testExecutingACustomFunctionThatSchedulesCommands() { var testHelper = TestHelper.expectingSuccess(). expect(CName.GET_TITLE). expect(CName.CLOSE). expect(CName.QUIT). replayAll(); var driver = testHelper.createDriver(); driver.call(function() { driver.getTitle(); driver.close(); }); driver.quit(); testHelper.execute(); } function testExecutingAFunctionThatReturnsATaskResultAfterSchedulingAnother() { var called = false; var testHelper = TestHelper.expectingSuccess(function() { assertTrue(called); }). expect(CName.GET_TITLE). andReturnSuccess('Google Search'). expect(CName.CLOSE). replayAll(); var driver = testHelper.createDriver(); var result = driver.call(function() { var title = driver.getTitle(); driver.close(); return title; }); result.then(function(title) { called = true; assertEquals('Google Search', title); }); testHelper.execute(); } function testExecutingACustomFunctionWhoseNestedCommandFails() { var called = false; var testHelper = TestHelper.expectingSuccess(function() { assertTrue('Callback not called', called); }). expect(CName.SWITCH_TO_WINDOW, {'name': 'foo'}). andReturnError(ECode.NO_SUCH_WINDOW, {'message':'window not found'}). replayAll(); var driver = testHelper.createDriver(); var result = driver.call(function() { return driver.switchTo().window('foo'); }); result.thenCatch(function(e) { assertEquals(ECode.NO_SUCH_WINDOW, e.code); assertEquals('window not found', e.message); called = true; return true; // suppress the error. }); testHelper.execute(); } function testCustomFunctionDoesNotCompleteUntilReturnedPromiseIsResolved() { var testHelper = TestHelper.expectingSuccess().replayAll(); var d = new webdriver.promise.Deferred(), stepOne = callbackHelper(function() { return d.promise; }), stepTwo = callbackHelper(); var driver = testHelper.createDriver(); driver.call(stepOne); driver.call(stepTwo); flowTester.turnEventLoop(); stepOne.assertCalled(); stepTwo.assertNotCalled(); flowTester.turnEventLoop(); stepOne.assertCalled(); stepTwo.assertNotCalled(); d.fulfill(); testHelper.execute(); stepTwo.assertCalled(); } function testNestedFunctionCommandExecutionOrder() { var msg = []; var testHelper = TestHelper.expectingSuccess(function() { assertEquals('acefdb', msg.join('')); }). 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'); testHelper.execute(); } function testExecutingNestedFunctionCommands() { var msg = []; var testHelper = TestHelper.expectingSuccess(function() { assertEquals('cheese is tasty!', msg.join('')); }). 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); testHelper.execute(); } function testReturnValuesFromNestedFunctionCommands() { var count = 0; var testHelper = TestHelper.expectingSuccess(function() { assertEquals('not called', 1, count); }). replayAll(); var driver = testHelper.createDriver(); var result = driver.call(function() { return driver.call(function() { return driver.call(goog.functions.constant('foobar')); }); }); result.then(function(value) { assertEquals('foobar', value); count += 1; }); testHelper.execute(); } function testExecutingANormalCommandAfterNestedCommandsThatReturnsAnAction() { var msg = []; var testHelper = TestHelper.expectingSuccess(function() { assertEquals('ab', msg.join('')); }). 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'); }); testHelper.execute(); } function testNestedCommandErrorsBubbleUp() { var testHelper = TestHelper. expectingFailure(expectedError(undefined, 'bam!')). replayAll(); var driver = testHelper.createDriver(); driver.call(function() { return driver.call(function() { return driver.call(goog.functions.error('bam!')); }); }); testHelper.execute(); } function testExecutingNestedCustomFunctionsThatSchedulesCommands() { var testHelper = TestHelper.expectingSuccess(). expect(CName.GET_TITLE). expect(CName.CLOSE). replayAll(); var driver = testHelper.createDriver(); driver.call(function() { driver.call(function() { driver.getTitle(); }); driver.close(); }); testHelper.execute(); } function testExecutingACustomFunctionThatReturnsADeferredAction() { var testHelper = TestHelper.expectingSuccess(). expect(CName.GET_TITLE).andReturnSuccess('Google'). replayAll(); var driver = testHelper.createDriver(); driver.call(function() { return driver.getTitle(); }).then(function(title) { assertEquals('Google', title); }); testHelper.execute(); } function testWebElementPromise_resolvesWhenUnderlyingElementDoes() { var el = new webdriver.WebElement(STUB_DRIVER, {'ELEMENT': 'foo'}); var d = webdriver.promise.defer(); var callback; new webdriver.WebElementPromise(STUB_DRIVER, d.promise).then( callback = callbackHelper(function(e) { assertEquals(e, el); })); callback.assertNotCalled(); d.fulfill(el); callback.assertCalled(); verifyAll(); // Make tearDown happy. } function testWebElement_resolvesBeforeCallbacksOnWireValueTrigger() { var el = new webdriver.promise.Deferred(); var callback, idCallback; var element = new webdriver.WebElementPromise(STUB_DRIVER, el.promise); var messages = []; webdriver.promise.when(element, function() { messages.push('element resolved'); }); webdriver.promise.when(element.getId(), function() { messages.push('wire value resolved'); }); assertArrayEquals([], messages); el.fulfill(new webdriver.WebElement(STUB_DRIVER, {'ELEMENT': 'foo'})); assertArrayEquals([ 'element resolved', 'wire value resolved' ], messages); verifyAll(); // Make tearDown happy. } function testWebElement_isRejectedIfUnderlyingIdIsRejected() { var id = new webdriver.promise.Deferred(); var callback, errback; var element = new webdriver.WebElementPromise(STUB_DRIVER, id.promise); webdriver.promise.when(element, callback = callbackHelper(), errback = callbackHelper(assertIsStubError)); callback.assertNotCalled(); errback.assertNotCalled(); id.reject(STUB_ERROR); callback.assertNotCalled(); errback.assertCalled(); verifyAll(); // Make tearDown happy. } function testExecuteScript_nullReturnValue() { var testHelper = TestHelper.expectingSuccess(). expect(CName.EXECUTE_SCRIPT). withParameters({ 'script': 'return document.body;', 'args': [] }). andReturnSuccess(null). replayAll(); var driver = testHelper.createDriver(); var callback; driver.executeScript('return document.body;'). then(callback = callbackHelper(function(result) { assertNull(result); })); testHelper.execute(); callback.assertCalled(); } function testExecuteScript_primitiveReturnValue() { var testHelper = TestHelper.expectingSuccess(). expect(CName.EXECUTE_SCRIPT). withParameters({ 'script': 'return document.body;', 'args': [] }). andReturnSuccess(123). replayAll(); var driver = testHelper.createDriver(); var callback; driver.executeScript('return document.body;'). then(callback = callbackHelper(function(result) { assertEquals(123, result); })); testHelper.execute(); callback.assertCalled(); } function testExecuteScript_webElementReturnValue() { var json = {}; json[webdriver.WebElement.ELEMENT_KEY] = 'foo'; var testHelper = TestHelper.expectingSuccess(). expect(CName.EXECUTE_SCRIPT). withParameters({ 'script': 'return document.body;', 'args': [] }). andReturnSuccess(json). replayAll(); var driver = testHelper.createDriver(); var callback; driver.executeScript('return document.body;'). then(function(webelement) { webdriver.promise.when(webelement.id_, callback = callbackHelper(function(id) { webdriver.test.testutil.assertObjectEquals(id, json); })); }); testHelper.execute(); callback.assertCalled(); } function testExecuteScript_arrayReturnValue() { var json = [{}]; json[0][webdriver.WebElement.ELEMENT_KEY] = 'foo'; var testHelper = TestHelper.expectingSuccess(). expect(CName.EXECUTE_SCRIPT). withParameters({ 'script': 'return document.body;', 'args': [] }). andReturnSuccess(json). replayAll(); var driver = testHelper.createDriver(); var callback; driver.executeScript('return document.body;'). then(function(array) { webdriver.promise.when(array[0].id_, callback = callbackHelper(function(id) { webdriver.test.testutil.assertObjectEquals(id, json[0]); })); }); testHelper.execute(); callback.assertCalled(); } function testExecuteScript_objectReturnValue() { var json = {'foo':{}}; json['foo'][webdriver.WebElement.ELEMENT_KEY] = 'foo'; var testHelper = TestHelper.expectingSuccess(). expect(CName.EXECUTE_SCRIPT). withParameters({ 'script': 'return document.body;', 'args': [] }). andReturnSuccess(json). replayAll(); var driver = testHelper.createDriver(); var callback; driver.executeScript('return document.body;'). then(function(obj) { webdriver.promise.when(obj['foo'].id_, callback = callbackHelper(function(id) { webdriver.test.testutil.assertObjectEquals(id, json['foo']); })); }); testHelper.execute(); callback.assertCalled(); } function testExecuteScript_scriptAsFunction() { var testHelper = TestHelper.expectingSuccess(). expect(CName.EXECUTE_SCRIPT). withParameters({ 'script': 'return (' + goog.nullFunction + ').apply(null, arguments);', 'args': [] }). andReturnSuccess(null). replayAll(); var driver = testHelper.createDriver(); driver.executeScript(goog.nullFunction); testHelper.execute(); } function testExecuteScript_simpleArgumentConversion() { var testHelper = TestHelper.expectingSuccess(). expect(CName.EXECUTE_SCRIPT). withParameters({ 'script': 'return 1;', 'args': ['abc', 123, true, [123, {'foo': 'bar'}]] }). andReturnSuccess(null). replayAll(); var driver = testHelper.createDriver(); driver.executeScript('return 1;', 'abc', 123, true, [123, {'foo': 'bar'}]); testHelper.execute(); } function testExecuteScript_webElementArgumentConversion() { var elementJson = {}; elementJson[webdriver.WebElement.ELEMENT_KEY] = 'fefifofum'; var testHelper = TestHelper.expectingSuccess(). expect(CName.EXECUTE_SCRIPT). withParameters({ 'script': 'return 1;', 'args': [elementJson] }). andReturnSuccess(null). replayAll(); var driver = testHelper.createDriver(); driver.executeScript('return 1;', new webdriver.WebElement(driver, elementJson)); testHelper.execute(); } function testExecuteScript_argumentConversion() { var elementJson = {}; elementJson[webdriver.WebElement.ELEMENT_KEY] = 'fefifofum'; var testHelper = TestHelper.expectingSuccess(). 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); driver.executeScript('return 1;', 'abc', 123, true, element, [123, {'foo': 'bar'}]); testHelper.execute(); } function testExecuteScript_scriptReturnsAnError() { var testHelper = TestHelper. expectingFailure(expectedError(ECode.UNKNOWN_ERROR, 'bam')). expect(CName.EXECUTE_SCRIPT). withParameters({ 'script': 'throw Error(arguments[0]);', 'args': ['bam'] }). andReturnError(ECode.UNKNOWN_ERROR, {'message':'bam'}). replayAll(); var driver = testHelper.createDriver(); driver.executeScript('throw Error(arguments[0]);', 'bam'); testHelper.execute(); } function testExecuteScript_failsIfArgumentIsARejectedPromise() { var testHelper = TestHelper.expectingSuccess().replayAll(); var callback = callbackHelper(assertIsStubError); var arg = webdriver.promise.rejected(STUB_ERROR); arg.thenCatch(goog.nullFunction); // Suppress default handler. var driver = testHelper.createDriver(); driver.executeScript(goog.nullFunction, arg).thenCatch(callback); testHelper.execute(); callback.assertCalled(); } function testExecuteAsyncScript_failsIfArgumentIsARejectedPromise() { var testHelper = TestHelper.expectingSuccess().replayAll(); var callback = callbackHelper(assertIsStubError); var arg = webdriver.promise.rejected(STUB_ERROR); arg.thenCatch(goog.nullFunction); // Suppress default handler. var driver = testHelper.createDriver(); driver.executeAsyncScript(goog.nullFunction, arg).thenCatch(callback); testHelper.execute(); callback.assertCalled(); } function testFindElement_elementNotFound() { var testHelper = TestHelper. expectingFailure(expectedError(ECode.NO_SUCH_ELEMENT, 'Unable to find element')). 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. testHelper.execute(); } function testFindElement_elementNotFoundInACallback() { var testHelper = TestHelper. expectingFailure( expectedError(ECode.NO_SUCH_ELEMENT, 'Unable to find element')). 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. }); testHelper.execute(); } function testFindElement_elementFound() { var testHelper = TestHelper.expectingSuccess(). 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(); testHelper.execute(); } function testFindElement_canUseElementInCallback() { var testHelper = TestHelper.expectingSuccess(). 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(); }); testHelper.execute(); } function testFindElement_byJs() { var testHelper = TestHelper.expectingSuccess(). 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 testHelper.execute(); } function testFindElement_byJs_returnsNonWebElementValue() { var testHelper = TestHelper. expectingFailure(function(e) { assertEquals( 'Not the expected error message', 'Custom locator did not return a WebElement', e.message); }). 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. testHelper.execute(); } function testFindElement_byJs_canPassArguments() { var script = 'return document.getElementsByTagName(arguments[0]);'; var testHelper = TestHelper.expectingSuccess(). expect(CName.EXECUTE_SCRIPT, { 'script': script, 'args': ['div'] }). andReturnSuccess({'ELEMENT':'one'}). replayAll(); var driver = testHelper.createDriver(); driver.findElement(By.js(script, 'div')); testHelper.execute(); } function testFindElement_customLocator() { var testHelper = TestHelper.expectingSuccess(). 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