poltergeist 0.6.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +77 -40
- data/lib/capybara/poltergeist.rb +11 -11
- data/lib/capybara/poltergeist/browser.rb +35 -12
- data/lib/capybara/poltergeist/client.rb +9 -12
- data/lib/capybara/poltergeist/client/agent.coffee +99 -6
- data/lib/capybara/poltergeist/client/browser.coffee +57 -79
- data/lib/capybara/poltergeist/client/compiled/agent.js +179 -19
- data/lib/capybara/poltergeist/client/compiled/browser.js +109 -81
- data/lib/capybara/poltergeist/client/compiled/connection.js +8 -1
- data/lib/capybara/poltergeist/client/compiled/main.js +75 -34
- data/lib/capybara/poltergeist/client/compiled/node.js +32 -39
- data/lib/capybara/poltergeist/client/compiled/web_page.js +118 -41
- data/lib/capybara/poltergeist/client/main.coffee +11 -23
- data/lib/capybara/poltergeist/client/node.coffee +16 -33
- data/lib/capybara/poltergeist/client/web_page.coffee +57 -26
- data/lib/capybara/poltergeist/driver.rb +36 -6
- data/lib/capybara/poltergeist/errors.rb +4 -15
- data/lib/capybara/poltergeist/json.rb +25 -0
- data/lib/capybara/poltergeist/network_traffic.rb +6 -0
- data/lib/capybara/poltergeist/network_traffic/request.rb +26 -0
- data/lib/capybara/poltergeist/network_traffic/response.rb +40 -0
- data/lib/capybara/poltergeist/node.rb +10 -6
- data/lib/capybara/poltergeist/version.rb +1 -1
- data/lib/capybara/poltergeist/web_socket_server.rb +3 -0
- metadata +112 -23
@@ -1,168 +1,183 @@
|
|
1
|
-
|
1
|
+
|
2
2
|
Poltergeist.Browser = (function() {
|
3
|
-
|
3
|
+
|
4
|
+
function Browser(owner, width, height) {
|
4
5
|
this.owner = owner;
|
6
|
+
this.width = width || 1024;
|
7
|
+
this.height = height || 768;
|
5
8
|
this.state = 'default';
|
6
9
|
this.page_id = 0;
|
7
10
|
this.resetPage();
|
8
11
|
}
|
12
|
+
|
9
13
|
Browser.prototype.resetPage = function() {
|
14
|
+
var _this = this;
|
10
15
|
if (this.page != null) {
|
11
16
|
this.page.release();
|
12
17
|
}
|
13
|
-
this.page = new Poltergeist.WebPage;
|
14
|
-
this.page.onLoadStarted =
|
15
|
-
if (
|
16
|
-
return
|
18
|
+
this.page = new Poltergeist.WebPage(this.width, this.height);
|
19
|
+
this.page.onLoadStarted = function() {
|
20
|
+
if (_this.state === 'clicked') {
|
21
|
+
return _this.state = 'loading';
|
17
22
|
}
|
18
|
-
}
|
19
|
-
this.page.
|
20
|
-
if (
|
21
|
-
|
22
|
-
return this.state = 'default';
|
23
|
+
};
|
24
|
+
this.page.onNavigationRequested = function(url, navigation) {
|
25
|
+
if (_this.state === 'clicked' && navigation === 'FormSubmitted') {
|
26
|
+
return _this.state = 'loading';
|
23
27
|
}
|
24
|
-
}
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
+
};
|
29
|
+
this.page.onLoadFinished = function(status) {
|
30
|
+
if (_this.state === 'loading') {
|
31
|
+
_this.sendResponse(status);
|
32
|
+
return _this.state = 'default';
|
33
|
+
}
|
34
|
+
};
|
35
|
+
return this.page.onInitialized = function() {
|
36
|
+
return _this.page_id += 1;
|
37
|
+
};
|
28
38
|
};
|
39
|
+
|
29
40
|
Browser.prototype.sendResponse = function(response) {
|
30
41
|
var errors;
|
31
42
|
errors = this.page.errors();
|
32
43
|
if (errors.length > 0) {
|
33
44
|
this.page.clearErrors();
|
34
|
-
|
45
|
+
throw new Poltergeist.JavascriptError(errors);
|
35
46
|
} else {
|
36
47
|
return this.owner.sendResponse(response);
|
37
48
|
}
|
38
49
|
};
|
39
|
-
|
50
|
+
|
51
|
+
Browser.prototype.node = function(page_id, id) {
|
40
52
|
if (page_id === this.page_id) {
|
41
|
-
return
|
53
|
+
return this.page.get(id);
|
42
54
|
} else {
|
43
|
-
|
55
|
+
throw new Poltergeist.ObsoleteNode;
|
44
56
|
}
|
45
57
|
};
|
46
|
-
|
47
|
-
|
48
|
-
page_id = arguments[0], id = arguments[1], fn = arguments[2], args = 4 <= arguments.length ? __slice.call(arguments, 3) : [];
|
49
|
-
callback = args.pop();
|
50
|
-
return this.getNode(page_id, id, function(node) {
|
51
|
-
var result;
|
52
|
-
result = node[fn].apply(node, args);
|
53
|
-
if (result instanceof Poltergeist.ObsoleteNode) {
|
54
|
-
return this.owner.sendError(result);
|
55
|
-
} else {
|
56
|
-
return callback.call(this, result, node);
|
57
|
-
}
|
58
|
-
});
|
59
|
-
};
|
60
|
-
Browser.prototype.visit = function(url) {
|
58
|
+
|
59
|
+
Browser.prototype.visit = function(url, headers) {
|
61
60
|
this.state = 'loading';
|
62
|
-
return this.page.open(url
|
61
|
+
return this.page.open(url, {
|
62
|
+
operation: "get",
|
63
|
+
headers: headers
|
64
|
+
});
|
63
65
|
};
|
66
|
+
|
64
67
|
Browser.prototype.current_url = function() {
|
65
68
|
return this.sendResponse(this.page.currentUrl());
|
66
69
|
};
|
70
|
+
|
71
|
+
Browser.prototype.status_code = function() {
|
72
|
+
return this.sendResponse(this.page.statusCode());
|
73
|
+
};
|
74
|
+
|
67
75
|
Browser.prototype.body = function() {
|
68
76
|
return this.sendResponse(this.page.content());
|
69
77
|
};
|
78
|
+
|
70
79
|
Browser.prototype.source = function() {
|
71
80
|
return this.sendResponse(this.page.source());
|
72
81
|
};
|
82
|
+
|
73
83
|
Browser.prototype.find = function(selector) {
|
74
84
|
return this.sendResponse({
|
75
85
|
page_id: this.page_id,
|
76
86
|
ids: this.page.find(selector)
|
77
87
|
});
|
78
88
|
};
|
89
|
+
|
79
90
|
Browser.prototype.find_within = function(page_id, id, selector) {
|
80
|
-
return this.
|
91
|
+
return this.sendResponse(this.node(page_id, id).find(selector));
|
81
92
|
};
|
93
|
+
|
82
94
|
Browser.prototype.text = function(page_id, id) {
|
83
|
-
return this.
|
95
|
+
return this.sendResponse(this.node(page_id, id).text());
|
84
96
|
};
|
97
|
+
|
85
98
|
Browser.prototype.attribute = function(page_id, id, name) {
|
86
|
-
return this.
|
99
|
+
return this.sendResponse(this.node(page_id, id).getAttribute(name));
|
87
100
|
};
|
101
|
+
|
88
102
|
Browser.prototype.value = function(page_id, id) {
|
89
|
-
return this.
|
103
|
+
return this.sendResponse(this.node(page_id, id).value());
|
90
104
|
};
|
105
|
+
|
91
106
|
Browser.prototype.set = function(page_id, id, value) {
|
92
|
-
|
93
|
-
|
94
|
-
});
|
107
|
+
this.node(page_id, id).set(value);
|
108
|
+
return this.sendResponse(true);
|
95
109
|
};
|
110
|
+
|
96
111
|
Browser.prototype.select_file = function(page_id, id, value) {
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
node.removeAttribute('_poltergeist_selected');
|
104
|
-
if (multiple) {
|
105
|
-
node.setAttribute('multiple', 'multiple');
|
106
|
-
}
|
107
|
-
return this.sendResponse(true);
|
108
|
-
});
|
112
|
+
var node;
|
113
|
+
node = this.node(page_id, id);
|
114
|
+
node.setAttribute('_poltergeist_selected', '');
|
115
|
+
this.page.uploadFile('[_poltergeist_selected]', value);
|
116
|
+
node.removeAttribute('_poltergeist_selected');
|
117
|
+
return this.sendResponse(true);
|
109
118
|
};
|
119
|
+
|
110
120
|
Browser.prototype.select = function(page_id, id, value) {
|
111
|
-
return this.
|
121
|
+
return this.sendResponse(this.node(page_id, id).select(value));
|
112
122
|
};
|
123
|
+
|
113
124
|
Browser.prototype.tag_name = function(page_id, id) {
|
114
|
-
return this.
|
125
|
+
return this.sendResponse(this.node(page_id, id).tagName());
|
115
126
|
};
|
127
|
+
|
116
128
|
Browser.prototype.visible = function(page_id, id) {
|
117
|
-
return this.
|
129
|
+
return this.sendResponse(this.node(page_id, id).isVisible());
|
118
130
|
};
|
131
|
+
|
119
132
|
Browser.prototype.evaluate = function(script) {
|
120
|
-
return this.sendResponse(
|
133
|
+
return this.sendResponse(this.page.evaluate("function() { return " + script + " }"));
|
121
134
|
};
|
135
|
+
|
122
136
|
Browser.prototype.execute = function(script) {
|
123
137
|
this.page.execute("function() { " + script + " }");
|
124
138
|
return this.sendResponse(true);
|
125
139
|
};
|
140
|
+
|
126
141
|
Browser.prototype.push_frame = function(id) {
|
127
142
|
this.page.pushFrame(id);
|
128
143
|
return this.sendResponse(true);
|
129
144
|
};
|
145
|
+
|
130
146
|
Browser.prototype.pop_frame = function() {
|
131
147
|
this.page.popFrame();
|
132
148
|
return this.sendResponse(true);
|
133
149
|
};
|
150
|
+
|
134
151
|
Browser.prototype.click = function(page_id, id) {
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
return this.owner.sendError(click);
|
144
|
-
} else {
|
145
|
-
return this.sendResponse(true);
|
146
|
-
}
|
147
|
-
}
|
148
|
-
}, this), 10);
|
149
|
-
});
|
152
|
+
var node;
|
153
|
+
node = this.node(page_id, id);
|
154
|
+
this.state = 'clicked';
|
155
|
+
node.click();
|
156
|
+
if (this.state !== 'loading') {
|
157
|
+
this.state = 'default';
|
158
|
+
return this.sendResponse(true);
|
159
|
+
}
|
150
160
|
};
|
161
|
+
|
151
162
|
Browser.prototype.drag = function(page_id, id, other_id) {
|
152
|
-
|
153
|
-
|
154
|
-
return this.sendResponse(true);
|
155
|
-
});
|
163
|
+
this.node(page_id, id).dragTo(this.node(page_id, other_id));
|
164
|
+
return this.sendResponse(true);
|
156
165
|
};
|
166
|
+
|
157
167
|
Browser.prototype.trigger = function(page_id, id, event) {
|
158
|
-
|
159
|
-
|
160
|
-
});
|
168
|
+
this.node(page_id, id).trigger(event);
|
169
|
+
return this.sendResponse(event);
|
161
170
|
};
|
171
|
+
|
172
|
+
Browser.prototype.equals = function(page_id, id, other_id) {
|
173
|
+
return this.sendResponse(this.node(page_id, id).isEqual(this.node(page_id, other_id)));
|
174
|
+
};
|
175
|
+
|
162
176
|
Browser.prototype.reset = function() {
|
163
177
|
this.resetPage();
|
164
178
|
return this.sendResponse(true);
|
165
179
|
};
|
180
|
+
|
166
181
|
Browser.prototype.render = function(path, full) {
|
167
182
|
var dimensions, document, viewport;
|
168
183
|
dimensions = this.page.validatedDimensions();
|
@@ -195,6 +210,7 @@ Poltergeist.Browser = (function() {
|
|
195
210
|
}
|
196
211
|
return this.sendResponse(true);
|
197
212
|
};
|
213
|
+
|
198
214
|
Browser.prototype.resize = function(width, height) {
|
199
215
|
this.page.setViewportSize({
|
200
216
|
width: width,
|
@@ -202,9 +218,21 @@ Poltergeist.Browser = (function() {
|
|
202
218
|
});
|
203
219
|
return this.sendResponse(true);
|
204
220
|
};
|
221
|
+
|
222
|
+
Browser.prototype.network_traffic = function() {
|
223
|
+
return this.sendResponse(this.page.networkTraffic());
|
224
|
+
};
|
225
|
+
|
205
226
|
Browser.prototype.exit = function() {
|
206
227
|
return phantom.exit();
|
207
228
|
};
|
229
|
+
|
208
230
|
Browser.prototype.noop = function() {};
|
231
|
+
|
232
|
+
Browser.prototype.browser_error = function() {
|
233
|
+
throw new Error('zomg');
|
234
|
+
};
|
235
|
+
|
209
236
|
return Browser;
|
210
|
-
|
237
|
+
|
238
|
+
})();
|
@@ -1,20 +1,27 @@
|
|
1
1
|
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
|
2
|
+
|
2
3
|
Poltergeist.Connection = (function() {
|
4
|
+
|
3
5
|
function Connection(owner, port) {
|
4
6
|
this.owner = owner;
|
5
7
|
this.port = port;
|
6
8
|
this.commandReceived = __bind(this.commandReceived, this);
|
9
|
+
|
7
10
|
this.socket = new WebSocket("ws://127.0.0.1:" + this.port + "/");
|
8
11
|
this.socket.onmessage = this.commandReceived;
|
9
12
|
this.socket.onclose = function() {
|
10
13
|
return phantom.exit();
|
11
14
|
};
|
12
15
|
}
|
16
|
+
|
13
17
|
Connection.prototype.commandReceived = function(message) {
|
14
18
|
return this.owner.runCommand(JSON.parse(message.data));
|
15
19
|
};
|
20
|
+
|
16
21
|
Connection.prototype.send = function(message) {
|
17
22
|
return this.socket.send(JSON.stringify(message));
|
18
23
|
};
|
24
|
+
|
19
25
|
return Connection;
|
20
|
-
|
26
|
+
|
27
|
+
})();
|
@@ -1,17 +1,12 @@
|
|
1
|
-
var Poltergeist
|
2
|
-
|
3
|
-
for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
|
4
|
-
|
5
|
-
ctor.prototype = parent.prototype;
|
6
|
-
child.prototype = new ctor;
|
7
|
-
child.__super__ = parent.prototype;
|
8
|
-
return child;
|
9
|
-
};
|
1
|
+
var Poltergeist,
|
2
|
+
__hasProp = {}.hasOwnProperty,
|
3
|
+
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
|
4
|
+
|
10
5
|
Poltergeist = (function() {
|
11
|
-
|
12
|
-
|
6
|
+
|
7
|
+
function Poltergeist(port, width, height) {
|
13
8
|
var that;
|
14
|
-
this.browser = new Poltergeist.Browser(this);
|
9
|
+
this.browser = new Poltergeist.Browser(this, width, height);
|
15
10
|
this.connection = new Poltergeist.Connection(this, port);
|
16
11
|
that = this;
|
17
12
|
phantom.onError = function(message, stack) {
|
@@ -19,15 +14,26 @@ Poltergeist = (function() {
|
|
19
14
|
};
|
20
15
|
this.running = false;
|
21
16
|
}
|
17
|
+
|
22
18
|
Poltergeist.prototype.runCommand = function(command) {
|
23
19
|
this.running = true;
|
24
|
-
|
20
|
+
try {
|
21
|
+
return this.browser[command.name].apply(this.browser, command.args);
|
22
|
+
} catch (error) {
|
23
|
+
if (error instanceof Poltergeist.Error) {
|
24
|
+
return this.sendError(error);
|
25
|
+
} else {
|
26
|
+
return this.sendError(new Poltergeist.BrowserError(error.toString(), error.stack));
|
27
|
+
}
|
28
|
+
}
|
25
29
|
};
|
30
|
+
|
26
31
|
Poltergeist.prototype.sendResponse = function(response) {
|
27
32
|
return this.send({
|
28
33
|
response: response
|
29
34
|
});
|
30
35
|
};
|
36
|
+
|
31
37
|
Poltergeist.prototype.sendError = function(error) {
|
32
38
|
return this.send({
|
33
39
|
error: {
|
@@ -36,77 +42,112 @@ Poltergeist = (function() {
|
|
36
42
|
}
|
37
43
|
});
|
38
44
|
};
|
39
|
-
|
40
|
-
if (message === 'PoltergeistAgent.ObsoleteNode') {
|
41
|
-
return this.sendError(new Poltergeist.ObsoleteNode);
|
42
|
-
} else {
|
43
|
-
return this.sendError(new Poltergeist.BrowserError(message, stack));
|
44
|
-
}
|
45
|
-
};
|
45
|
+
|
46
46
|
Poltergeist.prototype.send = function(data) {
|
47
47
|
if (this.running) {
|
48
48
|
this.connection.send(data);
|
49
49
|
return this.running = false;
|
50
50
|
}
|
51
51
|
};
|
52
|
+
|
52
53
|
return Poltergeist;
|
54
|
+
|
53
55
|
})();
|
56
|
+
|
54
57
|
window.Poltergeist = Poltergeist;
|
58
|
+
|
55
59
|
Poltergeist.Error = (function() {
|
60
|
+
|
56
61
|
function Error() {}
|
62
|
+
|
57
63
|
return Error;
|
64
|
+
|
58
65
|
})();
|
59
|
-
|
60
|
-
|
66
|
+
|
67
|
+
Poltergeist.ObsoleteNode = (function(_super) {
|
68
|
+
|
69
|
+
__extends(ObsoleteNode, _super);
|
70
|
+
|
61
71
|
function ObsoleteNode() {
|
62
|
-
ObsoleteNode.__super__.constructor.apply(this, arguments);
|
72
|
+
return ObsoleteNode.__super__.constructor.apply(this, arguments);
|
63
73
|
}
|
74
|
+
|
64
75
|
ObsoleteNode.prototype.name = "Poltergeist.ObsoleteNode";
|
76
|
+
|
65
77
|
ObsoleteNode.prototype.args = function() {
|
66
78
|
return [];
|
67
79
|
};
|
80
|
+
|
68
81
|
ObsoleteNode.prototype.toString = function() {
|
69
82
|
return this.name;
|
70
83
|
};
|
84
|
+
|
71
85
|
return ObsoleteNode;
|
72
|
-
|
73
|
-
Poltergeist.
|
74
|
-
|
86
|
+
|
87
|
+
})(Poltergeist.Error);
|
88
|
+
|
89
|
+
Poltergeist.ClickFailed = (function(_super) {
|
90
|
+
|
91
|
+
__extends(ClickFailed, _super);
|
92
|
+
|
75
93
|
function ClickFailed(selector, position) {
|
76
94
|
this.selector = selector;
|
77
95
|
this.position = position;
|
78
96
|
}
|
97
|
+
|
79
98
|
ClickFailed.prototype.name = "Poltergeist.ClickFailed";
|
99
|
+
|
80
100
|
ClickFailed.prototype.args = function() {
|
81
101
|
return [this.selector, this.position];
|
82
102
|
};
|
103
|
+
|
83
104
|
return ClickFailed;
|
84
|
-
|
85
|
-
Poltergeist.
|
86
|
-
|
105
|
+
|
106
|
+
})(Poltergeist.Error);
|
107
|
+
|
108
|
+
Poltergeist.JavascriptError = (function(_super) {
|
109
|
+
|
110
|
+
__extends(JavascriptError, _super);
|
111
|
+
|
87
112
|
function JavascriptError(errors) {
|
88
113
|
this.errors = errors;
|
89
114
|
}
|
115
|
+
|
90
116
|
JavascriptError.prototype.name = "Poltergeist.JavascriptError";
|
117
|
+
|
91
118
|
JavascriptError.prototype.args = function() {
|
92
119
|
return [this.errors];
|
93
120
|
};
|
121
|
+
|
94
122
|
return JavascriptError;
|
95
|
-
|
96
|
-
Poltergeist.
|
97
|
-
|
123
|
+
|
124
|
+
})(Poltergeist.Error);
|
125
|
+
|
126
|
+
Poltergeist.BrowserError = (function(_super) {
|
127
|
+
|
128
|
+
__extends(BrowserError, _super);
|
129
|
+
|
98
130
|
function BrowserError(message, stack) {
|
99
131
|
this.message = message;
|
100
132
|
this.stack = stack;
|
101
133
|
}
|
134
|
+
|
102
135
|
BrowserError.prototype.name = "Poltergeist.BrowserError";
|
136
|
+
|
103
137
|
BrowserError.prototype.args = function() {
|
104
138
|
return [this.message, this.stack];
|
105
139
|
};
|
140
|
+
|
106
141
|
return BrowserError;
|
107
|
-
|
142
|
+
|
143
|
+
})(Poltergeist.Error);
|
144
|
+
|
108
145
|
phantom.injectJs("" + phantom.libraryPath + "/web_page.js");
|
146
|
+
|
109
147
|
phantom.injectJs("" + phantom.libraryPath + "/node.js");
|
148
|
+
|
110
149
|
phantom.injectJs("" + phantom.libraryPath + "/connection.js");
|
150
|
+
|
111
151
|
phantom.injectJs("" + phantom.libraryPath + "/browser.js");
|
112
|
-
|
152
|
+
|
153
|
+
new Poltergeist(phantom.args[0], phantom.args[1], phantom.args[2]);
|