diff --git a/lib/driver.js b/lib/driver.js index 6ee4bd713..d1f7b0f11 100644 --- a/lib/driver.js +++ b/lib/driver.js @@ -12,15 +12,6 @@ class BaseDriver extends MobileJsonWireProtocol { this.sessionId = null; this.caps = null; this.lastCommand = B.delay(0); - - // crazy sebv queue - this.createTask = (cmd, args) => { - this.lastCommand = this.lastCommand.then(() => { - return this[cmd](...args); - }); - return this.lastCommand; - }; - } sessionExists (sessionId) { @@ -32,7 +23,7 @@ class BaseDriver extends MobileJsonWireProtocol { return !!caps; } - execute (cmd, ...args) { + async execute (cmd, ...args) { if (!this.sessionId && !_.contains(NO_SESSION_ID_COMMANDS, cmd)) { throw new errors.NoSuchDriverError(); } @@ -40,7 +31,12 @@ class BaseDriver extends MobileJsonWireProtocol { if (!this[cmd]) { throw new errors.NotYetImplementedError(); } - return this.createTask(cmd, args); + + let ret = this.lastCommand.then(() => { + return this[cmd](...args); + }); + this.lastCommand = ret.catch(() => {}); + return ret; } } diff --git a/test/driver-specs.js b/test/driver-specs.js index 6392eb709..757e6fe2e 100644 --- a/test/driver-specs.js +++ b/test/driver-specs.js @@ -80,6 +80,78 @@ describe('BaseDriver', () => { url.should.eventually.be.rejectedWith('session'); }); + describe('command queue', () => { + let d = new BaseDriver(); + let waitMs = 10; + d.getStatus = async () => { + await B.delay(waitMs); + return Date.now(); + }.bind(d); + + d.getSessions = async () => { + await B.delay(waitMs); + throw new Error("multipass"); + }.bind(d); + + it('should queue commands and execute/respond in the order received', async () => { + let numCmds = 10; + let cmds = []; + for (let i = 0; i < numCmds; i++) { + cmds.push(d.execute('getStatus')); + } + let results = await B.all(cmds); + for (let i = 1; i < numCmds; i++) { + if (results[i] <= results[i - 1]) { + throw new Error("Got result out of order"); + } + } + }); + + it('should handle errors correctly when queuing', async () => { + let numCmds = 10; + let cmds = []; + for (let i = 0; i < numCmds; i++) { + if (i === 5) { + cmds.push(d.execute('getSessions')); + } else { + cmds.push(d.execute('getStatus')); + } + } + let results = await B.settle(cmds); + for (let i = 1; i < 5; i++) { + if (results[i].value() <= results[i - 1].value()) { + throw new Error("Got result out of order"); + } + } + results[5].reason().message.should.contain("multipass"); + for (let i = 7; i < numCmds; i++) { + if (results[i].value() <= results[i - 1].value()) { + throw new Error("Got result out of order"); + } + } + }); + + it('should not care if queue empties for a bit', async () => { + let numCmds = 10; + let cmds = []; + for (let i = 0; i < numCmds; i++) { + cmds.push(d.execute('getStatus')); + } + let results = await B.all(cmds); + cmds = []; + for (let i = 0; i < numCmds; i++) { + cmds.push(d.execute('getStatus')); + } + results = await B.all(cmds); + for (let i = 1; i < numCmds; i++) { + if (results[i] <= results[i - 1]) { + throw new Error("Got result out of order"); + } + } + }); + + }); + }); describe('BaseDriver via HTTP', () => { @@ -108,35 +180,6 @@ describe('BaseDriver via HTTP', () => { }); }); - describe('command queue', () => { - function buildStatusRequest () { - return request({ - url: 'http://localhost:8181/wd/hub/status', - method: 'GET', - json: true - }); - } - it('should queue commands and execute/respond in the order received', async () => { - let numCmds = 10; - let waitMs = 10; - let cmds = []; - for (let i = 0; i < numCmds; i++) { - cmds.push(buildStatusRequest()); - } - d.getStatus = async () => { - await B.delay(waitMs); - return Date.now(); - }.bind(d); - - let results = await B.all(cmds); - for (let i = 1; i < numCmds; i++) { - if (results[i].value <= results[i - 1].value) { - throw new Error("Got result out of order"); - } - } - }); - }); - describe('command timeouts', () => { it.skip('should throw NYI for commands not implemented', async () => { });