1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311 |
- // Licensed to the Software Freedom Conservancy (SFC) under one
- // or more contributor license agreements. See the NOTICE file
- // distributed with this work for additional information
- // regarding copyright ownership. The SFC licenses this file
- // to you under the Apache License, Version 2.0 (the
- // "License"); you may not use this file except in compliance
- // with the License. You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing,
- // software distributed under the License is distributed on an
- // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- // KIND, either express or implied. See the License for the
- // specific language governing permissions and limitations
- // under the License.
- 'use strict';
- const testutil = require('./testutil');
- const By = require('../../lib/by').By;
- const Capabilities = require('../../lib/capabilities').Capabilities;
- const Executor = require('../../lib/command').Executor;
- const CName = require('../../lib/command').Name;
- const error = require('../../lib/error');
- const Button = require('../../lib/input').Button;
- const Key = require('../../lib/input').Key;
- const logging = require('../../lib/logging');
- const Session = require('../../lib/session').Session;
- const promise = require('../../lib/promise');
- const {enablePromiseManager, promiseManagerSuite} = require('../../lib/test/promise');
- const until = require('../../lib/until');
- const Alert = require('../../lib/webdriver').Alert;
- const AlertPromise = require('../../lib/webdriver').AlertPromise;
- const UnhandledAlertError = require('../../lib/webdriver').UnhandledAlertError;
- const WebDriver = require('../../lib/webdriver').WebDriver;
- const WebElement = require('../../lib/webdriver').WebElement;
- const WebElementPromise = require('../../lib/webdriver').WebElementPromise;
- const assert = require('assert');
- const sinon = require('sinon');
- const SESSION_ID = 'test_session_id';
- // Aliases for readability.
- const NativePromise = Promise;
- const StubError = testutil.StubError;
- const assertIsInstance = testutil.assertIsInstance;
- const assertIsStubError = testutil.assertIsStubError;
- const throwStubError = testutil.throwStubError;
- const fail = (msg) => assert.fail(msg);
- describe('WebDriver', function() {
- const LOG = logging.getLogger('webdriver.test');
- // before(function() {
- // logging.getLogger('webdriver').setLevel(logging.Level.ALL);
- // logging.installConsoleHandler();
- // });
- // after(function() {
- // logging.getLogger('webdriver').setLevel(null);
- // logging.removeConsoleHandler();
- // });
- var driver;
- var flow;
- var uncaughtExceptions;
- beforeEach(function setUp() {
- flow = promise.controlFlow();
- uncaughtExceptions = [];
- flow.on('uncaughtException', onUncaughtException);
- });
- afterEach(function tearDown() {
- if (!promise.USE_PROMISE_MANAGER) {
- return;
- }
- return waitForIdle(flow).then(function() {
- assert.deepEqual([], uncaughtExceptions);
- flow.reset();
- });
- });
- function onUncaughtException(e) {
- uncaughtExceptions.push(e);
- }
- function defer() {
- let d = {};
- let promise = new Promise((resolve, reject) => {
- Object.assign(d, {resolve, reject});
- });
- d.promise = promise;
- return d;
- }
- function waitForIdle(opt_flow) {
- if (!promise.USE_PROMISE_MANAGER) {
- return Promise.resolve();
- }
- var theFlow = opt_flow || flow;
- return new Promise(function(fulfill, reject) {
- if (theFlow.isIdle()) {
- 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(
- promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION);
- return new 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(ctor, message) {
- return function(e) {
- assertIsInstance(ctor, e);
- assert.equal(message, e.message);
- };
- }
- class Expectation {
- constructor(executor, name, opt_parameters) {
- this.executor_ = executor;
- this.name_ = name;
- this.times_ = 1;
- this.sessionId_ = SESSION_ID;
- this.check_ = null;
- this.toDo_ = null;
- this.withParameters(opt_parameters || {});
- }
- anyTimes() {
- this.times_ = Infinity;
- return this;
- }
- times(n) {
- this.times_ = n;
- return this;
- }
- withParameters(parameters) {
- this.parameters_ = parameters;
- if (this.name_ !== CName.NEW_SESSION) {
- this.parameters_['sessionId'] = this.sessionId_;
- }
- return this;
- }
- andReturn(code, opt_value) {
- this.toDo_ = function(command) {
- LOG.info('executing ' + command.getName() + '; returning ' + code);
- return Promise.resolve(opt_value !== void(0) ? opt_value : null);
- };
- return this;
- }
- andReturnSuccess(opt_value) {
- this.toDo_ = function(command) {
- LOG.info('executing ' + command.getName() + '; returning success');
- return Promise.resolve(opt_value !== void(0) ? opt_value : null);
- };
- return this;
- }
- andReturnError(error) {
- if (typeof error === 'number') {
- throw Error('need error type');
- }
- this.toDo_ = function(command) {
- LOG.info('executing ' + command.getName() + '; returning failure');
- return Promise.reject(error);
- };
- return this;
- }
- expect(name, opt_parameters) {
- this.end();
- return this.executor_.expect(name, opt_parameters);
- }
- end() {
- if (!this.toDo_) {
- this.andReturnSuccess(null);
- }
- return this.executor_;
- }
- execute(command) {
- assert.deepEqual(this.parameters_, command.getParameters());
- return this.toDo_(command);
- }
- }
- class FakeExecutor {
- constructor() {
- this.commands_ = new Map;
- }
- execute(command) {
- let expectations = this.commands_.get(command.getName());
- if (!expectations || !expectations.length) {
- assert.fail('unexpected command: ' + command.getName());
- return;
- }
- let next = expectations[0];
- let result = next.execute(command);
- if (next.times_ != Infinity) {
- next.times_ -= 1;
- if (!next.times_) {
- expectations.shift();
- }
- }
- return result;
- }
- expect(commandName, opt_parameters) {
- if (!this.commands_.has(commandName)) {
- this.commands_.set(commandName, []);
- }
- let e = new Expectation(this, commandName, opt_parameters);
- this.commands_.get(commandName).push(e);
- return e;
- }
- createDriver(opt_session) {
- let session = opt_session || new Session(SESSION_ID, {});
- return new WebDriver(session, this);
- }
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // Tests
- //
- /////////////////////////////////////////////////////////////////////////////
- describe('testAttachToSession', function() {
- it('sessionIsAvailable', function() {
- let aSession = new Session(SESSION_ID, {'browserName': 'firefox'});
- let executor = new FakeExecutor().
- expect(CName.DESCRIBE_SESSION).
- withParameters({'sessionId': SESSION_ID}).
- andReturnSuccess(aSession).
- end();
- let driver = WebDriver.attachToSession(executor, SESSION_ID);
- return driver.getSession().then(v => assert.strictEqual(v, aSession));
- });
- it('failsToGetSessionInfo', function() {
- let e = new Error('boom');
- let executor = new FakeExecutor().
- expect(CName.DESCRIBE_SESSION).
- withParameters({'sessionId': SESSION_ID}).
- andReturnError(e).
- end();
- let driver = WebDriver.attachToSession(executor, SESSION_ID);
- return driver.getSession()
- .then(() => assert.fail('should have failed!'),
- (actual) => assert.strictEqual(actual, e));
- });
- it('remote end does not recognize DESCRIBE_SESSION command', function() {
- let e = new error.UnknownCommandError;
- let executor = new FakeExecutor().
- expect(CName.DESCRIBE_SESSION).
- withParameters({'sessionId': SESSION_ID}).
- andReturnError(e).
- end();
- let driver = WebDriver.attachToSession(executor, SESSION_ID);
- return driver.getSession().then(session => {
- assert.ok(session instanceof Session);
- assert.strictEqual(session.getId(), SESSION_ID);
- assert.equal(session.getCapabilities().size, 0);
- });
- });
- it('usesActiveFlowByDefault', function() {
- let executor = new FakeExecutor().
- expect(CName.DESCRIBE_SESSION).
- withParameters({'sessionId': SESSION_ID}).
- andReturnSuccess({}).
- end();
- var driver = WebDriver.attachToSession(executor, SESSION_ID);
- assert.equal(driver.controlFlow(), promise.controlFlow());
- return waitForIdle(driver.controlFlow());
- });
- enablePromiseManager(() => {
- it('canAttachInCustomFlow', function() {
- let executor = new FakeExecutor().
- expect(CName.DESCRIBE_SESSION).
- withParameters({'sessionId': SESSION_ID}).
- andReturnSuccess({}).
- end();
- var otherFlow = new promise.ControlFlow();
- var driver = WebDriver.attachToSession(executor, SESSION_ID, otherFlow);
- assert.equal(otherFlow, driver.controlFlow());
- assert.notEqual(otherFlow, promise.controlFlow());
- return waitForIdle(otherFlow);
- });
- });
- });
- describe('testCreateSession', function() {
- it('happyPathWithCapabilitiesHashObject', function() {
- let aSession = new Session(SESSION_ID, {'browserName': 'firefox'});
- let executor = new FakeExecutor().
- expect(CName.NEW_SESSION).
- withParameters({
- 'desiredCapabilities': {'browserName': 'firefox'}
- }).
- andReturnSuccess(aSession).
- end();
- var driver = WebDriver.createSession(executor, {
- 'browserName': 'firefox'
- });
- return driver.getSession().then(v => assert.strictEqual(v, aSession));
- });
- it('happyPathWithCapabilitiesInstance', function() {
- let aSession = new Session(SESSION_ID, {'browserName': 'firefox'});
- let executor = new FakeExecutor().
- expect(CName.NEW_SESSION).
- withParameters({'desiredCapabilities': {'browserName': 'firefox'}}).
- andReturnSuccess(aSession).
- end();
- var driver = WebDriver.createSession(executor, Capabilities.firefox());
- return driver.getSession().then(v => assert.strictEqual(v, aSession));
- });
- it('handles desired and required capabilities', function() {
- let aSession = new Session(SESSION_ID, {'browserName': 'firefox'});
- let executor = new FakeExecutor().
- expect(CName.NEW_SESSION).
- withParameters({
- 'desiredCapabilities': {'foo': 'bar'},
- 'requiredCapabilities': {'bim': 'baz'}
- }).
- andReturnSuccess(aSession).
- end();
- let desired = new Capabilities().set('foo', 'bar');
- let required = new Capabilities().set('bim', 'baz');
- var driver = WebDriver.createSession(executor, {desired, required});
- return driver.getSession().then(v => assert.strictEqual(v, aSession));
- });
- it('failsToCreateSession', function() {
- let executor = new FakeExecutor().
- expect(CName.NEW_SESSION).
- withParameters({'desiredCapabilities': {'browserName': 'firefox'}}).
- andReturnError(new StubError()).
- end();
- var driver =
- WebDriver.createSession(executor, {'browserName': 'firefox'});
- return driver.getSession().then(fail, assertIsStubError);
- });
- it('invokes quit callback if it fails to create a session', function() {
- let called = false;
- let executor = new FakeExecutor()
- .expect(CName.NEW_SESSION)
- .withParameters({'desiredCapabilities': {'browserName': 'firefox'}})
- .andReturnError(new StubError())
- .end();
- var driver =
- WebDriver.createSession(executor, {'browserName': 'firefox'},
- null, () => called = true);
- return driver.getSession().then(fail, err => {
- assert.ok(called);
- assertIsStubError(err);
- });
- });
- it('usesActiveFlowByDefault', function() {
- let executor = new FakeExecutor().
- expect(CName.NEW_SESSION).
- withParameters({'desiredCapabilities': {}}).
- andReturnSuccess(new Session(SESSION_ID)).
- end();
- var driver = WebDriver.createSession(executor, {});
- assert.equal(promise.controlFlow(), driver.controlFlow());
- return waitForIdle(driver.controlFlow());
- });
- enablePromiseManager(() => {
- it('canCreateInCustomFlow', function() {
- let executor = new FakeExecutor().
- expect(CName.NEW_SESSION).
- withParameters({'desiredCapabilities': {}}).
- andReturnSuccess({}).
- end();
- var otherFlow = new promise.ControlFlow();
- var driver = WebDriver.createSession(executor, {}, otherFlow);
- assert.equal(otherFlow, driver.controlFlow());
- assert.notEqual(otherFlow, promise.controlFlow());
- return waitForIdle(otherFlow);
- });
- describe('creation failures bubble up in control flow', function() {
- function runTest(...args) {
- let executor = new FakeExecutor()
- .expect(CName.NEW_SESSION)
- .withParameters({'desiredCapabilities': {'browserName': 'firefox'}})
- .andReturnError(new StubError())
- .end();
- WebDriver.createSession(
- executor, {'browserName': 'firefox'}, ...args);
- return waitForAbort().then(assertIsStubError);
- }
- it('no onQuit callback', () => runTest());
- it('has onQuit callback', () => runTest(null, null, function() {}));
- it('onQuit callback failure suppress creation failure', function() {
- let e = new Error('hi!');
- let executor = new FakeExecutor()
- .expect(CName.NEW_SESSION)
- .withParameters({'desiredCapabilities': {'browserName': 'firefox'}})
- .andReturnError(new StubError())
- .end();
- WebDriver.createSession(
- executor, {'browserName': 'firefox'}, null, () => {throw e});
- return waitForAbort().then(err => assert.strictEqual(err, e));
- });
- });
- });
- });
- it('testDoesNotExecuteCommandIfSessionDoesNotResolve', function() {
- var session = Promise.reject(new StubError);
- return new FakeExecutor().createDriver(session)
- .getTitle()
- .then(_ => assert.fail('should have failed'), assertIsStubError);
- });
- it('testCommandReturnValuesArePassedToFirstCallback', function() {
- let executor = new FakeExecutor().
- expect(CName.GET_TITLE).andReturnSuccess('Google Search').
- end();
- var driver = executor.createDriver();
- return driver.getTitle()
- .then(title => assert.equal('Google Search', title));
- });
- it('testStopsCommandExecutionWhenAnErrorOccurs', function() {
- let e = new error.NoSuchWindowError('window not found');
- let executor = new FakeExecutor().
- expect(CName.SWITCH_TO_WINDOW).
- withParameters({
- 'name': 'foo',
- 'handle': 'foo'
- }).
- andReturnError(e).
- end();
- let driver = executor.createDriver();
- return driver.switchTo().window('foo')
- .then(
- _ => driver.getTitle(), // mock should blow if this gets executed
- v => assert.strictEqual(v, e));
- });
- it('testCanSuppressCommandFailures', function() {
- let e = new error.NoSuchWindowError('window not found');
- let executor = new FakeExecutor().
- expect(CName.SWITCH_TO_WINDOW).
- withParameters({
- 'name': 'foo',
- 'handle': 'foo'
- }).
- andReturnError(e).
- expect(CName.GET_TITLE).
- andReturnSuccess('Google Search').
- end();
- var driver = executor.createDriver();
- driver.switchTo().window('foo')
- .catch(v => assert.strictEqual(v, e));
- driver.getTitle();
- return waitForIdle();
- });
- it('testErrorsPropagateUpToTheRunningApplication', function() {
- let e = new error.NoSuchWindowError('window not found');
- let executor = new FakeExecutor().
- expect(CName.SWITCH_TO_WINDOW).
- withParameters({
- 'name': 'foo',
- 'handle': 'foo'
- }).
- andReturnError(e).
- end();
- return executor.createDriver()
- .switchTo().window('foo')
- .then(_ => assert.fail(), v => assert.strictEqual(v, e));
- });
- it('testErrbacksThatReturnErrorsStillSwitchToCallbackChain', function() {
- let executor = new FakeExecutor().
- expect(CName.SWITCH_TO_WINDOW).
- withParameters({
- 'name': 'foo',
- 'handle': 'foo'
- }).
- andReturnError(new error.NoSuchWindowError('window not found')).
- end();
- var driver = executor.createDriver();
- return driver.switchTo().window('foo').
- catch(function() { return new StubError; });
- then(assertIsStubError, () => assert.fail());
- });
- it('testErrbacksThrownCanOverrideOriginalError', function() {
- let executor = new FakeExecutor().
- expect(CName.SWITCH_TO_WINDOW, {
- 'name': 'foo',
- 'handle': 'foo'
- }).
- andReturnError(new error.NoSuchWindowError('window not found')).
- end();
- var driver = executor.createDriver();
- return driver.switchTo().window('foo')
- .catch(throwStubError)
- .then(assert.fail, assertIsStubError);
- });
- it('testReportsErrorWhenExecutingCommandsAfterExecutingAQuit', function() {
- let executor = new FakeExecutor().
- expect(CName.QUIT).
- end();
- let verifyError = expectedError(
- error.NoSuchSessionError,
- 'This driver instance does not have a valid session ID ' +
- '(did you call WebDriver.quit()?) and may no longer be used.');
- let driver = executor.createDriver();
- return driver.quit()
- .then(_ => driver.get('http://www.google.com'))
- .then(assert.fail, verifyError);
- });
- it('testCallbackCommandsExecuteBeforeNextCommand', function() {
- let executor = new FakeExecutor().
- expect(CName.GET_CURRENT_URL).
- expect(CName.GET, {'url': 'http://www.google.com'}).
- expect(CName.CLOSE).
- expect(CName.GET_TITLE).
- end();
- var driver = executor.createDriver();
- driver.getCurrentUrl().then(function() {
- driver.get('http://www.google.com').then(function() {
- driver.close();
- });
- });
- driver.getTitle();
- return waitForIdle();
- });
- enablePromiseManager(() => {
- it('testEachCallbackFrameRunsToCompletionBeforeTheNext', function() {
- let executor = new FakeExecutor().
- expect(CName.GET_TITLE).
- expect(CName.GET_CURRENT_URL).
- expect(CName.GET_CURRENT_WINDOW_HANDLE).
- expect(CName.CLOSE).
- expect(CName.QUIT).
- end();
- var driver = executor.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();
- });
- });
- describe('returningAPromise', function() {
- it('fromACallback', function() {
- let executor = new FakeExecutor().
- expect(CName.GET_TITLE).
- expect(CName.GET_CURRENT_URL).
- andReturnSuccess('http://www.google.com').
- end();
- var driver = executor.createDriver();
- return driver.getTitle().
- then(function() {
- return driver.getCurrentUrl();
- }).
- then(function(value) {
- assert.equal('http://www.google.com', value);
- });
- });
- it('fromAnErrbackSuppressesTheError', function() {
- let executor = new FakeExecutor().
- expect(CName.SWITCH_TO_WINDOW, {
- 'name': 'foo',
- 'handle': 'foo'
- }).
- andReturnError(new StubError()).
- expect(CName.GET_CURRENT_URL).
- andReturnSuccess('http://www.google.com').
- end();
- var driver = executor.createDriver();
- return driver.switchTo().window('foo').
- catch(function(e) {
- assertIsStubError(e);
- return driver.getCurrentUrl();
- }).
- then(url => assert.equal('http://www.google.com', url));
- });
- });
- describe('customFunctions', function() {
- it('returnsANonPromiseValue', function() {
- var driver = new FakeExecutor().createDriver();
- return driver.call(() => 'abc123').then(function(value) {
- assert.equal('abc123', value);
- });
- });
- enablePromiseManager(() => {
- it('executionOrderWithCustomFunctions', function() {
- var msg = [];
- let executor = new FakeExecutor().
- expect(CName.GET_TITLE).andReturnSuccess('cheese ').
- expect(CName.GET_CURRENT_URL).andReturnSuccess('tasty').
- end();
- var driver = executor.createDriver();
- var pushMsg = msg.push.bind(msg);
- driver.getTitle().then(pushMsg);
- driver.call(() => 'is ').then(pushMsg);
- driver.getCurrentUrl().then(pushMsg);
- driver.call(() => '!').then(pushMsg);
- return waitForIdle().then(function() {
- assert.equal('cheese is tasty!', msg.join(''));
- });
- });
- });
- it('passingArgumentsToACustomFunction', function() {
- var add = function(a, b) {
- return a + b;
- };
- var driver = new FakeExecutor().createDriver();
- return driver.call(add, null, 1, 2).then(function(value) {
- assert.equal(3, value);
- });
- });
- it('passingPromisedArgumentsToACustomFunction', function() {
- var promisedArg = Promise.resolve(2);
- var add = function(a, b) {
- return a + b;
- };
- var driver = new FakeExecutor().createDriver();
- return driver.call(add, null, 1, promisedArg).then(function(value) {
- assert.equal(3, value);
- });
- });
- it('passingArgumentsAndScopeToACustomFunction', function() {
- function Foo(name) {
- this.name = name;
- }
- Foo.prototype.getName = function() {
- return this.name;
- };
- var foo = new Foo('foo');
- var driver = new FakeExecutor().createDriver();
- return driver.call(foo.getName, foo).then(function(value) {
- assert.equal('foo', value);
- });
- });
- it('customFunctionThrowsAnError', function() {
- var driver = new FakeExecutor().createDriver();
- return driver.call(throwStubError).then(fail, assertIsStubError);
- });
- it('customFunctionSchedulesCommands', function() {
- let executor = new FakeExecutor().
- expect(CName.GET_TITLE).
- expect(CName.CLOSE).
- expect(CName.QUIT).
- end();
- var driver = executor.createDriver();
- driver.call(function() {
- driver.getTitle();
- driver.close();
- });
- driver.quit();
- return waitForIdle();
- });
- it('returnsATaskResultAfterSchedulingAnother', function() {
- let executor = new FakeExecutor().
- expect(CName.GET_TITLE).
- andReturnSuccess('Google Search').
- expect(CName.CLOSE).
- end();
- var driver = executor.createDriver();
- return driver.call(function() {
- var title = driver.getTitle();
- driver.close();
- return title;
- }).then(function(title) {
- assert.equal('Google Search', title);
- });
- });
- it('hasANestedCommandThatFails', function() {
- let executor = new FakeExecutor().
- expect(CName.SWITCH_TO_WINDOW, {
- 'name': 'foo',
- 'handle': 'foo'
- }).
- andReturnError(new StubError()).
- end();
- var driver = executor.createDriver();
- return driver.call(function() {
- return driver.switchTo().window('foo');
- }).then(fail, assertIsStubError);
- });
- enablePromiseManager(() => {
- it('doesNotCompleteUntilReturnedPromiseIsResolved', function() {
- var order = [];
- var driver = new FakeExecutor().createDriver();
- var d = 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 new Promise(f => setTimeout(f, 0)).then(function() {
- assert.deepEqual(['a'], order);
- d.fulfill();
- return waitForIdle().then(function() {
- assert.deepEqual(['a', 'b', 'c'], order);
- });
- });
- });
- });
- it('returnsADeferredAction', function() {
- let executor = new FakeExecutor().
- expect(CName.GET_TITLE).andReturnSuccess('Google').
- end();
- var driver = executor.createDriver();
- driver.call(function() {
- return driver.getTitle();
- }).then(function(title) {
- assert.equal('Google', title);
- });
- return waitForIdle();
- });
- });
- describe('nestedCommands', function() {
- enablePromiseManager(() => {
- it('commandExecutionOrder', function() {
- var msg = [];
- var driver = new FakeExecutor().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() {
- assert.equal('acefdb', msg.join(''));
- });
- });
- it('basicUsage', function() {
- var msg = [];
- var driver = new FakeExecutor().createDriver();
- var pushMsg = msg.push.bind(msg);
- driver.call(() => 'cheese ').then(pushMsg);
- driver.call(function() {
- driver.call(() => 'is ').then(pushMsg);
- driver.call(() => 'tasty').then(pushMsg);
- });
- driver.call(() => '!').then(pushMsg);
- return waitForIdle().then(function() {
- assert.equal('cheese is tasty!', msg.join(''));
- });
- });
- it('normalCommandAfterNestedCommandThatReturnsAnAction', function() {
- var msg = [];
- let executor = new FakeExecutor().
- expect(CName.CLOSE).
- end();
- var driver = executor.createDriver();
- driver.call(function() {
- return driver.call(function() {
- msg.push('a');
- return driver.call(() => 'foobar');
- });
- });
- driver.close().then(function() {
- msg.push('b');
- });
- return waitForIdle().then(function() {
- assert.equal('ab', msg.join(''));
- });
- });
- });
- it('canReturnValueFromNestedFunction', function() {
- var driver = new FakeExecutor().createDriver();
- return driver.call(function() {
- return driver.call(function() {
- return driver.call(() => 'foobar');
- });
- }).then(function(value) {
- assert.equal('foobar', value);
- });
- });
- it('errorsBubbleUp_caught', function() {
- var driver = new FakeExecutor().createDriver();
- var result = driver.call(function() {
- return driver.call(function() {
- return driver.call(throwStubError);
- });
- }).then(fail, assertIsStubError);
- return Promise.all([waitForIdle(), result]);
- });
- it('errorsBubbleUp_uncaught', function() {
- var driver = new FakeExecutor().createDriver();
- return driver.call(function() {
- return driver.call(function() {
- return driver.call(throwStubError);
- });
- })
- .then(_ => assert.fail('should have failed'), assertIsStubError);
- });
- it('canScheduleCommands', function() {
- let executor = new FakeExecutor().
- expect(CName.GET_TITLE).
- expect(CName.CLOSE).
- end();
- var driver = executor.createDriver();
- driver.call(function() {
- driver.call(function() {
- driver.getTitle();
- });
- driver.close();
- });
- return waitForIdle();
- });
- });
- describe('WebElementPromise', function() {
- let driver = new FakeExecutor().createDriver();
- it('resolvesWhenUnderlyingElementDoes', function() {
- let el = new WebElement(driver, {'ELEMENT': 'foo'});
- return new WebElementPromise(driver, Promise.resolve(el))
- .then(e => assert.strictEqual(e, el));
- });
- it('resolvesBeforeCallbacksOnWireValueTrigger', function() {
- var el = defer();
- var element = new WebElementPromise(driver, el.promise);
- var messages = [];
- let steps = [
- element.then(_ => messages.push('element resolved')),
- element.getId().then(_ => messages.push('wire value resolved'))
- ];
- el.resolve(new WebElement(driver, {'ELEMENT': 'foo'}));
- return Promise.all(steps).then(function() {
- assert.deepEqual([
- 'element resolved',
- 'wire value resolved'
- ], messages);
- });
- });
- it('isRejectedIfUnderlyingIdIsRejected', function() {
- let element =
- new WebElementPromise(driver, Promise.reject(new StubError));
- return element.then(fail, assertIsStubError);
- });
- });
- describe('executeScript', function() {
- it('nullReturnValue', function() {
- let executor = new FakeExecutor().
- expect(CName.EXECUTE_SCRIPT).
- withParameters({
- 'script': 'return document.body;',
- 'args': []
- }).
- andReturnSuccess(null).
- end();
- var driver = executor.createDriver();
- return driver.executeScript('return document.body;')
- .then((result) => assert.equal(null, result));
- });
- it('primitiveReturnValue', function() {
- let executor = new FakeExecutor().
- expect(CName.EXECUTE_SCRIPT).
- withParameters({
- 'script': 'return document.body;',
- 'args': []
- }).
- andReturnSuccess(123).
- end();
- var driver = executor.createDriver();
- return driver.executeScript('return document.body;')
- .then((result) => assert.equal(123, result));
- });
- it('webElementReturnValue', function() {
- var json = WebElement.buildId('foo');
- let executor = new FakeExecutor().
- expect(CName.EXECUTE_SCRIPT).
- withParameters({
- 'script': 'return document.body;',
- 'args': []
- }).
- andReturnSuccess(json).
- end();
- var driver = executor.createDriver();
- return driver.executeScript('return document.body;')
- .then((element) => element.getId())
- .then((id) => assert.equal(id, 'foo'));
- });
- it('arrayReturnValue', function() {
- var json = [WebElement.buildId('foo')];
- let executor = new FakeExecutor().
- expect(CName.EXECUTE_SCRIPT).
- withParameters({
- 'script': 'return document.body;',
- 'args': []
- }).
- andReturnSuccess(json).
- end();
- var driver = executor.createDriver();
- return driver.executeScript('return document.body;')
- .then(function(array) {
- assert.equal(1, array.length);
- return array[0].getId();
- })
- .then((id) => assert.equal('foo', id));
- });
- it('objectReturnValue', function() {
- var json = {'foo': WebElement.buildId('foo')};
- let executor = new FakeExecutor().
- expect(CName.EXECUTE_SCRIPT).
- withParameters({
- 'script': 'return document.body;',
- 'args': []
- }).
- andReturnSuccess(json).
- end();
- var driver = executor.createDriver();
- var callback;
- return driver.executeScript('return document.body;')
- .then((obj) => obj['foo'].getId())
- .then((id) => assert.equal(id, 'foo'));
- });
- it('scriptAsFunction', function() {
- let executor = new FakeExecutor().
- expect(CName.EXECUTE_SCRIPT).
- withParameters({
- 'script': 'return (' + function() {} +
- ').apply(null, arguments);',
- 'args': []
- }).
- andReturnSuccess(null).
- end();
- var driver = executor.createDriver();
- return driver.executeScript(function() {});
- });
- it('simpleArgumentConversion', function() {
- let executor = new FakeExecutor().
- expect(CName.EXECUTE_SCRIPT).
- withParameters({
- 'script': 'return 1;',
- 'args': ['abc', 123, true, [123, {'foo': 'bar'}]]
- }).
- andReturnSuccess(null).
- end();
- var driver = executor.createDriver();
- return driver.executeScript(
- 'return 1;', 'abc', 123, true, [123, {'foo': 'bar'}]);
- });
- it('webElementArgumentConversion', function() {
- var elementJson = WebElement.buildId('fefifofum');
- let executor = new FakeExecutor().
- expect(CName.EXECUTE_SCRIPT).
- withParameters({
- 'script': 'return 1;',
- 'args': [elementJson]
- }).
- andReturnSuccess(null).
- end();
- var driver = executor.createDriver();
- return driver.executeScript('return 1;',
- new WebElement(driver, 'fefifofum'));
- });
- it('webElementPromiseArgumentConversion', function() {
- var elementJson = WebElement.buildId('bar');
- let executor = new FakeExecutor().
- expect(CName.FIND_ELEMENT,
- {'using': 'css selector', 'value': '*[id="foo"]'}).
- andReturnSuccess(elementJson).
- expect(CName.EXECUTE_SCRIPT).
- withParameters({
- 'script': 'return 1;',
- 'args': [elementJson]
- }).
- andReturnSuccess(null).
- end();
- var driver = executor.createDriver();
- var element = driver.findElement(By.id('foo'));
- return driver.executeScript('return 1;', element);
- });
- it('argumentConversion', function() {
- var elementJson = WebElement.buildId('fefifofum');
- let executor = new FakeExecutor().
- expect(CName.EXECUTE_SCRIPT).
- withParameters({
- 'script': 'return 1;',
- 'args': ['abc', 123, true, elementJson, [123, {'foo': 'bar'}]]
- }).
- andReturnSuccess(null).
- end();
- var driver = executor.createDriver();
- var element = new WebElement(driver, 'fefifofum');
- return driver.executeScript('return 1;',
- 'abc', 123, true, element, [123, {'foo': 'bar'}]);
- });
- it('scriptReturnsAnError', function() {
- let executor = new FakeExecutor().
- expect(CName.EXECUTE_SCRIPT).
- withParameters({
- 'script': 'throw Error(arguments[0]);',
- 'args': ['bam']
- }).
- andReturnError(new StubError).
- end();
- var driver = executor.createDriver();
- return driver.executeScript('throw Error(arguments[0]);', 'bam').
- then(fail, assertIsStubError);
- });
- it('failsIfArgumentIsARejectedPromise', function() {
- let executor = new FakeExecutor();
- var arg = Promise.reject(new StubError);
- arg.catch(function() {}); // Suppress default handler.
- var driver = executor.createDriver();
- return driver.executeScript(function() {}, arg).
- then(fail, assertIsStubError);
- });
- });
- describe('executeAsyncScript', function() {
- it('failsIfArgumentIsARejectedPromise', function() {
- var arg = Promise.reject(new StubError);
- arg.catch(function() {}); // Suppress default handler.
- var driver = new FakeExecutor().createDriver();
- return driver.executeAsyncScript(function() {}, arg).
- then(fail, assertIsStubError);
- });
- });
- describe('findElement', function() {
- it('elementNotFound', function() {
- let executor = new FakeExecutor().
- expect(CName.FIND_ELEMENT,
- {using: 'css selector', value: '*[id="foo"]'}).
- andReturnError(new StubError).
- end();
- var driver = executor.createDriver();
- return driver.findElement(By.id('foo'))
- .then(assert.fail, assertIsStubError);
- });
- it('elementNotFoundInACallback', function() {
- let executor = new FakeExecutor().
- expect(CName.FIND_ELEMENT,
- {using: 'css selector', value: '*[id="foo"]'}).
- andReturnError(new StubError).
- end();
- var driver = executor.createDriver();
- return Promise.resolve()
- .then(_ => driver.findElement(By.id('foo')))
- .then(assert.fail, assertIsStubError);
- });
- it('elementFound', function() {
- let executor = new FakeExecutor().
- expect(CName.FIND_ELEMENT,
- {using: 'css selector', value: '*[id="foo"]'}).
- andReturnSuccess(WebElement.buildId('bar')).
- expect(CName.CLICK_ELEMENT, {'id': WebElement.buildId('bar')}).
- andReturnSuccess().
- end();
- var driver = executor.createDriver();
- var element = driver.findElement(By.id('foo'));
- element.click();
- return waitForIdle();
- });
- it('canUseElementInCallback', function() {
- let executor = new FakeExecutor().
- expect(CName.FIND_ELEMENT,
- {using: 'css selector', value: '*[id="foo"]'}).
- andReturnSuccess(WebElement.buildId('bar')).
- expect(CName.CLICK_ELEMENT, {'id': WebElement.buildId('bar')}).
- andReturnSuccess().
- end();
- var driver = executor.createDriver();
- driver.findElement(By.id('foo')).then(function(element) {
- element.click();
- });
- return waitForIdle();
- });
- it('byJs', function() {
- let executor = new FakeExecutor().
- expect(CName.EXECUTE_SCRIPT, {
- 'script': 'return document.body',
- 'args': []
- }).
- andReturnSuccess(WebElement.buildId('bar')).
- expect(CName.CLICK_ELEMENT, {'id': WebElement.buildId('bar')}).
- end();
- var driver = executor.createDriver();
- var element = driver.findElement(By.js('return document.body'));
- element.click(); // just to make sure
- return waitForIdle();
- });
- it('byJs_returnsNonWebElementValue', function() {
- let executor = new FakeExecutor().
- expect(CName.EXECUTE_SCRIPT, {'script': 'return 123', 'args': []}).
- andReturnSuccess(123).
- end();
- var driver = executor.createDriver();
- return driver.findElement(By.js('return 123'))
- .then(assert.fail, function(e) {
- assertIsInstance(TypeError, e);
- assert.equal(
- 'Custom locator did not return a WebElement', e.message);
- });
- });
- it('byJs_canPassArguments', function() {
- var script = 'return document.getElementsByTagName(arguments[0]);';
- let executor = new FakeExecutor().
- expect(CName.EXECUTE_SCRIPT, {
- 'script': script,
- 'args': ['div']
- }).
- andReturnSuccess(WebElement.buildId('one')).
- end();
- var driver = executor.createDriver();
- driver.findElement(By.js(script, 'div'));
- return waitForIdle();
- });
- it('customLocator', function() {
- let executor = new FakeExecutor().
- expect(CName.FIND_ELEMENTS, {'using': 'css selector', 'value': 'a'}).
- andReturnSuccess([
- WebElement.buildId('foo'),
- WebElement.buildId('bar')]).
- expect(CName.CLICK_ELEMENT, {'id': WebElement.buildId('foo')}).
- andReturnSuccess().
- end();
- var driver = executor.createDriver();
- var element = driver.findElement(function(d) {
- assert.equal(driver, d);
- return d.findElements(By.tagName('a'));
- });
- return element.click();
- });
- it('customLocatorThrowsIfresultIsNotAWebElement', function() {
- var driver = new FakeExecutor().createDriver();
- return driver.findElement(_ => 1)
- .then(assert.fail, function(e) {
- assertIsInstance(TypeError, e);
- assert.equal(
- 'Custom locator did not return a WebElement', e.message);
- });
- });
- });
- describe('findElements', function() {
- it('returnsMultipleElements', function() {
- var ids = ['foo', 'bar', 'baz'];
- let executor = new FakeExecutor().
- expect(CName.FIND_ELEMENTS, {'using':'css selector', 'value':'a'}).
- andReturnSuccess(ids.map(WebElement.buildId)).
- end();
- var driver = executor.createDriver();
- return driver.findElements(By.tagName('a'))
- .then(function(elements) {
- return promise.all(elements.map(function(e) {
- assert.ok(e instanceof WebElement);
- return e.getId();
- }));
- })
- .then((actual) => assert.deepEqual(ids, actual));
- });
- it('byJs', function() {
- var ids = ['foo', 'bar', 'baz'];
- let executor = new FakeExecutor().
- expect(CName.EXECUTE_SCRIPT, {
- 'script': 'return document.getElementsByTagName("div");',
- 'args': []
- }).
- andReturnSuccess(ids.map(WebElement.buildId)).
- end();
- var driver = executor.createDriver();
- return driver.
- findElements(By.js('return document.getElementsByTagName("div");')).
- then(function(elements) {
- return promise.all(elements.map(function(e) {
- assert.ok(e instanceof WebElement);
- return e.getId();
- }));
- }).
- then((actual) => assert.deepEqual(ids, actual));
- });
- it('byJs_filtersOutNonWebElementResponses', function() {
- var ids = ['foo', 'bar', 'baz'];
- var json = [
- WebElement.buildId(ids[0]),
- 123,
- 'a',
- false,
- WebElement.buildId(ids[1]),
- {'not a web element': 1},
- WebElement.buildId(ids[2])
- ];
- let executor = new FakeExecutor().
- expect(CName.EXECUTE_SCRIPT, {
- 'script': 'return document.getElementsByTagName("div");',
- 'args': []
- }).
- andReturnSuccess(json).
- end();
- var driver = executor.createDriver();
- driver.findElements(By.js('return document.getElementsByTagName("div");')).
- then(function(elements) {
- return promise.all(elements.map(function(e) {
- assert.ok(e instanceof WebElement);
- return e.getId();
- }));
- }).
- then((actual) => assert.deepEqual(ids, actual));
- return waitForIdle();
- });
- it('byJs_convertsSingleWebElementResponseToArray', function() {
- let executor = new FakeExecutor().
- expect(CName.EXECUTE_SCRIPT, {
- 'script': 'return document.getElementsByTagName("div");',
- 'args': []
- }).
- andReturnSuccess(WebElement.buildId('foo')).
- end();
- var driver = executor.createDriver();
- return driver.
- findElements(By.js('return document.getElementsByTagName("div");')).
- then(function(elements) {
- return promise.all(elements.map(function(e) {
- assert.ok(e instanceof WebElement);
- return e.getId();
- }));
- }).
- then((actual) => assert.deepEqual(['foo'], actual));
- });
- it('byJs_canPassScriptArguments', function() {
- var script = 'return document.getElementsByTagName(arguments[0]);';
- let executor = new FakeExecutor().
- expect(CName.EXECUTE_SCRIPT, {
- 'script': script,
- 'args': ['div']
- }).
- andReturnSuccess([
- WebElement.buildId('one'),
- WebElement.buildId('two')
- ]).
- end();
- var driver = executor.createDriver();
- return driver.findElements(By.js(script, 'div'))
- then(function(elements) {
- return promise.all(elements.map(function(e) {
- assert.ok(e instanceof WebElement);
- return e.getId();
- }));
- }).
- then((actual) => assert.deepEqual(['one', 'two'], actual));
- });
- });
- describe('sendKeys', function() {
- it('convertsVarArgsIntoStrings_simpleArgs', function() {
- let executor = new FakeExecutor().
- expect(CName.SEND_KEYS_TO_ELEMENT,
- {'id': WebElement.buildId('one'),
- 'text': '12abc3',
- 'value':'12abc3'.split('')}).
- andReturnSuccess().
- end();
- var driver = executor.createDriver();
- var element = new WebElement(driver, 'one');
- element.sendKeys(1, 2, 'abc', 3);
- return waitForIdle();
- });
- it('convertsVarArgsIntoStrings_promisedArgs', function() {
- let executor = new FakeExecutor().
- expect(CName.FIND_ELEMENT,
- {'using':'css selector', 'value':'*[id="foo"]'}).
- andReturnSuccess(WebElement.buildId('one')).
- expect(CName.SEND_KEYS_TO_ELEMENT,
- {'id':WebElement.buildId('one'),
- 'text': 'abc123def',
- 'value':'abc123def'.split('')}).
- andReturnSuccess().
- end();
- var driver = executor.createDriver();
- var element = driver.findElement(By.id('foo'));
- return element.sendKeys(
- Promise.resolve('abc'),
- 123,
- Promise.resolve('def'));
- });
- it('sendKeysWithAFileDetector', function() {
- let executor = new FakeExecutor().
- expect(CName.FIND_ELEMENT,
- {'using':'css selector', 'value':'*[id="foo"]'}).
- andReturnSuccess(WebElement.buildId('one')).
- expect(CName.SEND_KEYS_TO_ELEMENT,
- {'id': WebElement.buildId('one'),
- 'text': 'modified/path',
- 'value':'modified/path'.split('')}).
- andReturnSuccess().
- end();
- let driver = executor.createDriver();
- let handleFile = function(d, path) {
- assert.strictEqual(driver, d);
- assert.equal(path, 'original/path');
- return Promise.resolve('modified/path');
- };
- driver.setFileDetector({handleFile});
- return driver.findElement(By.id('foo')).sendKeys('original/', 'path');
- });
- });
- describe("switchTo()", function() {
- describe("window", function() {
- it('should return a resolved promise when the window is found', function() {
- let executor = new FakeExecutor().
- expect(CName.SWITCH_TO_WINDOW).
- withParameters({
- 'name': 'foo',
- 'handle': 'foo'
- }).
- andReturnSuccess().
- end();
- executor.createDriver().switchTo().window('foo');
- return waitForIdle();
- });
- it('should propagate exceptions', function() {
- let e = new error.NoSuchWindowError('window not found');
- let executor = new FakeExecutor().
- expect(CName.SWITCH_TO_WINDOW).
- withParameters({
- 'name': 'foo',
- 'handle': 'foo'
- }).
- andReturnError(e).
- end();
- return executor.createDriver()
- .switchTo().window('foo')
- .then(assert.fail, v => assert.strictEqual(v, e));
- });
- });
- });
- describe('elementEquality', function() {
- it('isReflexive', function() {
- var a = new WebElement(new FakeExecutor().createDriver(), 'foo');
- return WebElement.equals(a, a).then(assert.ok);
- });
- it('failsIfAnInputElementCouldNotBeFound', function() {
- let id = Promise.reject(new StubError);
- var driver = new FakeExecutor().createDriver();
- var a = new WebElement(driver, 'foo');
- var b = new WebElementPromise(driver, id);
- return WebElement.equals(a, b).then(fail, assertIsStubError);
- });
- });
- describe('waiting', function() {
- describe('supports custom wait functions', function() {
- it('waitSucceeds', function() {
- let executor = new FakeExecutor().
- expect(CName.FIND_ELEMENTS,
- {using: 'css selector', value: '*[id="foo"]'}).
- andReturnSuccess([]).
- times(2).
- expect(CName.FIND_ELEMENTS,
- {using: 'css selector', value: '*[id="foo"]'}).
- andReturnSuccess([WebElement.buildId('bar')]).
- end();
- var driver = executor.createDriver();
- driver.wait(function() {
- return driver.findElements(By.id('foo')).then(els => els.length > 0);
- }, 200);
- return waitForIdle();
- });
- it('waitTimesout_timeoutCaught', function() {
- let executor = new FakeExecutor().
- expect(CName.FIND_ELEMENTS,
- {using: 'css selector', value: '*[id="foo"]'}).
- andReturnSuccess([]).
- anyTimes().
- end();
- var driver = executor.createDriver();
- return driver.wait(function() {
- return driver.findElements(By.id('foo')).then(els => els.length > 0);
- }, 25).then(fail, function(e) {
- assert.equal('Wait timed out after ',
- e.message.substring(0, 'Wait timed out after '.length));
- });
- });
- enablePromiseManager(() => {
- it('waitTimesout_timeoutNotCaught', function() {
- let executor = new FakeExecutor().
- expect(CName.FIND_ELEMENTS,
- {using: 'css selector', value: '*[id="foo"]'}).
- andReturnSuccess([]).
- anyTimes().
- end();
- var driver = executor.createDriver();
- driver.wait(function() {
- return driver.findElements(By.id('foo')).then(els => els.length > 0);
- }, 25);
- return waitForAbort().then(function(e) {
- assert.equal('Wait timed out after ',
- e.message.substring(0, 'Wait timed out after '.length));
- });
- });
- });
- });
- describe('supports condition objects', function() {
- it('wait succeeds', function() {
- let executor = new FakeExecutor()
- .expect(CName.FIND_ELEMENTS,
- {using: 'css selector', value: '*[id="foo"]'})
- .andReturnSuccess([])
- .times(2)
- .expect(CName.FIND_ELEMENTS,
- {using: 'css selector', value: '*[id="foo"]'})
- .andReturnSuccess([WebElement.buildId('bar')])
- .end();
- let driver = executor.createDriver();
- return driver.wait(until.elementLocated(By.id('foo')), 200);
- });
- it('wait times out', function() {
- let executor = new FakeExecutor()
- .expect(CName.FIND_ELEMENTS,
- {using: 'css selector', value: '*[id="foo"]'})
- .andReturnSuccess([])
- .anyTimes()
- .end();
- let driver = executor.createDriver();
- return driver.wait(until.elementLocated(By.id('foo')), 5)
- .then(fail, err => assert.ok(err instanceof error.TimeoutError));
- });
- });
- describe('supports promise objects', function() {
- it('wait succeeds', function() {
- let promise = new Promise(resolve => {
- setTimeout(() => resolve(1), 10);
- });
- let driver = new FakeExecutor().createDriver();
- return driver.wait(promise, 200).then(v => assert.equal(v, 1));
- });
- it('wait times out', function() {
- let promise = new Promise(resolve => {/* never resolves */});
- let driver = new FakeExecutor().createDriver();
- return driver.wait(promise, 5)
- .then(fail, err => assert.ok(err instanceof error.TimeoutError));
- });
- it('wait fails if promise is rejected', function() {
- let err = Error('boom');
- let driver = new FakeExecutor().createDriver();
- return driver.wait(Promise.reject(err), 5)
- .then(fail, e => assert.strictEqual(e, err));
- });
- });
- it('fails if not supported condition type provided', function() {
- let driver = new FakeExecutor().createDriver();
- assert.throws(() => driver.wait({}, 5), TypeError);
- });
- });
- describe('alert handling', function() {
- it('alertResolvesWhenPromisedTextResolves', function() {
- let driver = new FakeExecutor().createDriver();
- let deferredText = defer();
- let alert = new AlertPromise(driver, deferredText.promise);
- deferredText.resolve(new Alert(driver, 'foo'));
- return alert.getText().then(text => assert.equal(text, 'foo'));
- });
- it('cannotSwitchToAlertThatIsNotPresent', function() {
- let e = new error.NoSuchAlertError;
- let executor = new FakeExecutor()
- .expect(CName.GET_ALERT_TEXT)
- .andReturnError(e)
- .end();
- return executor.createDriver()
- .switchTo().alert()
- .then(assert.fail, v => assert.strictEqual(v, e));
- });
- enablePromiseManager(() => {
- it('alertsBelongToSameFlowAsParentDriver', function() {
- let executor = new FakeExecutor()
- .expect(CName.GET_ALERT_TEXT).andReturnSuccess('hello')
- .end();
- var driver = executor.createDriver();
- var otherFlow = new promise.ControlFlow();
- otherFlow.execute(function() {
- driver.switchTo().alert().then(function() {
- assert.strictEqual(
- driver.controlFlow(), promise.controlFlow(),
- 'Alert should belong to the same flow as its parent driver');
- });
- });
- assert.notEqual(otherFlow, driver.controlFlow);
- return Promise.all([
- waitForIdle(otherFlow),
- waitForIdle(driver.controlFlow())
- ]);
- });
- });
- it('commandsFailIfAlertNotPresent', function() {
- let e = new error.NoSuchAlertError;
- let executor = new FakeExecutor()
- .expect(CName.GET_ALERT_TEXT)
- .andReturnError(e)
- .end();
- var driver = executor.createDriver();
- var alert = driver.switchTo().alert();
- var expectError = (v) => assert.strictEqual(v, e);
- return alert.getText()
- .then(fail, expectedError)
- .then(() => alert.accept())
- .then(fail, expectedError)
- .then(() => alert.dismiss())
- .then(fail, expectError)
- .then(() => alert.sendKeys('hi'))
- .then(fail, expectError);
- });
- });
- enablePromiseManager(() => {
- it('testWebElementsBelongToSameFlowAsParentDriver', function() {
- let executor = new FakeExecutor()
- .expect(CName.FIND_ELEMENT,
- {using: 'css selector', value: '*[id="foo"]'})
- .andReturnSuccess(WebElement.buildId('abc123'))
- .end();
- var driver = executor.createDriver();
- var otherFlow = new promise.ControlFlow();
- otherFlow.execute(function() {
- driver.findElement({id: 'foo'}).then(function() {
- assert.equal(driver.controlFlow(), promise.controlFlow());
- });
- });
- assert.notEqual(otherFlow, driver.controlFlow);
- return Promise.all([
- waitForIdle(otherFlow),
- waitForIdle(driver.controlFlow())
- ]);
- });
- });
- it('testFetchingLogs', function() {
- let executor = new FakeExecutor().
- expect(CName.GET_LOG, {'type': 'browser'}).
- andReturnSuccess([
- {'level': 'INFO', 'message': 'hello', 'timestamp': 1234},
- {'level': 'DEBUG', 'message': 'abc123', 'timestamp': 5678}
- ]).
- end();
- var driver = executor.createDriver();
- return driver.manage().logs().get('browser').then(function(entries) {
- assert.equal(2, entries.length);
- assert.ok(entries[0] instanceof logging.Entry);
- assert.equal(logging.Level.INFO.value, entries[0].level.value);
- assert.equal('hello', entries[0].message);
- assert.equal(1234, entries[0].timestamp);
- assert.ok(entries[1] instanceof logging.Entry);
- assert.equal(logging.Level.DEBUG.value, entries[1].level.value);
- assert.equal('abc123', entries[1].message);
- assert.equal(5678, entries[1].timestamp);
- });
- });
- it('testCommandsFailIfInitialSessionCreationFailed', function() {
- var session = Promise.reject(new StubError);
- var driver = new FakeExecutor().createDriver(session);
- var navigateResult = driver.get('some-url').then(fail, assertIsStubError);
- var quitResult = driver.quit().then(fail, assertIsStubError);
- return waitForIdle().then(function() {
- return promise.all(navigateResult, quitResult);
- });
- });
- it('testWebElementCommandsFailIfInitialDriverCreationFailed', function() {
- var session = Promise.reject(new StubError);
- var driver = new FakeExecutor().createDriver(session);
- return driver.findElement(By.id('foo')).click().
- then(fail, assertIsStubError);
- });
- it('testWebElementCommansFailIfElementCouldNotBeFound', function() {
- let e = new error.NoSuchElementError('Unable to find element');
- let executor = new FakeExecutor().
- expect(CName.FIND_ELEMENT,
- {using: 'css selector', value: '*[id="foo"]'}).
- andReturnError(e).
- end();
- var driver = executor.createDriver();
- return driver.findElement(By.id('foo')).click()
- .then(fail, v => assert.strictEqual(v, e));
- });
- it('testCannotFindChildElementsIfParentCouldNotBeFound', function() {
- let e = new error.NoSuchElementError('Unable to find element');
- let executor = new FakeExecutor().
- expect(CName.FIND_ELEMENT,
- {using: 'css selector', value: '*[id="foo"]'}).
- andReturnError(e).
- end();
- var driver = executor.createDriver();
- return driver.findElement(By.id('foo'))
- .findElement(By.id('bar'))
- .findElement(By.id('baz'))
- .then(fail, v => assert.strictEqual(v, e));
- });
- describe('actions()', function() {
- it('failsIfInitialDriverCreationFailed', function() {
- let session = Promise.reject(new StubError('no session for you'));
- let driver = new FakeExecutor().createDriver(session);
- driver.getSession().catch(function() {});
- return driver.
- actions().
- mouseDown().
- mouseUp().
- perform().
- catch(assertIsStubError);
- });
- describe('mouseMove', function() {
- it('noElement', function() {
- let executor = new FakeExecutor()
- .expect(CName.MOVE_TO, {'xoffset': 0, 'yoffset': 125})
- .andReturnSuccess()
- .end();
- return executor.createDriver().
- actions().
- mouseMove({x: 0, y: 125}).
- perform();
- });
- it('element', function() {
- let executor = new FakeExecutor()
- .expect(CName.FIND_ELEMENT,
- {using: 'css selector', value: '*[id="foo"]'})
- .andReturnSuccess(WebElement.buildId('abc123'))
- .expect(CName.MOVE_TO,
- {'element': 'abc123', 'xoffset': 0, 'yoffset': 125})
- .andReturnSuccess()
- .end();
- var driver = executor.createDriver();
- var element = driver.findElement(By.id('foo'));
- return driver.actions()
- .mouseMove(element, {x: 0, y: 125})
- .perform();
- });
- });
- it('supportsMouseDown', function() {
- let executor = new FakeExecutor()
- .expect(CName.MOUSE_DOWN, {'button': Button.LEFT})
- .andReturnSuccess()
- .end();
- return executor.createDriver().
- actions().
- mouseDown().
- perform();
- });
- it('testActionSequence', function() {
- let executor = new FakeExecutor()
- .expect(CName.FIND_ELEMENT,
- {using: 'css selector', value: '*[id="a"]'})
- .andReturnSuccess(WebElement.buildId('id1'))
- .expect(CName.FIND_ELEMENT,
- {using: 'css selector', value: '*[id="b"]'})
- .andReturnSuccess(WebElement.buildId('id2'))
- .expect(CName.SEND_KEYS_TO_ACTIVE_ELEMENT,
- {'value': [Key.SHIFT]})
- .andReturnSuccess()
- .expect(CName.MOVE_TO, {'element': 'id1'})
- .andReturnSuccess()
- .expect(CName.CLICK, {'button': Button.LEFT})
- .andReturnSuccess()
- .expect(CName.MOVE_TO, {'element': 'id2'})
- .andReturnSuccess()
- .expect(CName.CLICK, {'button': Button.LEFT})
- .andReturnSuccess()
- .end();
- var driver = executor.createDriver();
- var element1 = driver.findElement(By.id('a'));
- var element2 = driver.findElement(By.id('b'));
- return driver.actions()
- .keyDown(Key.SHIFT)
- .click(element1)
- .click(element2)
- .perform();
- });
- });
- describe('touchActions()', function() {
- it('failsIfInitialDriverCreationFailed', function() {
- let session = Promise.reject(new StubError);
- let driver = new FakeExecutor().createDriver(session);
- driver.getSession().catch(function() {});
- return driver.
- touchActions().
- scroll({x: 3, y: 4}).
- perform().
- catch(assertIsStubError);
- });
- it('testTouchActionSequence', function() {
- let executor = new FakeExecutor()
- .expect(CName.TOUCH_DOWN, {x: 1, y: 2}).andReturnSuccess()
- .expect(CName.TOUCH_MOVE, {x: 3, y: 4}).andReturnSuccess()
- .expect(CName.TOUCH_UP, {x: 5, y: 6}).andReturnSuccess()
- .end();
- var driver = executor.createDriver();
- return driver.touchActions()
- .tapAndHold({x: 1, y: 2})
- .move({x: 3, y: 4})
- .release({x: 5, y: 6})
- .perform();
- });
- });
- describe('manage()', function() {
- describe('setTimeouts()', function() {
- describe('throws if no timeouts are specified', function() {
- let driver;
- before(() => driver = new FakeExecutor().createDriver());
- it('; no arguments', function() {
- assert.throws(() => driver.manage().setTimeouts(), TypeError);
- });
- it('; ignores unrecognized timeout keys', function() {
- assert.throws(
- () => driver.manage().setTimeouts({foo: 123}), TypeError);
- });
- it('; ignores positional arguments', function() {
- assert.throws(
- () => driver.manage().setTimeouts(1234, 56), TypeError);
- });
- });
- describe('throws timeout is not a number, null, or undefined', () => {
- let driver;
- before(() => driver = new FakeExecutor().createDriver());
- function checkError(e) {
- return e instanceof TypeError
- && /expected "(script|pageLoad|implicit)" to be a number/.test(
- e.message);
- }
- it('script', function() {
- assert.throws(
- () => driver.manage().setTimeouts({script: 'abc'}),
- checkError);
- });
- it('pageLoad', function() {
- assert.throws(
- () => driver.manage().setTimeouts({pageLoad: 'abc'}),
- checkError);
- });
- it('implicit', function() {
- assert.throws(
- () => driver.manage().setTimeouts({implicit: 'abc'}),
- checkError);
- });
- });
- it('can set multiple timeouts', function() {
- let executor = new FakeExecutor()
- .expect(CName.SET_TIMEOUT, {script:1, pageLoad: 2, implicit: 3})
- .andReturnSuccess()
- .end();
- let driver = executor.createDriver();
- return driver.manage()
- .setTimeouts({script: 1, pageLoad: 2, implicit: 3});
- });
- it('falls back to legacy wire format if W3C version fails', () => {
- let executor = new FakeExecutor()
- .expect(CName.SET_TIMEOUT, {implicit: 3})
- .andReturnError(Error('oops'))
- .expect(CName.SET_TIMEOUT, {type: 'implicit', ms: 3})
- .andReturnSuccess()
- .end();
- let driver = executor.createDriver();
- return driver.manage().setTimeouts({implicit: 3});
- });
- describe('deprecated API calls setTimeouts()', function() {
- it('implicitlyWait()', function() {
- let executor = new FakeExecutor()
- .expect(CName.SET_TIMEOUT, {implicit: 3})
- .andReturnSuccess()
- .end();
- let driver = executor.createDriver();
- return driver.manage().timeouts().implicitlyWait(3);
- });
- it('setScriptTimeout()', function() {
- let executor = new FakeExecutor()
- .expect(CName.SET_TIMEOUT, {script: 3})
- .andReturnSuccess()
- .end();
- let driver = executor.createDriver();
- return driver.manage().timeouts().setScriptTimeout(3);
- });
- it('pageLoadTimeout()', function() {
- let executor = new FakeExecutor()
- .expect(CName.SET_TIMEOUT, {pageLoad: 3})
- .andReturnSuccess()
- .end();
- let driver = executor.createDriver();
- return driver.manage().timeouts().pageLoadTimeout(3);
- });
- });
- });
- });
- describe('generator support', function() {
- var driver;
- beforeEach(function() {
- driver = new WebDriver(
- new Session('test-session', {}),
- new ExplodingExecutor());
- });
- it('canUseGeneratorsWithWebDriverCall', function() {
- return driver.call(function* () {
- var x = yield Promise.resolve(1);
- var y = yield Promise.resolve(2);
- return x + y;
- }).then(function(value) {
- assert.deepEqual(3, value);
- });
- });
- it('canDefineScopeOnGeneratorCall', function() {
- return driver.call(function* () {
- var x = yield Promise.resolve(1);
- return this.name + x;
- }, {name: 'Bob'}).then(function(value) {
- assert.deepEqual('Bob1', value);
- });
- });
- it('canSpecifyArgsOnGeneratorCall', function() {
- return driver.call(function* (a, b) {
- var x = yield Promise.resolve(1);
- var y = yield Promise.resolve(2);
- return [x + y, a, b];
- }, null, 'abc', 123).then(function(value) {
- assert.deepEqual([3, 'abc', 123], value);
- });
- });
- it('canUseGeneratorWithWebDriverWait', function() {
- var values = [];
- return driver.wait(function* () {
- yield values.push(1);
- values.push(yield promise.delayed(10).then(function() {
- return 2;
- }));
- yield values.push(3);
- return values.length === 6;
- }, 250).then(function() {
- assert.deepEqual([1, 2, 3, 1, 2, 3], values);
- });
- });
- /**
- * @constructor
- * @implements {CommandExecutor}
- */
- function ExplodingExecutor() {}
- /** @override */
- ExplodingExecutor.prototype.execute = function(command, cb) {
- cb(Error('Unsupported operation'));
- };
- });
- describe('wire format', function() {
- const FAKE_DRIVER = new FakeExecutor().createDriver();
- describe('can serialize', function() {
- function runSerializeTest(input, want) {
- let executor = new FakeExecutor().
- expect(CName.NEW_SESSION).
- withParameters({'desiredCapabilities': want}).
- andReturnSuccess({'browserName': 'firefox'}).
- end();
- return WebDriver.createSession(executor, input)
- .getSession();
- }
- it('function as a string', function() {
- function foo() { return 'foo'; }
- return runSerializeTest(foo, '' + foo);
- });
- it('object with toJSON()', function() {
- return runSerializeTest(
- new Date(605728511546),
- '1989-03-12T17:55:11.546Z');
- });
- it('Session', function() {
- return runSerializeTest(new Session('foo', {}), 'foo');
- });
- it('Capabilities', function() {
- var prefs = new logging.Preferences();
- prefs.setLevel(logging.Type.BROWSER, logging.Level.DEBUG);
- var caps = Capabilities.chrome();
- caps.setLoggingPrefs(prefs);
- return runSerializeTest(
- caps,
- {
- 'browserName': 'chrome',
- 'loggingPrefs': {'browser': 'DEBUG'}
- });
- });
- it('WebElement', function() {
- return runSerializeTest(
- new WebElement(FAKE_DRIVER, 'fefifofum'),
- WebElement.buildId('fefifofum'));
- });
- it('WebElementPromise', function() {
- return runSerializeTest(
- new WebElementPromise(
- FAKE_DRIVER,
- Promise.resolve(new WebElement(FAKE_DRIVER, 'fefifofum'))),
- WebElement.buildId('fefifofum'));
- });
- describe('an array', function() {
- it('with Serializable', function() {
- return runSerializeTest([new Session('foo', {})], ['foo']);
- });
- it('with WebElement', function() {
- return runSerializeTest(
- [new WebElement(FAKE_DRIVER, 'fefifofum')],
- [WebElement.buildId('fefifofum')]);
- });
- it('with WebElementPromise', function() {
- return runSerializeTest(
- [new WebElementPromise(
- FAKE_DRIVER,
- Promise.resolve(new WebElement(FAKE_DRIVER, 'fefifofum')))],
- [WebElement.buildId('fefifofum')]);
- });
- it('complex array', function() {
- var expected = [
- 'abc', 123, true, WebElement.buildId('fefifofum'),
- [123, {'foo': 'bar'}]
- ];
- var element = new WebElement(FAKE_DRIVER, 'fefifofum');
- var input = ['abc', 123, true, element, [123, {'foo': 'bar'}]];
- return runSerializeTest(input, expected);
- });
- it('nested promises', function() {
- return runSerializeTest(
- ['abc', Promise.resolve([123, Promise.resolve(true)])],
- ['abc', [123, true]]);
- });
- });
- describe('an object', function() {
- it('literal', function() {
- var expected = {sessionId: 'foo'};
- return runSerializeTest({sessionId: 'foo'}, expected);
- });
- it('with sub-objects', function() {
- var expected = {sessionId: {value: 'foo'}};
- return runSerializeTest(
- {sessionId: {value: 'foo'}}, expected);
- });
- it('with values that have toJSON', function() {
- return runSerializeTest(
- {a: {b: new Date(605728511546)}},
- {a: {b: '1989-03-12T17:55:11.546Z'}});
- });
- it('with a Session', function() {
- return runSerializeTest(
- {a: new Session('foo', {})},
- {a: 'foo'});
- });
- it('nested', function() {
- var elementJson = WebElement.buildId('fefifofum');
- var expected = {
- 'script': 'return 1',
- 'args': ['abc', 123, true, elementJson, [123, {'foo': 'bar'}]],
- 'sessionId': 'foo'
- };
- var element = new WebElement(FAKE_DRIVER, 'fefifofum');
- var parameters = {
- 'script': 'return 1',
- 'args':['abc', 123, true, element, [123, {'foo': 'bar'}]],
- 'sessionId': new Session('foo', {})
- };
- return runSerializeTest(parameters, expected);
- });
- });
- });
- describe('can deserialize', function() {
- function runDeserializeTest(original, want) {
- let executor = new FakeExecutor()
- .expect(CName.GET_CURRENT_URL)
- .andReturnSuccess(original)
- .end();
- let driver = executor.createDriver();
- return driver.getCurrentUrl().then(function(got) {
- assert.deepEqual(got, want);
- });
- }
- it('primitives', function() {
- return Promise.all([
- runDeserializeTest(1, 1),
- runDeserializeTest('', ''),
- runDeserializeTest(true, true),
- runDeserializeTest(undefined, undefined),
- runDeserializeTest(null, null)
- ]);
- });
- it('simple object', function() {
- return runDeserializeTest(
- {sessionId: 'foo'},
- {sessionId: 'foo'});
- });
- it('nested object', function() {
- return runDeserializeTest(
- {'foo': {'bar': 123}},
- {'foo': {'bar': 123}});
- });
- it('array', function() {
- return runDeserializeTest(
- [{'foo': {'bar': 123}}],
- [{'foo': {'bar': 123}}]);
- });
- it('passes through function properties', function() {
- function bar() {}
- return runDeserializeTest(
- [{foo: {'bar': 123}, func: bar}],
- [{foo: {'bar': 123}, func: bar}]);
- });
- });
- });
- });
|