forked from angular/protractor
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore(promises) move interactive_test_util off q, rework to ES6 syntax (
angular#5037) - move interactive_test_util off q - rework to ES6 syntax
- Loading branch information
Showing
5 changed files
with
174 additions
and
153 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,150 +1,169 @@ | ||
var child_process = require('child_process'), | ||
q = require('q'), | ||
net = require('net'); | ||
const child_process = require('child_process'); | ||
const net = require('net'); | ||
|
||
var TIMEOUT = 10000; | ||
const TIMEOUT = 10000; | ||
|
||
// An instance of a protractor debugger server. | ||
var Server = function(serverStartCmd, port) { | ||
class Server { | ||
constructor(command, port) { | ||
this.command = command; | ||
this.port = port; | ||
} | ||
// Start protractor and its debugger server as a child process. | ||
this.start = function() { | ||
var deferred = q.defer(); | ||
var received = ''; | ||
|
||
serverStartCmd += ' --debuggerServerPort ' + port; | ||
serverStartCmd = serverStartCmd.split(/\s/); | ||
var test_process = child_process.spawn(serverStartCmd[0], | ||
serverStartCmd.slice(1)); | ||
|
||
var timeoutObj = setTimeout(function() { | ||
var errMsg = 'Did not start interactive server in ' + TIMEOUT/1000 + 's.'; | ||
if (received) { | ||
errMsg += ' Server startup output: ' + received; | ||
} | ||
deferred.reject(errMsg); | ||
}, TIMEOUT); | ||
test_process.stdout.on('data', function(data) { | ||
received += data; | ||
if (received.indexOf('Server listening on 127.0.0.1:' + port) >= 0) { | ||
clearTimeout(timeoutObj); | ||
// Add a small time for browser to get ready | ||
setTimeout(deferred.resolve, 2000); | ||
} | ||
}); | ||
start() { | ||
return new Promise((resolve, reject) => { | ||
let received = ''; | ||
|
||
const commands = `${this.command} --debuggerServerPort ${this.port}`.split(/\s/); | ||
const command = commands[0]; | ||
const args = commands.slice(1); | ||
const test_process = child_process.spawn(command, args); | ||
|
||
const timeout = setTimeout(() => { | ||
let errorMessage = `Did not start interactive server in ${TIMEOUT/1000}s.`; | ||
if (received) { | ||
errorMessage += ` Server startup output: ${received}`; | ||
} | ||
reject(errorMessage); | ||
}, TIMEOUT); | ||
|
||
test_process.stdout.on('data', (data) => { | ||
received += data; | ||
if (received.indexOf(`Server listening on 127.0.0.1:${this.port}`) !== -1) { | ||
clearTimeout(timeout); | ||
// Add a small time for browser to get ready | ||
setTimeout(resolve(), 2000); | ||
} | ||
}); | ||
|
||
test_process.stderr.on('data', function(data) { | ||
received += data; | ||
test_process.stderr.on('data', (data) => { | ||
received += data; | ||
}); | ||
}); | ||
|
||
return deferred.promise; | ||
}; | ||
}; | ||
|
||
// A client to attach to Protractor's debugger server and exchange data. | ||
var Client = function(port) { | ||
var socket; | ||
|
||
// Connect to the server. | ||
this.connect = function() { | ||
var deferred = q.defer(); | ||
socket = net.connect({port: port}, function() { | ||
deferred.resolve(); | ||
} | ||
} | ||
|
||
// A client to attach to Protractor's debugger server and exchange data. | ||
class Client { | ||
constructor(port) { | ||
this.port = port; | ||
this.socket = undefined; | ||
} | ||
|
||
// Connect to the server. | ||
connect() { | ||
return new Promise(resolve => { | ||
this.socket = net.connect({port: this.port}, () => { | ||
resolve(); | ||
}); | ||
}); | ||
return deferred.promise; | ||
}; | ||
} | ||
|
||
// Disconnect from the server. | ||
this.disconnect = function() { | ||
socket.end(); | ||
}; | ||
|
||
// Send a command to the server and wait for a response. Return response as a | ||
// promise. | ||
this.sendCommand = function(cmd) { | ||
var deferred = q.defer(); | ||
var received = ''; | ||
var timeoutObj = setTimeout(function() { | ||
var errMsg = 'Command <' + JSON.stringify(cmd) + | ||
'> did not receive a response in ' + TIMEOUT/1000 + 's.'; | ||
if (received) { | ||
errMsg += ' Received messages so far: ' + received; | ||
} | ||
deferred.reject(errMsg); | ||
}, TIMEOUT); | ||
|
||
var ondata = function(data) { | ||
received += data.toString(); | ||
var i = received.indexOf('\r\n'); | ||
if (i >= 0) { | ||
clearTimeout(timeoutObj); | ||
var response = received.substring(0, i).trim(); | ||
deferred.resolve(response); | ||
} | ||
}; | ||
socket.on('data', ondata); | ||
|
||
var onerror = function(data) { | ||
deferred.reject('Received error: ' + data); | ||
}; | ||
socket.on('error', onerror); | ||
|
||
socket.write(cmd + '\r\n'); | ||
return deferred.promise.fin(function() { | ||
clearTimeout(timeoutObj); | ||
socket.removeListener('data', ondata); | ||
socket.removeListener('error', onerror); | ||
disconnect() { | ||
this.socket.end(); | ||
} | ||
|
||
// Send a command to the server and wait for a response. Return response as a | ||
// promise. | ||
sendCommand(command) { | ||
let timeout; | ||
let ondata; | ||
let onerror; | ||
|
||
return new Promise((resolve, reject) => { | ||
let received = ''; | ||
timeout = setTimeout(() => { | ||
let errorMessage = `Command ${JSON.stringify(command)} did not receive a response in ${TIMEOUT/1000}s.`; | ||
if (received) { | ||
errorMessage += ` Received messages so far: ${received}`; | ||
} | ||
reject(errorMessage); | ||
}, TIMEOUT); | ||
|
||
ondata = (data) => { | ||
received += data.toString(); | ||
let i = received.indexOf('\r\n'); | ||
if (i !== -1) { | ||
clearTimeout(timeout); | ||
const response = received.substring(0, i).trim(); | ||
resolve(response); | ||
} | ||
}; | ||
this.socket.on('data', ondata); | ||
|
||
onerror = (data) => { | ||
reject(`Received error: ${data}`); | ||
}; | ||
this.socket.on('error', onerror); | ||
|
||
this.socket.write(`${command}\r\n`); | ||
}).finally(() => { | ||
clearTimeout(timeout); | ||
this.socket.removeListener('data', ondata); | ||
this.socket.removeListener('error', onerror); | ||
}); | ||
}; | ||
}; | ||
} | ||
} | ||
|
||
/** | ||
* Util for running an interactive Protractor test. | ||
*/ | ||
exports.InteractiveTest = function(interactiveServerStartCmd, port) { | ||
var expectations = []; | ||
|
||
// Adds a command to send as well as the response to verify against. | ||
module.exports = class InteractiveTest { | ||
constructor(command, port) { | ||
this.command = command; | ||
this.port = port; | ||
this.expectations = []; | ||
} | ||
|
||
// Adds a command to send as well as the response to verify against. | ||
// If opt_expectedResult is undefined, the test will still wait for the server | ||
// to respond after sending the command, but will not verify against it. | ||
// Note, this does not actually interact with the server, but simply adds the | ||
// Note, this does not actually interact with the server, but simply adds the | ||
// command to a queue. | ||
this.addCommandExpectation = function(command, opt_expectedResult) { | ||
expectations.push({ | ||
addCommandExpectation(command, opt_expectedResult) { | ||
this.expectations.push({ | ||
command: command, | ||
expectedResult: opt_expectedResult | ||
}); | ||
}; | ||
} | ||
|
||
// Execute the interactive test. This will first start Protractor and its | ||
// debugger server. Then it will connect to the server. Finally, it will | ||
// debugger server. Then it will connect to the server. Finally, it will | ||
// send the queue of commands against the server sequentially and verify the | ||
// response from the server if needed. | ||
this.run = function() { | ||
var server = new Server(interactiveServerStartCmd, port); | ||
return server.start().then(function() { | ||
var client = new Client(port); | ||
return client.connect().then(function() { | ||
var verifyAll = function(i) { | ||
if (i < expectations.length) { | ||
var expectedResult = expectations[i].expectedResult; | ||
var command = expectations[i].command; | ||
return client.sendCommand(command).then(function(response) { | ||
if (expectedResult !== undefined && expectedResult !== response) { | ||
throw ('Command <' + JSON.stringify(command) + '> received: ' + | ||
response + ', but expects: ' + expectedResult); | ||
} else { | ||
return verifyAll(i + 1); | ||
} | ||
}); | ||
} | ||
}; | ||
return verifyAll(0); | ||
}).fin(function() { | ||
// '^]' This is the term signal. | ||
client.sendCommand(String.fromCharCode(0x1D)); | ||
client.disconnect(); | ||
}); | ||
}).done(); | ||
}; | ||
// response from the server if needed. | ||
async run() { | ||
let failed = false; | ||
let successfulCommands = []; | ||
let failedCommands = []; | ||
|
||
const server = new Server(this.command, this.port); | ||
await server.start(); | ||
const client = new Client(this.port); | ||
await client.connect(); | ||
for (let expectation of this.expectations) { | ||
const expectedResult = expectation.expectedResult; | ||
const command = expectation.command; | ||
const response = await client.sendCommand(command); | ||
if (expectedResult !== undefined && expectedResult !== response) { | ||
failed = true; | ||
successfulCommands.push( | ||
`Command ${JSON.stringify(command)} received: ${response}, but expects: ${expectedResult}\n` | ||
); | ||
} else { | ||
failedCommands.push('Command response as expected\n'); | ||
} | ||
} | ||
console.log('Successful commands: '); | ||
for (let command of successfulCommands) { | ||
console.log(command); | ||
} | ||
console.log('Failed commands: '); | ||
for (let command of failedCommands) { | ||
console.log(command); | ||
} | ||
console.log('Summary: ' + (failed ? 'fail' : 'pass')); | ||
await client.sendCommand(String.fromCharCode(0x1D)); | ||
await client.disconnect(); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,12 @@ | ||
var env = require('../../spec/environment.js'); | ||
var InteractiveTest = require('./interactive_test_util').InteractiveTest; | ||
var port = env.interactiveTestPort; | ||
var test = new InteractiveTest( | ||
'node built/cli.js --baseUrl http://localhost:' + env.webServerDefaultPort + | ||
const env = require('../../spec/environment.js'); | ||
const InteractiveTest = require('./interactive_test_util'); | ||
const port = env.interactiveTestPort; | ||
const test = new InteractiveTest( | ||
'node built/cli.js --baseUrl http://localhost:' + env.webServerDefaultPort + | ||
'/ng1 --elementExplorer true', port); | ||
|
||
// Check we automatically go to to baseUrl. | ||
test.addCommandExpectation( | ||
'browser.driver.getCurrentUrl()', | ||
'http://localhost:' + env.webServerDefaultPort + '/ng1/#/form'); | ||
test.run(); | ||
'browser.driver.getCurrentUrl()', | ||
'http://localhost:' + env.webServerDefaultPort + 'asdasd/asdng1/#/form'); | ||
test.run().then(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,6 @@ | ||
{ | ||
"strict": false, | ||
"esversion": 6, | ||
"predef": [ | ||
"protractor", | ||
"browser", | ||
|