poltergeist 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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]);
|