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,5 +1,7 @@
|
|
1
1
|
class Poltergeist.Browser
|
2
|
-
constructor: (@owner) ->
|
2
|
+
constructor: (@owner, width, height) ->
|
3
|
+
@width = width || 1024
|
4
|
+
@height = height || 768
|
3
5
|
@state = 'default'
|
4
6
|
@page_id = 0
|
5
7
|
|
@@ -7,11 +9,14 @@ class Poltergeist.Browser
|
|
7
9
|
|
8
10
|
resetPage: ->
|
9
11
|
@page.release() if @page?
|
10
|
-
@page = new Poltergeist.WebPage
|
12
|
+
@page = new Poltergeist.WebPage(@width, @height)
|
11
13
|
|
12
14
|
@page.onLoadStarted = =>
|
13
15
|
@state = 'loading' if @state == 'clicked'
|
14
16
|
|
17
|
+
@page.onNavigationRequested = (url, navigation) =>
|
18
|
+
@state = 'loading' if @state == 'clicked' && navigation == 'FormSubmitted'
|
19
|
+
|
15
20
|
@page.onLoadFinished = (status) =>
|
16
21
|
if @state == 'loading'
|
17
22
|
this.sendResponse(status)
|
@@ -25,37 +30,26 @@ class Poltergeist.Browser
|
|
25
30
|
|
26
31
|
if errors.length > 0
|
27
32
|
@page.clearErrors()
|
28
|
-
|
33
|
+
throw new Poltergeist.JavascriptError(errors)
|
29
34
|
else
|
30
35
|
@owner.sendResponse(response)
|
31
36
|
|
32
|
-
|
37
|
+
node: (page_id, id) ->
|
33
38
|
if page_id == @page_id
|
34
|
-
|
39
|
+
@page.get(id)
|
35
40
|
else
|
36
|
-
|
37
|
-
|
38
|
-
nodeCall: (page_id, id, fn, args...) ->
|
39
|
-
callback = args.pop()
|
40
|
-
|
41
|
-
this.getNode(
|
42
|
-
page_id, id,
|
43
|
-
(node) ->
|
44
|
-
result = node[fn](args...)
|
45
|
-
|
46
|
-
if result instanceof Poltergeist.ObsoleteNode
|
47
|
-
@owner.sendError(result)
|
48
|
-
else
|
49
|
-
callback.call(this, result, node)
|
50
|
-
)
|
41
|
+
throw new Poltergeist.ObsoleteNode
|
51
42
|
|
52
|
-
visit: (url) ->
|
43
|
+
visit: (url, headers) ->
|
53
44
|
@state = 'loading'
|
54
|
-
@page.open(url)
|
45
|
+
@page.open(url, operation: "get", headers: headers)
|
55
46
|
|
56
47
|
current_url: ->
|
57
48
|
this.sendResponse @page.currentUrl()
|
58
49
|
|
50
|
+
status_code: ->
|
51
|
+
this.sendResponse @page.statusCode()
|
52
|
+
|
59
53
|
body: ->
|
60
54
|
this.sendResponse @page.content()
|
61
55
|
|
@@ -66,53 +60,44 @@ class Poltergeist.Browser
|
|
66
60
|
this.sendResponse(page_id: @page_id, ids: @page.find(selector))
|
67
61
|
|
68
62
|
find_within: (page_id, id, selector) ->
|
69
|
-
this.
|
63
|
+
this.sendResponse this.node(page_id, id).find(selector)
|
70
64
|
|
71
65
|
text: (page_id, id) ->
|
72
|
-
this.
|
66
|
+
this.sendResponse this.node(page_id, id).text()
|
73
67
|
|
74
68
|
attribute: (page_id, id, name) ->
|
75
|
-
this.
|
69
|
+
this.sendResponse this.node(page_id, id).getAttribute(name)
|
76
70
|
|
77
71
|
value: (page_id, id) ->
|
78
|
-
this.
|
72
|
+
this.sendResponse this.node(page_id, id).value()
|
79
73
|
|
80
74
|
set: (page_id, id, value) ->
|
81
|
-
this.
|
75
|
+
this.node(page_id, id).set(value)
|
76
|
+
this.sendResponse(true)
|
82
77
|
|
83
78
|
# PhantomJS only allows us to reference the element by CSS selector, not XPath,
|
84
79
|
# so we have to add an attribute to the element to identify it, then remove it
|
85
80
|
# afterwards.
|
86
|
-
#
|
87
|
-
# PhantomJS does not support multiple-file inputs, so we have to blatently cheat
|
88
|
-
# by temporarily changing it to a single-file input. This obviously could break
|
89
|
-
# things in various ways, which is not ideal, but it works in the simplest case.
|
90
81
|
select_file: (page_id, id, value) ->
|
91
|
-
this.
|
92
|
-
page_id, id, 'isMultiple',
|
93
|
-
(multiple, node) ->
|
94
|
-
node.removeAttribute('multiple') if multiple
|
95
|
-
node.setAttribute('_poltergeist_selected', '')
|
82
|
+
node = this.node(page_id, id)
|
96
83
|
|
97
|
-
|
84
|
+
node.setAttribute('_poltergeist_selected', '')
|
85
|
+
@page.uploadFile('[_poltergeist_selected]', value)
|
86
|
+
node.removeAttribute('_poltergeist_selected')
|
98
87
|
|
99
|
-
|
100
|
-
node.setAttribute('multiple', 'multiple') if multiple
|
101
|
-
|
102
|
-
this.sendResponse(true)
|
103
|
-
)
|
88
|
+
this.sendResponse(true)
|
104
89
|
|
105
90
|
select: (page_id, id, value) ->
|
106
|
-
this.
|
91
|
+
this.sendResponse this.node(page_id, id).select(value)
|
107
92
|
|
108
93
|
tag_name: (page_id, id) ->
|
109
|
-
this.
|
94
|
+
this.sendResponse this.node(page_id, id).tagName()
|
110
95
|
|
111
96
|
visible: (page_id, id) ->
|
112
|
-
this.
|
97
|
+
this.sendResponse this.node(page_id, id).isVisible()
|
113
98
|
|
114
99
|
evaluate: (script) ->
|
115
|
-
this.sendResponse
|
100
|
+
this.sendResponse @page.evaluate("function() { return #{script} }")
|
116
101
|
|
117
102
|
execute: (script) ->
|
118
103
|
@page.execute("function() { #{script} }")
|
@@ -127,43 +112,29 @@ class Poltergeist.Browser
|
|
127
112
|
this.sendResponse(true)
|
128
113
|
|
129
114
|
click: (page_id, id) ->
|
130
|
-
#
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
# callback can (possibly) fire, before we decide whether to send a response.
|
143
|
-
setTimeout(
|
144
|
-
=>
|
145
|
-
if @state == 'clicked'
|
146
|
-
@state = 'default'
|
147
|
-
|
148
|
-
if click instanceof Poltergeist.ClickFailed
|
149
|
-
@owner.sendError(click)
|
150
|
-
else
|
151
|
-
this.sendResponse(true)
|
152
|
-
,
|
153
|
-
10
|
154
|
-
)
|
155
|
-
)
|
115
|
+
# Get the node before changing state, in case there is an exception
|
116
|
+
node = this.node(page_id, id)
|
117
|
+
|
118
|
+
# If the click event triggers onNavigationRequested, we will transition to the 'loading'
|
119
|
+
# state and wait for onLoadFinished before sending a response.
|
120
|
+
@state = 'clicked'
|
121
|
+
|
122
|
+
node.click()
|
123
|
+
|
124
|
+
if @state != 'loading'
|
125
|
+
@state = 'default'
|
126
|
+
this.sendResponse(true)
|
156
127
|
|
157
128
|
drag: (page_id, id, other_id) ->
|
158
|
-
this.
|
159
|
-
|
160
|
-
(obsolete, node) ->
|
161
|
-
node.dragTo(@page.get(other_id))
|
162
|
-
this.sendResponse(true)
|
163
|
-
)
|
129
|
+
this.node(page_id, id).dragTo this.node(page_id, other_id)
|
130
|
+
this.sendResponse(true)
|
164
131
|
|
165
132
|
trigger: (page_id, id, event) ->
|
166
|
-
this.
|
133
|
+
this.node(page_id, id).trigger(event)
|
134
|
+
this.sendResponse(event)
|
135
|
+
|
136
|
+
equals: (page_id, id, other_id) ->
|
137
|
+
this.sendResponse this.node(page_id, id).isEqual(this.node(page_id, other_id))
|
167
138
|
|
168
139
|
reset: ->
|
169
140
|
this.resetPage()
|
@@ -189,8 +160,15 @@ class Poltergeist.Browser
|
|
189
160
|
@page.setViewportSize(width: width, height: height)
|
190
161
|
this.sendResponse(true)
|
191
162
|
|
163
|
+
network_traffic: ->
|
164
|
+
this.sendResponse(@page.networkTraffic())
|
165
|
+
|
192
166
|
exit: ->
|
193
167
|
phantom.exit()
|
194
168
|
|
195
169
|
noop: ->
|
196
170
|
# NOOOOOOP!
|
171
|
+
|
172
|
+
# This command is purely for testing error handling
|
173
|
+
browser_error: ->
|
174
|
+
throw new Error('zomg')
|
@@ -1,101 +1,146 @@
|
|
1
1
|
var PoltergeistAgent;
|
2
|
-
|
2
|
+
|
3
3
|
PoltergeistAgent = (function() {
|
4
|
+
|
4
5
|
function PoltergeistAgent() {
|
5
6
|
this.elements = [];
|
6
7
|
this.nodes = {};
|
7
8
|
this.windows = [];
|
8
9
|
this.pushWindow(window);
|
9
10
|
}
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
|
12
|
+
PoltergeistAgent.prototype.externalCall = function(name, args) {
|
13
|
+
try {
|
14
|
+
return {
|
15
|
+
value: this[name].apply(this, args)
|
16
|
+
};
|
17
|
+
} catch (error) {
|
18
|
+
return {
|
19
|
+
error: {
|
20
|
+
message: error.toString(),
|
21
|
+
stack: error.stack
|
22
|
+
}
|
23
|
+
};
|
24
|
+
}
|
25
|
+
};
|
26
|
+
|
27
|
+
PoltergeistAgent.stringify = function(object) {
|
28
|
+
return JSON.stringify(object, function(key, value) {
|
29
|
+
if (Array.isArray(this[key])) {
|
30
|
+
return this[key];
|
31
|
+
} else {
|
32
|
+
return value;
|
33
|
+
}
|
34
|
+
});
|
14
35
|
};
|
36
|
+
|
15
37
|
PoltergeistAgent.prototype.pushWindow = function(new_window) {
|
16
38
|
this.windows.push(new_window);
|
17
39
|
this.window = new_window;
|
18
40
|
this.document = this.window.document;
|
19
41
|
return null;
|
20
42
|
};
|
43
|
+
|
21
44
|
PoltergeistAgent.prototype.popWindow = function() {
|
22
45
|
this.windows.pop();
|
23
46
|
this.window = this.windows[this.windows.length - 1];
|
24
47
|
this.document = this.window.document;
|
25
48
|
return null;
|
26
49
|
};
|
50
|
+
|
27
51
|
PoltergeistAgent.prototype.pushFrame = function(id) {
|
28
52
|
return this.pushWindow(this.document.getElementById(id).contentWindow);
|
29
53
|
};
|
54
|
+
|
30
55
|
PoltergeistAgent.prototype.popFrame = function() {
|
31
56
|
return this.popWindow();
|
32
57
|
};
|
58
|
+
|
33
59
|
PoltergeistAgent.prototype.currentUrl = function() {
|
34
60
|
return window.location.toString();
|
35
61
|
};
|
62
|
+
|
36
63
|
PoltergeistAgent.prototype.find = function(selector, within) {
|
37
|
-
var i, ids, results, _ref;
|
64
|
+
var i, ids, results, _i, _ref;
|
38
65
|
if (within == null) {
|
39
66
|
within = this.document;
|
40
67
|
}
|
41
68
|
results = this.document.evaluate(selector, within, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
|
42
69
|
ids = [];
|
43
|
-
for (i = 0, _ref = results.snapshotLength; 0 <= _ref ?
|
70
|
+
for (i = _i = 0, _ref = results.snapshotLength; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
|
44
71
|
ids.push(this.register(results.snapshotItem(i)));
|
45
72
|
}
|
46
73
|
return ids;
|
47
74
|
};
|
75
|
+
|
48
76
|
PoltergeistAgent.prototype.register = function(element) {
|
49
77
|
this.elements.push(element);
|
50
78
|
return this.elements.length - 1;
|
51
79
|
};
|
80
|
+
|
52
81
|
PoltergeistAgent.prototype.documentSize = function() {
|
53
82
|
return {
|
54
83
|
height: this.document.documentElement.scrollHeight,
|
55
84
|
width: this.document.documentElement.scrollWidth
|
56
85
|
};
|
57
86
|
};
|
87
|
+
|
58
88
|
PoltergeistAgent.prototype.get = function(id) {
|
59
89
|
var _base;
|
60
90
|
return (_base = this.nodes)[id] || (_base[id] = new PoltergeistAgent.Node(this, this.elements[id]));
|
61
91
|
};
|
62
|
-
|
92
|
+
|
93
|
+
PoltergeistAgent.prototype.nodeCall = function(id, name, args) {
|
63
94
|
var node;
|
64
95
|
node = this.get(id);
|
65
96
|
if (node.isObsolete()) {
|
66
97
|
throw new PoltergeistAgent.ObsoleteNode;
|
67
98
|
}
|
68
|
-
return node[name].apply(node,
|
99
|
+
return node[name].apply(node, args);
|
69
100
|
};
|
101
|
+
|
70
102
|
return PoltergeistAgent;
|
103
|
+
|
71
104
|
})();
|
105
|
+
|
72
106
|
PoltergeistAgent.ObsoleteNode = (function() {
|
107
|
+
|
73
108
|
function ObsoleteNode() {}
|
109
|
+
|
74
110
|
ObsoleteNode.prototype.toString = function() {
|
75
111
|
return "PoltergeistAgent.ObsoleteNode";
|
76
112
|
};
|
113
|
+
|
77
114
|
return ObsoleteNode;
|
115
|
+
|
78
116
|
})();
|
117
|
+
|
79
118
|
PoltergeistAgent.Node = (function() {
|
119
|
+
|
80
120
|
Node.EVENTS = {
|
81
121
|
FOCUS: ['blur', 'focus', 'focusin', 'focusout'],
|
82
122
|
MOUSE: ['click', 'dblclick', 'mousedown', 'mouseenter', 'mouseleave', 'mousemove', 'mouseover', 'mouseout', 'mouseup']
|
83
123
|
};
|
124
|
+
|
84
125
|
function Node(agent, element) {
|
85
126
|
this.agent = agent;
|
86
127
|
this.element = element;
|
87
128
|
}
|
129
|
+
|
88
130
|
Node.prototype.parentId = function() {
|
89
131
|
return this.agent.register(this.element.parentNode);
|
90
132
|
};
|
133
|
+
|
91
134
|
Node.prototype.find = function(selector) {
|
92
135
|
return this.agent.find(selector, this.element);
|
93
136
|
};
|
137
|
+
|
94
138
|
Node.prototype.isObsolete = function() {
|
95
|
-
var obsolete
|
96
|
-
|
139
|
+
var obsolete,
|
140
|
+
_this = this;
|
141
|
+
obsolete = function(element) {
|
97
142
|
if (element.parentNode != null) {
|
98
|
-
if (element.parentNode ===
|
143
|
+
if (element.parentNode === _this.agent.document) {
|
99
144
|
return false;
|
100
145
|
} else {
|
101
146
|
return obsolete(element.parentNode);
|
@@ -103,20 +148,55 @@ PoltergeistAgent.Node = (function() {
|
|
103
148
|
} else {
|
104
149
|
return true;
|
105
150
|
}
|
106
|
-
}
|
151
|
+
};
|
107
152
|
return obsolete(this.element);
|
108
153
|
};
|
154
|
+
|
109
155
|
Node.prototype.changed = function() {
|
110
156
|
var event;
|
111
157
|
event = document.createEvent('HTMLEvents');
|
112
|
-
event.initEvent(
|
158
|
+
event.initEvent('change', true, false);
|
159
|
+
return this.element.dispatchEvent(event);
|
160
|
+
};
|
161
|
+
|
162
|
+
Node.prototype.input = function() {
|
163
|
+
var event;
|
164
|
+
event = document.createEvent('HTMLEvents');
|
165
|
+
event.initEvent('input', true, false);
|
113
166
|
return this.element.dispatchEvent(event);
|
114
167
|
};
|
168
|
+
|
169
|
+
Node.prototype.keyupdowned = function(eventName, keyCode) {
|
170
|
+
var event;
|
171
|
+
event = document.createEvent('UIEvents');
|
172
|
+
event.initEvent(eventName, true, true);
|
173
|
+
event.keyCode = keyCode;
|
174
|
+
event.which = keyCode;
|
175
|
+
event.charCode = 0;
|
176
|
+
return this.element.dispatchEvent(event);
|
177
|
+
};
|
178
|
+
|
179
|
+
Node.prototype.keypressed = function(altKey, ctrlKey, shiftKey, metaKey, keyCode, charCode) {
|
180
|
+
var event;
|
181
|
+
event = document.createEvent('UIEvents');
|
182
|
+
event.initEvent('keypress', true, true);
|
183
|
+
event.window = this.agent.window;
|
184
|
+
event.altKey = altKey;
|
185
|
+
event.ctrlKey = ctrlKey;
|
186
|
+
event.shiftKey = shiftKey;
|
187
|
+
event.metaKey = metaKey;
|
188
|
+
event.keyCode = keyCode;
|
189
|
+
event.charCode = charCode;
|
190
|
+
event.which = keyCode;
|
191
|
+
return this.element.dispatchEvent(event);
|
192
|
+
};
|
193
|
+
|
115
194
|
Node.prototype.insideBody = function() {
|
116
195
|
return this.element === this.agent.document.body || this.agent.document.evaluate('ancestor::body', this.element, null, XPathResult.BOOLEAN_TYPE, null).booleanValue;
|
117
196
|
};
|
197
|
+
|
118
198
|
Node.prototype.text = function() {
|
119
|
-
var el, i, node, results, text, _ref;
|
199
|
+
var el, i, node, results, text, _i, _ref;
|
120
200
|
if (!this.isVisible()) {
|
121
201
|
return '';
|
122
202
|
}
|
@@ -127,7 +207,7 @@ PoltergeistAgent.Node = (function() {
|
|
127
207
|
}
|
128
208
|
results = this.agent.document.evaluate('.//text()[not(ancestor::script)]', el, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
|
129
209
|
text = '';
|
130
|
-
for (i = 0, _ref = results.snapshotLength; 0 <= _ref ?
|
210
|
+
for (i = _i = 0, _ref = results.snapshotLength; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
|
131
211
|
node = results.snapshotItem(i);
|
132
212
|
if (this.isVisible(node.parentNode)) {
|
133
213
|
text += node.textContent;
|
@@ -135,6 +215,7 @@ PoltergeistAgent.Node = (function() {
|
|
135
215
|
}
|
136
216
|
return text;
|
137
217
|
};
|
218
|
+
|
138
219
|
Node.prototype.getAttribute = function(name) {
|
139
220
|
if (name === 'checked' || name === 'selected') {
|
140
221
|
return this.element[name];
|
@@ -142,6 +223,11 @@ PoltergeistAgent.Node = (function() {
|
|
142
223
|
return this.element.getAttribute(name);
|
143
224
|
}
|
144
225
|
};
|
226
|
+
|
227
|
+
Node.prototype.scrollIntoView = function() {
|
228
|
+
return this.element.scrollIntoViewIfNeeded();
|
229
|
+
};
|
230
|
+
|
145
231
|
Node.prototype.value = function() {
|
146
232
|
var option, _i, _len, _ref, _results;
|
147
233
|
if (this.element.tagName === 'SELECT' && this.element.multiple) {
|
@@ -158,22 +244,39 @@ PoltergeistAgent.Node = (function() {
|
|
158
244
|
return this.element.value;
|
159
245
|
}
|
160
246
|
};
|
247
|
+
|
161
248
|
Node.prototype.set = function(value) {
|
249
|
+
var char, keyCode, _i, _len;
|
162
250
|
if (this.element.maxLength >= 0) {
|
163
251
|
value = value.substr(0, this.element.maxLength);
|
164
252
|
}
|
165
|
-
this.element.value =
|
166
|
-
|
253
|
+
this.element.value = '';
|
254
|
+
this.trigger('focus');
|
255
|
+
for (_i = 0, _len = value.length; _i < _len; _i++) {
|
256
|
+
char = value[_i];
|
257
|
+
this.element.value += char;
|
258
|
+
keyCode = this.characterToKeyCode(char);
|
259
|
+
this.keyupdowned('keydown', keyCode);
|
260
|
+
this.keypressed(false, false, false, false, char.charCodeAt(0), char.charCodeAt(0));
|
261
|
+
this.keyupdowned('keyup', keyCode);
|
262
|
+
}
|
263
|
+
this.changed();
|
264
|
+
this.input();
|
265
|
+
return this.trigger('blur');
|
167
266
|
};
|
267
|
+
|
168
268
|
Node.prototype.isMultiple = function() {
|
169
269
|
return this.element.multiple;
|
170
270
|
};
|
271
|
+
|
171
272
|
Node.prototype.setAttribute = function(name, value) {
|
172
273
|
return this.element.setAttribute(name, value);
|
173
274
|
};
|
275
|
+
|
174
276
|
Node.prototype.removeAttribute = function(name) {
|
175
277
|
return this.element.removeAttribute(name);
|
176
278
|
};
|
279
|
+
|
177
280
|
Node.prototype.select = function(value) {
|
178
281
|
if (value === false && !this.element.parentNode.multiple) {
|
179
282
|
return false;
|
@@ -183,9 +286,11 @@ PoltergeistAgent.Node = (function() {
|
|
183
286
|
return true;
|
184
287
|
}
|
185
288
|
};
|
289
|
+
|
186
290
|
Node.prototype.tagName = function() {
|
187
291
|
return this.element.tagName;
|
188
292
|
};
|
293
|
+
|
189
294
|
Node.prototype.isVisible = function(element) {
|
190
295
|
if (!element) {
|
191
296
|
element = this.element;
|
@@ -198,6 +303,7 @@ PoltergeistAgent.Node = (function() {
|
|
198
303
|
return true;
|
199
304
|
}
|
200
305
|
};
|
306
|
+
|
201
307
|
Node.prototype.position = function() {
|
202
308
|
var rect;
|
203
309
|
rect = this.element.getClientRects()[0];
|
@@ -210,6 +316,7 @@ PoltergeistAgent.Node = (function() {
|
|
210
316
|
height: rect.height
|
211
317
|
};
|
212
318
|
};
|
319
|
+
|
213
320
|
Node.prototype.trigger = function(name) {
|
214
321
|
var event;
|
215
322
|
if (Node.EVENTS.MOUSE.indexOf(name) !== -1) {
|
@@ -223,6 +330,7 @@ PoltergeistAgent.Node = (function() {
|
|
223
330
|
}
|
224
331
|
return this.element.dispatchEvent(event);
|
225
332
|
};
|
333
|
+
|
226
334
|
Node.prototype.clickTest = function(x, y) {
|
227
335
|
var el, origEl;
|
228
336
|
el = origEl = document.elementFromPoint(x, y);
|
@@ -240,6 +348,7 @@ PoltergeistAgent.Node = (function() {
|
|
240
348
|
selector: origEl && this.getSelector(origEl)
|
241
349
|
};
|
242
350
|
};
|
351
|
+
|
243
352
|
Node.prototype.getSelector = function(el) {
|
244
353
|
var className, selector, _i, _len, _ref;
|
245
354
|
selector = el.tagName !== 'HTML' ? this.getSelector(el.parentNode) + ' ' : '';
|
@@ -254,15 +363,66 @@ PoltergeistAgent.Node = (function() {
|
|
254
363
|
}
|
255
364
|
return selector;
|
256
365
|
};
|
366
|
+
|
367
|
+
Node.prototype.characterToKeyCode = function(character) {
|
368
|
+
var code, specialKeys;
|
369
|
+
code = character.toUpperCase().charCodeAt(0);
|
370
|
+
specialKeys = {
|
371
|
+
96: 192,
|
372
|
+
45: 189,
|
373
|
+
61: 187,
|
374
|
+
91: 219,
|
375
|
+
93: 221,
|
376
|
+
92: 220,
|
377
|
+
59: 186,
|
378
|
+
39: 222,
|
379
|
+
44: 188,
|
380
|
+
46: 190,
|
381
|
+
47: 191,
|
382
|
+
127: 46,
|
383
|
+
126: 192,
|
384
|
+
33: 49,
|
385
|
+
64: 50,
|
386
|
+
35: 51,
|
387
|
+
36: 52,
|
388
|
+
37: 53,
|
389
|
+
94: 54,
|
390
|
+
38: 55,
|
391
|
+
42: 56,
|
392
|
+
40: 57,
|
393
|
+
41: 48,
|
394
|
+
95: 189,
|
395
|
+
43: 187,
|
396
|
+
123: 219,
|
397
|
+
125: 221,
|
398
|
+
124: 220,
|
399
|
+
58: 186,
|
400
|
+
34: 222,
|
401
|
+
60: 188,
|
402
|
+
62: 190,
|
403
|
+
63: 191
|
404
|
+
};
|
405
|
+
return specialKeys[code] || code;
|
406
|
+
};
|
407
|
+
|
408
|
+
Node.prototype.isDOMEqual = function(other_id) {
|
409
|
+
return this.element === this.agent.get(other_id).element;
|
410
|
+
};
|
411
|
+
|
257
412
|
return Node;
|
413
|
+
|
258
414
|
})();
|
415
|
+
|
259
416
|
window.__poltergeist = new PoltergeistAgent;
|
417
|
+
|
260
418
|
document.addEventListener('DOMContentLoaded', function() {
|
261
419
|
return console.log('__DOMContentLoaded');
|
262
420
|
});
|
421
|
+
|
263
422
|
window.confirm = function(message) {
|
264
423
|
return true;
|
265
424
|
};
|
425
|
+
|
266
426
|
window.prompt = function(message, _default) {
|
267
427
|
return _default || null;
|
268
|
-
};
|
428
|
+
};
|