forked from angular/protractor
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathexplorer.js
155 lines (141 loc) · 4.19 KB
/
explorer.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
151
152
153
154
155
var repl = require('repl');
var debuggerCommons = require('../debuggerCommons');
var CommandRepl = require('../modes/commandRepl');
/**
* BETA BETA BETA
* Custom explorer to test protractor commands.
*
* @constructor
*/
var WdRepl = function() {
this.client;
};
/**
* Initiate debugger client.
* @private
*/
WdRepl.prototype.initClient_ = function() {
this.client =
debuggerCommons.attachDebugger(process.argv[2], process.argv[3]);
};
/**
* Instantiate a server to handle IO.
* @param {number} port The port to start the server.
* @private
*/
WdRepl.prototype.initServer_ = function(port) {
var net = require('net');
var self = this;
var cmdRepl = new CommandRepl(this.client);
var received = '';
net.createServer(function(sock) {
sock.on('data', function(data) {
received += data.toString();
var eolIndex = received.indexOf('\r\n');
if (eolIndex === 0) {
return;
}
var input = received.substring(0, eolIndex);
received = received.substring(eolIndex + 2);
if (data[0] === 0x1D) {
// '^]': term command
self.client.req({command: 'disconnect'}, function() {
// Intentionally blank.
});
sock.end();
} else if (input[input.length - 1] === '\t') {
// If the last character is the TAB key, this is an autocomplete
// request. We use everything before the TAB as the init data to feed
// into autocomplete.
input = input.substring(0, input.length - 1);
cmdRepl.complete(input, function(err, res) {
if (err) {
sock.write('ERROR: ' + err + '\r\n');
} else {
sock.write(JSON.stringify(res) + '\r\n');
}
});
} else {
// Normal input
input = input.trim();
cmdRepl.stepEval(input, function(err, res) {
if (err) {
sock.write('ERROR: ' + err + '\r\n');
return;
}
if (res === undefined) {
res = '';
}
sock.write(res + '\r\n');
});
}
});
}).listen(port);
console.log('Server listening on 127.0.0.1:' + port);
};
/**
* Instantiate a repl to handle IO.
* @private
*/
WdRepl.prototype.initRepl_ = function() {
var self = this;
var cmdRepl = new CommandRepl(this.client);
// Eval function for processing a single step in repl.
var stepEval = function(cmd, context, filename, callback) {
// The command that eval feeds is of the form '(CMD\n)', so we trim the
// double quotes and new line.
cmd = debuggerCommons.trimReplCmd(cmd);
cmdRepl.stepEval(cmd, function(err, res) {
// Result is a string representation of the evaluation.
if (res !== undefined) {
console.log(res);
}
callback(err, undefined);
});
};
var replServer = repl.start({
prompt: cmdRepl.prompt,
input: process.stdin,
output: process.stdout,
eval: stepEval,
useGlobal: false,
ignoreUndefined: true
});
replServer.complete = cmdRepl.complete.bind(cmdRepl);
replServer.on('exit', function() {
console.log('Exiting...');
self.client.req({command: 'disconnect'}, function() {
// Intentionally blank.
});
});
};
/**
* Instantiate a repl or a server.
* @private
*/
WdRepl.prototype.initReplOrServer_ = function() {
// Note instead of starting either repl or server, another approach is to
// feed the server socket into the repl as the input/output streams. The
// advantage is that the process becomes much more realistic because now we're
// using the normal repl. However, it was not possible to test autocomplete
// this way since we cannot immitate the TAB key over the wire.
var debuggerServerPort = process.argv[4];
if (debuggerServerPort) {
this.initServer_(debuggerServerPort);
} else {
this.initRepl_();
}
};
/**
* Initiate the debugger.
* @public
*/
WdRepl.prototype.init = function() {
console.log('Type <tab> to see a list of locator strategies.');
console.log('Use the `list` helper function to find elements by strategy:');
console.log(' e.g., list(by.binding(\'\')) gets all bindings.');
this.initClient_();
this.initReplOrServer_();
};
var wdRepl = new WdRepl();
wdRepl.init();