forked from angular/protractor
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathwddebugger.js
138 lines (126 loc) · 4.33 KB
/
wddebugger.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
var repl = require('repl');
var debuggerCommons = require('../debuggerCommons');
var CommandRepl = require('../modes/commandRepl');
var DebuggerRepl = require('../modes/debuggerRepl');
/**
* BETA BETA BETA
* Custom protractor debugger which steps through one control flow task
* at a time.
*
* @constructor
*/
var WdDebugger = function() {
this.client;
this.replServer;
// repl is broken into 'command repl' and 'debugger repl'.
this.cmdRepl;
this.dbgRepl;
// currentRepl is a pointer to one of them.
this.currentRepl;
};
/**
* Initiate debugger client.
* @private
*/
WdDebugger.prototype.initClient_ = function() {
this.client =
debuggerCommons.attachDebugger(process.argv[2], process.argv[3]);
this.client.once('ready', function() {
console.log(' ready\n');
console.log('press c to continue to the next webdriver command');
console.log('press d to continue to the next debugger statement');
console.log('type "repl" to enter interactive mode');
console.log('type "exit" to break out of interactive mode');
console.log('press ^C to exit');
console.log();
});
};
/**
* Eval function for processing a single step in repl.
* @private
* @param {string} cmd
* @param {object} context
* @param {string} filename
* @param {function} callback
*/
WdDebugger.prototype.stepEval_ = function(cmd, context, filename, callback) {
// The loop won't come back until 'callback' is called.
// Note - node's debugger gets around this by adding custom objects
// named 'c', 's', etc to the REPL context. They have getters which
// perform the desired function, and the callback is stored for later use.
// Think about whether this is a better pattern.
cmd = debuggerCommons.trimReplCmd(cmd);
if (this.currentRepl === this.dbgRepl && cmd === 'repl' ||
this.currentRepl === this.cmdRepl && cmd === 'exit') {
// switch repl mode
this.currentRepl =
this.currentRepl === this.dbgRepl ? this.cmdRepl : this.dbgRepl;
// For node backward compatibility. In older versions of node `setPrompt`
// does not exist, and we set the prompt by overwriting `replServer.prompt`
// directly.
if (this.replServer.setPrompt) {
this.replServer.setPrompt(this.currentRepl.prompt);
} else {
this.replServer.prompt = this.currentRepl.prompt;
}
this.replServer.complete = this.currentRepl.complete.bind(this.currentRepl);
callback();
} else if (this.currentRepl === this.cmdRepl) {
// If we are currently in command repl mode.
this.cmdRepl.stepEval(cmd, function(err, res) {
// Result is a string representation of the evaluation, so we console.log
// the result to print it properly. Then we callback with undefined so
// that the result isn't printed twice.
if (res !== undefined) {
console.log(res);
}
callback(err, undefined);
});
} else {
this.dbgRepl.stepEval(cmd, callback);
}
};
/**
* Instantiate all repl objects, and debuggerRepl as current and start repl.
* @private
*/
WdDebugger.prototype.initRepl_ = function() {
var self = this;
this.cmdRepl = new CommandRepl(this.client);
this.dbgRepl = new DebuggerRepl(this.client);
this.currentRepl = this.dbgRepl;
// We want the prompt to show up only after the controlflow text prints.
this.dbgRepl.printControlFlow_(function() {
// Backward compatibility: node version 0.8.14 has a number of built in
// libraries for repl, and the keyword 'repl' clashes with our usage.
if (repl._builtinLibs && repl._builtinLibs.indexOf('repl') > -1) {
repl._builtinLibs.splice(repl._builtinLibs.indexOf('repl'), 1);
}
self.replServer = repl.start({
prompt: self.currentRepl.prompt,
input: process.stdin,
output: process.stdout,
eval: self.stepEval_.bind(self),
useGlobal: false,
ignoreUndefined: true
});
self.replServer.complete = self.currentRepl.complete.bind(self.currentRepl);
self.replServer.on('exit', function() {
console.log('Exiting debugger.');
self.client.req({command: 'disconnect'}, function() {
// Intentionally blank.
});
});
});
};
/**
* Initiate the debugger.
* @public
*/
WdDebugger.prototype.init = function() {
console.log('------- WebDriver Debugger -------');
this.initClient_();
this.initRepl_();
};
var wdDebugger = new WdDebugger();
wdDebugger.init();