This repository was archived by the owner on Jul 29, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
/
Copy pathinteractive_test_util.js
150 lines (133 loc) · 4.68 KB
/
interactive_test_util.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
var child_process = require('child_process'),
q = require('q'),
net = require('net');
var TIMEOUT = 10000;
// An instance of a protractor debugger server.
var Server = function(serverStartCmd, 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);
}
});
test_process.stderr.on('data', function(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();
});
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);
});
};
};
/**
* 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.
// 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
// command to a queue.
this.addCommandExpectation = function(command, opt_expectedResult) {
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
// 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();
};
};