isomorfeus-puppetmaster 0.3.1 → 0.4.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.
- checksums.yaml +4 -4
- data/README.md +3 -9
- data/lib/isomorfeus-puppetmaster.rb +1 -4
- data/lib/isomorfeus/puppetmaster/document.rb +35 -23
- data/lib/isomorfeus/puppetmaster/driver/puppeteer.rb +41 -35
- data/lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb +30 -8
- data/lib/isomorfeus/puppetmaster/driver_registration.rb +2 -12
- data/lib/isomorfeus/puppetmaster/self_forwardable.rb +8 -0
- data/lib/isomorfeus/puppetmaster/server.rb +13 -9
- data/lib/isomorfeus/puppetmaster/server/executor_middleware.rb +17 -8
- data/lib/isomorfeus/puppetmaster/version.rb +1 -1
- metadata +41 -44
- data/lib/isomorfeus/puppetmaster/driver/jsdom.rb +0 -373
- data/lib/isomorfeus/puppetmaster/driver/jsdom_document.rb +0 -917
- data/lib/isomorfeus/puppetmaster/driver/jsdom_node.rb +0 -842
@@ -1,917 +0,0 @@
|
|
1
|
-
module Isomorfeus
|
2
|
-
module Puppetmaster
|
3
|
-
module Driver
|
4
|
-
module JsdomDocument
|
5
|
-
def document_accept_alert(document, **options, &block)
|
6
|
-
raise Isomorfeus::Puppetmaster::NotSupported
|
7
|
-
# TODO maybe wrap in mutex
|
8
|
-
# text = options.has_key?(:text) ? "`#{options[:text]}`" : 'null'
|
9
|
-
# @context.exec <<~JAVASCRIPT
|
10
|
-
# ModalText = #{text};
|
11
|
-
# AllDomHandles[#{document.handle}].on('dialog', DialogAcceptHandler);
|
12
|
-
# JAVASCRIPT
|
13
|
-
# block.call
|
14
|
-
# sleep @reaction_timeout
|
15
|
-
# @context.eval 'ModalText'
|
16
|
-
# ensure
|
17
|
-
# matched = await <<~JAVASCRIPT
|
18
|
-
# LastResult = ModalTextMatched;
|
19
|
-
# ModalTextMatched = false;
|
20
|
-
# ModalText = null;
|
21
|
-
# AllDomHandles[#{document.handle}].removeListener('dialog', DialogAcceptHandler);
|
22
|
-
# JAVASCRIPT
|
23
|
-
# raise Isomorfeus::Puppetmaster::NoModalError if options.has_key?(:text) && !matched
|
24
|
-
end
|
25
|
-
|
26
|
-
def document_accept_confirm(document, **options, &block)
|
27
|
-
raise Isomorfeus::Puppetmaster::NotSupported
|
28
|
-
# TODO maybe wrap in mutex
|
29
|
-
# text = options.has_key?(:text) ? "`#{options[:text]}`" : 'null'
|
30
|
-
# @context.exec <<~JAVASCRIPT
|
31
|
-
# ModalText = #{text};
|
32
|
-
# AllDomHandles[#{document.handle}].on('dialog', DialogAcceptHandler);
|
33
|
-
# JAVASCRIPT
|
34
|
-
# block.call
|
35
|
-
# sleep @reaction_timeout
|
36
|
-
# @context.eval 'ModalText'
|
37
|
-
# ensure
|
38
|
-
# matched = await <<~JAVASCRIPT
|
39
|
-
# LastResult = ModalTextMatched;
|
40
|
-
# ModalTextMatched = false;
|
41
|
-
# ModalText = null;
|
42
|
-
# AllDomHandles[#{document.handle}].removeListener('dialog', DialogAcceptHandler);
|
43
|
-
# JAVASCRIPT
|
44
|
-
# raise Isomorfeus::Puppetmaster::NoModalError if options.has_key?(:text) && !matched
|
45
|
-
end
|
46
|
-
|
47
|
-
def document_accept_leave_page(document, **options, &block)
|
48
|
-
raise Isomorfeus::Puppetmaster::NotSupported
|
49
|
-
# TODO maybe wrap in mutex
|
50
|
-
# text = options.has_key?(:text) ? "`#{options[:text]}`" : 'null'
|
51
|
-
# @context.exec <<~JAVASCRIPT
|
52
|
-
# ModalText = #{text};
|
53
|
-
# AllDomHandles[#{document.handle}].on('dialog', DialogAcceptHandler);
|
54
|
-
# JAVASCRIPT
|
55
|
-
# block.call
|
56
|
-
# sleep @reaction_timeout
|
57
|
-
# @context.eval 'ModalText'
|
58
|
-
# ensure
|
59
|
-
# matched = await <<~JAVASCRIPT
|
60
|
-
# LastResult = ModalTextMatched;
|
61
|
-
# ModalTextMatched = false;
|
62
|
-
# ModalText = null;
|
63
|
-
# AllDomHandles[#{document.handle}].removeListener('dialog', DialogAcceptHandler);
|
64
|
-
# JAVASCRIPT
|
65
|
-
# raise Isomorfeus::Puppetmaster::NoModalError if options.has_key?(:text) && !matched
|
66
|
-
end
|
67
|
-
|
68
|
-
def document_accept_prompt(document, **options, &block)
|
69
|
-
raise Isomorfeus::Puppetmaster::NotSupported
|
70
|
-
# # TODO maybe wrap in mutex
|
71
|
-
# text = options.has_key?(:text) ? "`#{options[:text]}`" : 'null'
|
72
|
-
# @context.exec <<~JAVASCRIPT
|
73
|
-
# ModalText = #{text};
|
74
|
-
# AllDomHandles[#{document.handle}].on('dialog', DialogAcceptHandler);
|
75
|
-
# JAVASCRIPT
|
76
|
-
# block.call
|
77
|
-
# sleep @reaction_timeout
|
78
|
-
# @context.eval 'ModalText'
|
79
|
-
# ensure
|
80
|
-
# matched = await <<~JAVASCRIPT
|
81
|
-
# LastResult = ModalTextMatched;
|
82
|
-
# ModalTextMatched = false;
|
83
|
-
# ModalText = null;
|
84
|
-
# AllDomHandles[#{document.handle}].removeListener('dialog', DialogAcceptHandler);
|
85
|
-
# JAVASCRIPT
|
86
|
-
# raise Isomorfeus::Puppetmaster::NoModalError if options.has_key?(:text) && !matched
|
87
|
-
end
|
88
|
-
|
89
|
-
def document_all_text(document)
|
90
|
-
@context.eval "AllDomHandles[#{document.handle}].window.document.documentElement.textContent"
|
91
|
-
end
|
92
|
-
|
93
|
-
def document_body(document)
|
94
|
-
node_data = @context.exec <<~JAVASCRIPT
|
95
|
-
var node = AllDomHandles[#{document.handle}].window.document.body;
|
96
|
-
var node_handle = RegisterElementHandle(node);
|
97
|
-
var name = node.nodeName;
|
98
|
-
var tag = node.tagName.toLowerCase();
|
99
|
-
return {handle: node_handle, name: name, tag: tag, type: null, content_editable: node.isContentEditable};
|
100
|
-
JAVASCRIPT
|
101
|
-
if node_data
|
102
|
-
node_data[:css_selector] = 'body'
|
103
|
-
Isomorfeus::Puppetmaster::Node.new_by_tag(self, document, node_data)
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
def document_bring_to_front(_document); end
|
108
|
-
|
109
|
-
def document_clear_authentication_credentials(document)
|
110
|
-
raise Isomorfeus::Puppetmaster::NotSupported
|
111
|
-
end
|
112
|
-
|
113
|
-
def document_clear_cookies(document)
|
114
|
-
@context.exec "AllDomHandles[#{document.handle}].cookieJar.removeAllCookiesSync()"
|
115
|
-
end
|
116
|
-
|
117
|
-
def document_clear_extra_headers(document)
|
118
|
-
raise Isomorfeus::Puppetmaster::NotSupported
|
119
|
-
end
|
120
|
-
|
121
|
-
def document_clear_url_blacklist(document)
|
122
|
-
raise Isomorfeus::Puppetmaster::NotSupported
|
123
|
-
end
|
124
|
-
|
125
|
-
def document_click(document, x: nil, y: nil, modifiers: nil)
|
126
|
-
# modifier_keys: :alt, :control, :meta, :shift
|
127
|
-
# raise Isomorfeus::Pupppetmaster::InvalidActionError.new(:click) unless visible?
|
128
|
-
modifiers = [modifiers] if modifiers.is_a?(Symbol)
|
129
|
-
modifiers = [] unless modifiers
|
130
|
-
modifiers = modifiers.map {|key| key.to_s.camelize(:lower) }
|
131
|
-
@context.exec <<~JAVASCRIPT
|
132
|
-
var options = {button: 0, bubbles: true, cancelable: true};
|
133
|
-
var window = AllDomHandles[#{document.handle}].window;
|
134
|
-
var modifiers = #{modifiers};
|
135
|
-
if (modifiers.includes('meta')) { options['metaKey'] = true; }
|
136
|
-
if (modifiers.includes('control')) { options['ctrlKey'] = true; }
|
137
|
-
if (modifiers.includes('shift')) { options['shiftKey'] = true; }
|
138
|
-
if (modifiers.includes('alt')) { options['altKey'] = true; }
|
139
|
-
var x = #{x ? x : 'null'};
|
140
|
-
var y = #{y ? y : 'null'};
|
141
|
-
if (x && y) {
|
142
|
-
options['clientX'] = x;
|
143
|
-
options['clientY'] = y;
|
144
|
-
}
|
145
|
-
window.document.dispatchEvent(new window.MouseEvent('mousedown', options));
|
146
|
-
window.document.dispatchEvent(new window.MouseEvent('mouseup', options));
|
147
|
-
window.document.dispatchEvent(new window.MouseEvent('click', options));
|
148
|
-
JAVASCRIPT
|
149
|
-
end
|
150
|
-
|
151
|
-
def document_close(document)
|
152
|
-
await <<~JAVASCRIPT
|
153
|
-
delete AllDomHandles[#{document.handle}];
|
154
|
-
delete AllConsoleHandles[#{document.handle}];
|
155
|
-
delete ConsoleMessages[#{document.handle}];
|
156
|
-
JAVASCRIPT
|
157
|
-
end
|
158
|
-
|
159
|
-
def document_console(document)
|
160
|
-
messages = @context.eval "ConsoleMessages[#{document.handle}]"
|
161
|
-
messages.map {|m| Isomorfeus::Puppetmaster::ConsoleMessage.new(m)}
|
162
|
-
end
|
163
|
-
|
164
|
-
def document_cookies(document)
|
165
|
-
uri = document_url(document)
|
166
|
-
if uri == 'about:blank'
|
167
|
-
uri = if Isomorfeus::Puppetmaster.server_host
|
168
|
-
u = URI.new
|
169
|
-
u.scheme = Isomorfeus::Puppetmaster.server_scheme if Isomorfeus::Puppetmaster.server_scheme
|
170
|
-
u.host = Isomorfeus::Puppetmaster.server_host
|
171
|
-
u.to_s
|
172
|
-
else
|
173
|
-
'http://127.0.0.1'
|
174
|
-
end
|
175
|
-
end
|
176
|
-
result = @context.eval "AllDomHandles[#{document.handle}].cookieJar.getCookiesSync('#{uri.to_s}')"
|
177
|
-
result_hash = {}
|
178
|
-
result.each do |cookie|
|
179
|
-
cookie['name'] = cookie['key']
|
180
|
-
cookie['expires'] = DateTime.parse(cookie['expires']).to_time if cookie.has_key?('expires')
|
181
|
-
result_hash[cookie['name']] = Isomorfeus::Puppetmaster::Cookie.new(cookie)
|
182
|
-
end
|
183
|
-
result_hash
|
184
|
-
end
|
185
|
-
|
186
|
-
def document_dismiss_confirm(document, **options, &block)
|
187
|
-
# TODO
|
188
|
-
text = options.has_key?(:text) ? "`#{options[:text]}`" : 'null'
|
189
|
-
@context.exec <<~JAVASCRIPT
|
190
|
-
ModalText = #{text};
|
191
|
-
AllDomHandles[#{document.handle}].on('dialog', DialogDismissHandler);
|
192
|
-
JAVASCRIPT
|
193
|
-
block.call
|
194
|
-
sleep @reaction_timeout
|
195
|
-
@context.eval 'ModalText'
|
196
|
-
ensure
|
197
|
-
matched = await <<~JAVASCRIPT
|
198
|
-
LastResult = ModalTextMatched;
|
199
|
-
ModalTextMatched = false;
|
200
|
-
ModalText = null;
|
201
|
-
AllDomHandles[#{document.handle}].removeListener('dialog', DialogDismissHandler);
|
202
|
-
JAVASCRIPT
|
203
|
-
raise Isomorfeus::Puppetmaster::ModalNotFound if options.has_key?(:text) && !matched
|
204
|
-
end
|
205
|
-
|
206
|
-
def document_dismiss_leave_page(document, **options, &block)
|
207
|
-
# TODO
|
208
|
-
text = options.has_key?(:text) ? "`#{options[:text]}`" : 'null'
|
209
|
-
@context.exec <<~JAVASCRIPT
|
210
|
-
ModalText = #{text};
|
211
|
-
AllDomHandles[#{document.handle}].on('dialog', DialogDismissHandler);
|
212
|
-
JAVASCRIPT
|
213
|
-
block.call
|
214
|
-
sleep @reaction_timeout
|
215
|
-
@context.eval 'ModalText'
|
216
|
-
ensure
|
217
|
-
matched = await <<~JAVASCRIPT
|
218
|
-
LastResult = ModalTextMatched;
|
219
|
-
ModalTextMatched = false;
|
220
|
-
ModalText = null;
|
221
|
-
AllDomHandles[#{document.handle}].removeListener('dialog', DialogDismissHandler);
|
222
|
-
JAVASCRIPT
|
223
|
-
raise Isomorfeus::Puppetmaster::ModalNotFound if options.has_key?(:text) && !matched
|
224
|
-
end
|
225
|
-
|
226
|
-
def document_dismiss_prompt(document, **options, &block)
|
227
|
-
# TODO
|
228
|
-
text = options.has_key?(:text) ? "`#{options[:text]}`" : 'null'
|
229
|
-
@context.exec <<~JAVASCRIPT
|
230
|
-
ModalText = #{text};
|
231
|
-
AllDomHandles[#{document.handle}].on('dialog', DialogDismissHandler);
|
232
|
-
JAVASCRIPT
|
233
|
-
block.call
|
234
|
-
sleep @reaction_timeout
|
235
|
-
@context.eval 'ModalText'
|
236
|
-
ensure
|
237
|
-
matched = await <<~JAVASCRIPT
|
238
|
-
LastResult = ModalTextMatched;
|
239
|
-
ModalTextMatched = false;
|
240
|
-
ModalText = null;
|
241
|
-
AllDomHandles[#{document.handle}].removeListener('dialog', DialogDismissHandler);
|
242
|
-
JAVASCRIPT
|
243
|
-
raise Isomorfeus::Puppetmaster::ModalNotFound if options.has_key?(:text) && !matched
|
244
|
-
end
|
245
|
-
|
246
|
-
def document_dispatch_event(document, name, event_type = nil, **options)
|
247
|
-
raise ArgumentError, 'Unknown event' unless EVENTS.key?(name.to_sym) || event_type
|
248
|
-
event_type, opts = *EVENTS[name.to_s.downcase.tr('_', '').to_sym] if event_type.nil?
|
249
|
-
opts.merge!(options)
|
250
|
-
final_options = options.map { |k,v| "#{k}: '#{v}'" }
|
251
|
-
@context.exec <<~JAVASCRIPT
|
252
|
-
var window = AllDomHandles[#{document.handle}].window;
|
253
|
-
var event = new window.#{event_type}('#{name}', { #{final_options.join(', ')} });
|
254
|
-
window.document.dispatchEvent(event);
|
255
|
-
JAVASCRIPT
|
256
|
-
end
|
257
|
-
|
258
|
-
def document_double_click(document, x: nil, y: nil, modifiers: nil)
|
259
|
-
# modifier_keys: :alt, :control, :meta, :shift
|
260
|
-
modifiers = [modifiers] if modifiers.is_a?(Symbol)
|
261
|
-
modifiers = [] unless modifiers
|
262
|
-
modifiers = modifiers.map {|key| key.to_s.camelize(:lower) }
|
263
|
-
await <<~JAVASCRIPT
|
264
|
-
var options = {button: 0, bubbles: true, cancelable: true};
|
265
|
-
var window = AllDomHandles[#{document.handle}].window;
|
266
|
-
var modifiers = #{modifiers};
|
267
|
-
if (modifiers.includes('meta')) { options['metaKey'] = true; }
|
268
|
-
if (modifiers.includes('control')) { options['ctrlKey'] = true; }
|
269
|
-
if (modifiers.includes('shift')) { options['shiftKey'] = true; }
|
270
|
-
if (modifiers.includes('alt')) { options['altKey'] = true; }
|
271
|
-
var x = #{x ? x : 'null'};
|
272
|
-
var y = #{y ? y : 'null'};
|
273
|
-
if (x && y) {
|
274
|
-
options['clientX'] = x;
|
275
|
-
options['clientY'] = y;
|
276
|
-
}
|
277
|
-
window.document.dispatchEvent(new window.MouseEvent('mousedown', options));
|
278
|
-
window.document.dispatchEvent(new window.MouseEvent('mouseup', options));
|
279
|
-
window.document.dispatchEvent(new window.MouseEvent('dblclick', options));
|
280
|
-
JAVASCRIPT
|
281
|
-
end
|
282
|
-
|
283
|
-
def document_evaluate_script(document, script, *args)
|
284
|
-
@context.eval <<~JAVASCRIPT
|
285
|
-
AllDomHandles[#{document.handle}].window.eval(
|
286
|
-
"var arguments = #{ "#{args}".gsub('"', '\"') };" +
|
287
|
-
"#{script.strip.gsub('\\', '\\\\\\').gsub('"', '\"').gsub("\n", "\\n")}"
|
288
|
-
)
|
289
|
-
JAVASCRIPT
|
290
|
-
rescue ExecJS::ProgramError => e
|
291
|
-
raise determine_error(e.message)
|
292
|
-
end
|
293
|
-
|
294
|
-
def document_execute_script(document, script, *args)
|
295
|
-
@context.eval <<~JAVASCRIPT
|
296
|
-
AllDomHandles[#{document.handle}].window.eval(
|
297
|
-
"(function() { var arguments = #{ "#{args}".gsub('"', '\"') };" +
|
298
|
-
"#{script.strip.gsub('\\', '\\\\\\').gsub('"', '\"').gsub("\n", "\\n")}" +
|
299
|
-
"})()"
|
300
|
-
)
|
301
|
-
JAVASCRIPT
|
302
|
-
rescue ExecJS::ProgramError => e
|
303
|
-
raise determine_error(e.message)
|
304
|
-
end
|
305
|
-
|
306
|
-
def document_find(document, selector)
|
307
|
-
js_escaped_selector = selector.gsub('\\', '\\\\\\').gsub('"', '\"')
|
308
|
-
node_data = @context.exec <<~JAVASCRIPT
|
309
|
-
var node = AllDomHandles[#{document.handle}].window.document.querySelector("#{js_escaped_selector}");
|
310
|
-
if (node) {
|
311
|
-
var node_handle = RegisterElementHandle(node);
|
312
|
-
var tag = node.tagName ? node.tagName.toLowerCase() : '';
|
313
|
-
var name = node.nodeName;
|
314
|
-
var type = null;
|
315
|
-
if (tag === 'input') { type = node.getAttribute('type'); }
|
316
|
-
return {handle: node_handle, name: name, tag: tag, type: type, content_editable: node.isContentEditable};
|
317
|
-
}
|
318
|
-
JAVASCRIPT
|
319
|
-
if node_data
|
320
|
-
node_data[:css_selector] = selector
|
321
|
-
Isomorfeus::Puppetmaster::Node.new_by_tag(self, document, node_data)
|
322
|
-
else
|
323
|
-
raise Isomorfeus::Puppetmaster::ElementNotFound.new(selector)
|
324
|
-
end
|
325
|
-
rescue Exception => e
|
326
|
-
raise determine_error(e.message)
|
327
|
-
end
|
328
|
-
|
329
|
-
def document_find_all(document, selector)
|
330
|
-
js_escaped_selector = selector.gsub('\\', '\\\\\\').gsub('"', '\"')
|
331
|
-
node_data_array = @context.exec <<~JAVASCRIPT
|
332
|
-
var node_array = AllDomHandles[#{document.handle}].window.document.querySelectorAll("#{js_escaped_selector}");
|
333
|
-
var node_data_array = [];
|
334
|
-
if (node_array) {
|
335
|
-
for (var i=0; i<node_array.length; i++) {
|
336
|
-
var node = node_array[i];
|
337
|
-
var node_handle = RegisterElementHandle(node_array[i]);
|
338
|
-
var tag = node.tagName ? node.tagName.toLowerCase() : '';
|
339
|
-
var name = node.nodeName;
|
340
|
-
var type = null;
|
341
|
-
if (tag === 'input') { type = node.getAttribute('type'); }
|
342
|
-
node_data_array.push({handle: node_handle, name: name, tag: tag, type: type, content_editable: node.isContentEditable});
|
343
|
-
}
|
344
|
-
}
|
345
|
-
return node_data_array;
|
346
|
-
JAVASCRIPT
|
347
|
-
node_data_array.map do |node_data|
|
348
|
-
node_data[:css_selector] = selector
|
349
|
-
Isomorfeus::Puppetmaster::Node.new_by_tag(self, document, node_data)
|
350
|
-
end
|
351
|
-
end
|
352
|
-
|
353
|
-
def document_find_all_xpath(document, query)
|
354
|
-
js_escaped_query = query.gsub('\\', '\\\\\\').gsub('"', '\"')
|
355
|
-
node_data_array = @context.exec <<~JAVASCRIPT
|
356
|
-
var window = AllDomHandles[#{document.handle}].window;
|
357
|
-
var document = window.document;
|
358
|
-
var xpath_result = document.evaluate("#{js_escaped_query}", document, null, window.XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
|
359
|
-
var node;
|
360
|
-
var node_data_array = [];
|
361
|
-
while (node = xpath_result.iterateNext()) {
|
362
|
-
var node_handle = RegisterElementHandle(node);
|
363
|
-
var tag = node.tagName ? node.tagName.toLowerCase() : '';
|
364
|
-
var name = node.nodeName;
|
365
|
-
var type = null;
|
366
|
-
if (tag === 'input') { type = node.getAttribute('type'); }
|
367
|
-
node_data_array.push({handle: node_handle, name: name, tag: tag, type: type, content_editable: node.isContentEditable});
|
368
|
-
}
|
369
|
-
return node_data_array;
|
370
|
-
JAVASCRIPT
|
371
|
-
node_data_array.map do |node_data|
|
372
|
-
node_data[:xpath_query] = query
|
373
|
-
Isomorfeus::Puppetmaster::Node.new_by_tag(self, document, node_data)
|
374
|
-
end
|
375
|
-
end
|
376
|
-
|
377
|
-
def document_find_xpath(document, query)
|
378
|
-
js_escaped_query = query.gsub('\\', '\\\\\\').gsub('"', '\"')
|
379
|
-
node_data = @context.exec <<~JAVASCRIPT
|
380
|
-
var window = AllDomHandles[#{document.handle}].window;
|
381
|
-
var document = window.document;
|
382
|
-
var xpath_result = document.evaluate("#{js_escaped_query}", document, null, window.XPathResult.FIRST_ORDERED_NODE_TYPE, null);
|
383
|
-
var node = xpath_result.singleNodeValue;
|
384
|
-
if (node) {
|
385
|
-
var node_handle = RegisterElementHandle(node);
|
386
|
-
var tag = node.tagName ? node.tagName.toLowerCase() : '';
|
387
|
-
var name = node.nodeName;
|
388
|
-
var type = null;
|
389
|
-
if (tag === 'input') { type = node.getAttribute('type'); }
|
390
|
-
return {handle: node_handle, name: name, tag: tag, type: type, content_editable: node.isContentEditable};
|
391
|
-
}
|
392
|
-
JAVASCRIPT
|
393
|
-
if node_data
|
394
|
-
node_data[:xpath_query] = query
|
395
|
-
Isomorfeus::Puppetmaster::Node.new_by_tag(self, document, node_data)
|
396
|
-
else
|
397
|
-
raise Isomorfeus::Puppetmaster::ElementNotFound.new(query)
|
398
|
-
end
|
399
|
-
rescue ExecJS::ProgramError => e
|
400
|
-
raise determine_error('invalid xpath query')
|
401
|
-
end
|
402
|
-
|
403
|
-
def document_go_back(document)
|
404
|
-
raise 'Browser history not supported.'
|
405
|
-
@context.eval "AllDomHandles[#{document.handle}].window.history.back()"
|
406
|
-
end
|
407
|
-
|
408
|
-
def document_go_forward(document)
|
409
|
-
raise 'Browser history not supported.'
|
410
|
-
@context.eval "AllDomHandles[#{document.handle}].window.history.forward()"
|
411
|
-
end
|
412
|
-
|
413
|
-
def document_goto(document, uri)
|
414
|
-
parsed_uri = URI.parse(uri)
|
415
|
-
parsed_uri.host = @app.host unless parsed_uri.host
|
416
|
-
parsed_uri.port = @app.port unless parsed_uri.port
|
417
|
-
parsed_uri.scheme = @app.scheme unless parsed_uri.scheme
|
418
|
-
response_hash, messages = await <<~JAVASCRIPT
|
419
|
-
ConsoleMessages[#{document.handle}] = [];
|
420
|
-
var cookie_jar = AllDomHandles[#{document.handle}].cookieJar.cloneSync(new MemoryCookieStore());
|
421
|
-
cookie_jar.rejectPublicSuffixes = false;
|
422
|
-
var con = new jsdom.VirtualConsole()
|
423
|
-
con.on('error', (msg) => { ConsoleMessages[#{document.handle}].push({level: 'error', location: '', text: msg}); });
|
424
|
-
con.on('warn', (msg) => { ConsoleMessages[#{document.handle}].push({level: 'warn', location: '', text: msg}); });
|
425
|
-
con.on('info', (msg) => { ConsoleMessages[#{document.handle}].push({level: 'info', location: '', text: msg}); });
|
426
|
-
con.on('log', (msg) => { ConsoleMessages[#{document.handle}].push({level: 'dir', location: '', text: msg}); });
|
427
|
-
con.on('debug', (msg) => { ConsoleMessages[#{document.handle}].push({level: 'dir', location: '', text: msg}); });
|
428
|
-
AllConsoleHandles[#{document.handle}] = con;
|
429
|
-
try {
|
430
|
-
var new_dom = await JSDOM.fromURL('#{parsed_uri.to_s}', Object.assign({}, JSDOMOptions, { cookieJar: cookie_jar, virtualConsole: con }));
|
431
|
-
AllDomHandles[#{document.handle}] = new_dom;
|
432
|
-
var formatted_response = {
|
433
|
-
headers: {},
|
434
|
-
ok: true,
|
435
|
-
remote_address: '#{parsed_uri.to_s}',
|
436
|
-
request: {},
|
437
|
-
status: 200,
|
438
|
-
status_text: '',
|
439
|
-
text: '',
|
440
|
-
url: '#{parsed_uri.to_s}'
|
441
|
-
};
|
442
|
-
LastResult = [formatted_response, ConsoleMessages[#{document.handle}]];
|
443
|
-
} catch (err) {
|
444
|
-
var formatted_error_response = {
|
445
|
-
headers: err.options.headers,
|
446
|
-
ok: false,
|
447
|
-
remote_address: '#{parsed_uri.to_s}',
|
448
|
-
request: {},
|
449
|
-
status: err.statusCode ? err.statusCode : 500,
|
450
|
-
status_text: err.response ? err.response.statusMessage : '',
|
451
|
-
text: err.message ? err.message : '',
|
452
|
-
url: '#{parsed_uri.to_s}'
|
453
|
-
};
|
454
|
-
LastResult = [formatted_error_response, ConsoleMessages[#{document.handle}]];
|
455
|
-
}
|
456
|
-
JAVASCRIPT
|
457
|
-
con_messages = messages.map {|m| Isomorfeus::Puppetmaster::ConsoleMessage.new(m)}
|
458
|
-
# STDERR.puts 'M', con_messages
|
459
|
-
# STDERR.puts 'R', response_hash
|
460
|
-
con_messages.each { |m| raise determine_error(m.text) if m.level == 'error' && !m.text.start_with?('Failed to load resource:') }
|
461
|
-
if response_hash
|
462
|
-
response = Isomorfeus::Puppetmaster::Response.new(response_hash)
|
463
|
-
if response.status == 500 && response.text.start_with?('Error:')
|
464
|
-
error = determine_error(response.text)
|
465
|
-
raise error if error
|
466
|
-
end
|
467
|
-
document.instance_variable_set(:@response, response)
|
468
|
-
end
|
469
|
-
document.response
|
470
|
-
end
|
471
|
-
|
472
|
-
def document_head(document)
|
473
|
-
node_data = @context.exec <<~JAVASCRIPT
|
474
|
-
var node = AllDomHandles[#{document.handle}].window.document.head;
|
475
|
-
var node_handle = RegisterElementHandle(node);
|
476
|
-
var name = node.nodeName;
|
477
|
-
var tag = node.tagName.toLowerCase();
|
478
|
-
return {handle: node_handle, name: name, tag: tag, type: null, content_editable: node.isContentEditable};
|
479
|
-
JAVASCRIPT
|
480
|
-
if node_data
|
481
|
-
node_data[:css_selector] = 'body'
|
482
|
-
Isomorfeus::Puppetmaster::Node.new_by_tag(self, document, node_data)
|
483
|
-
end
|
484
|
-
end
|
485
|
-
|
486
|
-
def document_html(document)
|
487
|
-
@context.eval "AllDomHandles[#{document.handle}].serialize()"
|
488
|
-
end
|
489
|
-
|
490
|
-
def document_open_new_document(_document, uri = nil)
|
491
|
-
if !uri || uri == 'about:blank'
|
492
|
-
parsed_uri = 'about:blank'
|
493
|
-
else
|
494
|
-
parsed_uri = URI.parse(uri)
|
495
|
-
parsed_uri.host = @app.host unless parsed_uri.host
|
496
|
-
parsed_uri.port = @app.port unless parsed_uri.port
|
497
|
-
parsed_uri.scheme = @app.scheme unless parsed_uri.scheme
|
498
|
-
end
|
499
|
-
handle, response_hash, messages = await <<~JAVASCRIPT
|
500
|
-
var con = new jsdom.VirtualConsole();
|
501
|
-
var jar = new jsdom.CookieJar(new MemoryCookieStore(), {rejectPublicSuffixes: false, looseMode: true});
|
502
|
-
var handle_id = RegisterCon(con);
|
503
|
-
con.on('error', (msg) => { ConsoleMessages[handle_id].push({level: 'error', location: '', text: msg}); });
|
504
|
-
con.on('warn', (msg) => { ConsoleMessages[handle_id].push({level: 'warn', location: '', text: msg}); });
|
505
|
-
con.on('info', (msg) => { ConsoleMessages[handle_id].push({level: 'info', location: '', text: msg}); });
|
506
|
-
con.on('log', (msg) => { ConsoleMessages[handle_id].push({level: 'dir', location: '', text: msg}); });
|
507
|
-
con.on('debug', (msg) => { ConsoleMessages[handle_id].push({level: 'dir', location: '', text: msg}); });
|
508
|
-
try {
|
509
|
-
var new_dom;
|
510
|
-
var uri = '#{parsed_uri.to_s}';
|
511
|
-
if (uri === 'about:blank') {
|
512
|
-
new_dom = new JSDOM('', Object.assign({}, JSDOMOptions, { cookieJar: jar, virtualConsole: con }));
|
513
|
-
} else {
|
514
|
-
new_dom = await JSDOM.fromURL(uri, Object.assign({}, JSDOMOptions, { cookieJar: jar, virtualConsole: con }));
|
515
|
-
}
|
516
|
-
AllDomHandles[handle_id] = new_dom;
|
517
|
-
var formatted_response = {
|
518
|
-
headers: {},
|
519
|
-
ok: false,
|
520
|
-
remote_address: '#{parsed_uri.to_s}',
|
521
|
-
request: {},
|
522
|
-
status: 200,
|
523
|
-
status_text: '',
|
524
|
-
text: '',
|
525
|
-
url: '#{parsed_uri.to_s}'
|
526
|
-
};
|
527
|
-
LastResult = [handle_id, formatted_response, ConsoleMessages[handle_id]];
|
528
|
-
} catch (err) {
|
529
|
-
var formatted_response = {
|
530
|
-
headers: err.options.headers,
|
531
|
-
ok: true,
|
532
|
-
remote_address: '#{parsed_uri.to_s}',
|
533
|
-
request: {},
|
534
|
-
status: err.statusCode,
|
535
|
-
status_text: err.response ? err.response.statusMessage : '',
|
536
|
-
text: '',
|
537
|
-
url: '#{parsed_uri.to_s}'
|
538
|
-
};
|
539
|
-
LastResult = [handle_id, formatted_response, ConsoleMessages[handle_id]];
|
540
|
-
}
|
541
|
-
JAVASCRIPT
|
542
|
-
# STDERR.puts 'R', response_hash
|
543
|
-
# STDERR.puts 'C', messages
|
544
|
-
con_messages = messages.map {|m| Isomorfeus::Puppetmaster::ConsoleMessage.new(m)}
|
545
|
-
con_messages.each { |m| raise determine_error(m.text) if m.level == 'error' && !m.text.start_with?('Failed to load resource:') }
|
546
|
-
response = Isomorfeus::Puppetmaster::Response.new(response_hash)
|
547
|
-
if response.status == 500 && response.text.start_with?('Error:')
|
548
|
-
error = determine_error(response.text)
|
549
|
-
raise error if error
|
550
|
-
end
|
551
|
-
Isomorfeus::Puppetmaster::Document.new(self, handle, response)
|
552
|
-
end
|
553
|
-
|
554
|
-
def document_reload(document)
|
555
|
-
document_goto(document, document_url(document))
|
556
|
-
end
|
557
|
-
|
558
|
-
def document_remove_cookie(document, name)
|
559
|
-
uri = document_url(document)
|
560
|
-
if uri == 'about:blank'
|
561
|
-
uri = if Isomorfeus::Puppetmaster.server_host
|
562
|
-
u = URI.new
|
563
|
-
u.scheme = Isomorfeus::Puppetmaster.server_scheme if Isomorfeus::Puppetmaster.server_scheme
|
564
|
-
u.host = Isomorfeus::Puppetmaster.server_host
|
565
|
-
u.to_s
|
566
|
-
else
|
567
|
-
'http://127.0.0.1'
|
568
|
-
end
|
569
|
-
end
|
570
|
-
domain = URI.parse(uri).host
|
571
|
-
await <<~JAVASCRIPT
|
572
|
-
var cookies = AllDomHandles[#{document.handle}].cookieJar.getCookiesSync('#{uri.to_s}')
|
573
|
-
var path = '/';
|
574
|
-
for(i=0; i<cookies.length; i++) {
|
575
|
-
if (cookies[i].key === '#{name}' && cookies[i].domain === '#{domain}') {
|
576
|
-
var path = cookies[i].path;
|
577
|
-
break;
|
578
|
-
}
|
579
|
-
}
|
580
|
-
var promise = new Promise(function(resolve, reject) {
|
581
|
-
AllDomHandles[#{document.handle}].cookieJar.store.removeCookie('#{domain}', path, '#{name}', function(err){ resolve(true); });
|
582
|
-
})
|
583
|
-
await promise;
|
584
|
-
JAVASCRIPT
|
585
|
-
end
|
586
|
-
|
587
|
-
def document_render_base64(document, **options)
|
588
|
-
raise Isomorfeus::Puppetmaster::NotSupported
|
589
|
-
end
|
590
|
-
|
591
|
-
def document_reset_user_agent(document)
|
592
|
-
raise Isomorfeus::Puppetmaster::NotSupported
|
593
|
-
end
|
594
|
-
|
595
|
-
def document_right_click(document, x: nil, y: nil, modifiers: nil)
|
596
|
-
# modifier_keys: :alt, :control, :meta, :shift
|
597
|
-
modifiers = [modifiers] if modifiers.is_a?(Symbol)
|
598
|
-
modifiers = [] unless modifiers
|
599
|
-
modifiers = modifiers.map {|key| key.to_s.camelize(:lower) }
|
600
|
-
await <<~JAVASCRIPT
|
601
|
-
var options = {button: 2, bubbles: true, cancelable: true};
|
602
|
-
var window = AllDomHandles[#{document.handle}].window;
|
603
|
-
var modifiers = #{modifiers};
|
604
|
-
if (modifiers.includes('meta')) { options['metaKey'] = true; }
|
605
|
-
if (modifiers.includes('control')) { options['ctrlKey'] = true; }
|
606
|
-
if (modifiers.includes('shift')) { options['shiftKey'] = true; }
|
607
|
-
if (modifiers.includes('alt')) { options['altKey'] = true; }
|
608
|
-
var x = #{x ? x : 'null'};
|
609
|
-
var y = #{y ? y : 'null'};
|
610
|
-
if (x && y) {
|
611
|
-
options['clientX'] = x;
|
612
|
-
options['clientY'] = y;
|
613
|
-
}
|
614
|
-
window.document.dispatchEvent(new window.MouseEvent('mousedown', options));
|
615
|
-
window.document.dispatchEvent(new window.MouseEvent('mouseup', options));
|
616
|
-
window.document.dispatchEvent(new window.MouseEvent('contextmenu', options));
|
617
|
-
JAVASCRIPT
|
618
|
-
end
|
619
|
-
|
620
|
-
def document_save_pdf(document, **options)
|
621
|
-
raise Isomorfeus::Puppetmaster::NotSupported
|
622
|
-
end
|
623
|
-
|
624
|
-
def document_save_screenshot(document, file, **options)
|
625
|
-
raise Isomorfeus::Puppetmaster::NotSupported
|
626
|
-
end
|
627
|
-
|
628
|
-
def document_scroll_by(document, x, y)
|
629
|
-
@context.exec <<~JAVASCRIPT
|
630
|
-
AllDomHandles[#{document.handle}].window.scrollX = AllDomHandles[#{document.handle}].window.scrollX + #{x};
|
631
|
-
AllDomHandles[#{document.handle}].window.scrollY = AllDomHandles[#{document.handle}].window.scrollY + #{y};
|
632
|
-
JAVASCRIPT
|
633
|
-
end
|
634
|
-
|
635
|
-
def document_scroll_to(document, x, y)
|
636
|
-
@context.exec <<~JAVASCRIPT
|
637
|
-
AllDomHandles[#{document.handle}].window.scrollX = #{x};
|
638
|
-
AllDomHandles[#{document.handle}].window.scrollY = #{y};
|
639
|
-
JAVASCRIPT
|
640
|
-
end
|
641
|
-
|
642
|
-
def document_set_authentication_credentials(document, username, password)
|
643
|
-
raise Isomorfeus::Puppetmaster::NotSupported
|
644
|
-
end
|
645
|
-
|
646
|
-
def document_set_cookie(document, name, value, **options)
|
647
|
-
options[:key] ||= name
|
648
|
-
options[:value] ||= value
|
649
|
-
uri = document_url(document)
|
650
|
-
if uri == 'about:blank'
|
651
|
-
uri = if Isomorfeus::Puppetmaster.server_host
|
652
|
-
u = URI.new
|
653
|
-
u.scheme = Isomorfeus::Puppetmaster.server_scheme if Isomorfeus::Puppetmaster.server_scheme
|
654
|
-
u.host = Isomorfeus::Puppetmaster.server_host
|
655
|
-
u.to_s
|
656
|
-
else
|
657
|
-
'http://127.0.0.1'
|
658
|
-
end
|
659
|
-
end
|
660
|
-
options[:domain] ||= URI.parse(uri).host
|
661
|
-
final_options = []
|
662
|
-
final_options << "expires: new Date('#{options.delete(:expires).to_s}')" if options.has_key?(:expires)
|
663
|
-
final_options << "httpOnly: #{options.delete(:http_only)}" if options.has_key?(:http_only)
|
664
|
-
final_options << "secure: #{options.delete(:secure)}" if options.has_key?(:secure)
|
665
|
-
final_options << "sameSite: '#{options.delete(:same_site)}'" if options.has_key?(:same_site)
|
666
|
-
options.each do |k,v|
|
667
|
-
final_options << "#{k}: '#{v}'"
|
668
|
-
end
|
669
|
-
@context.exec "AllDomHandles[#{document.handle}].cookieJar.setCookieSync(new Cookie({#{final_options.join(', ')}}), '#{uri.to_s}', {ignoreError: true})"
|
670
|
-
end
|
671
|
-
|
672
|
-
def document_set_extra_headers(document, headers_hash)
|
673
|
-
raise Isomorfeus::Puppetmaster::NotSupported
|
674
|
-
end
|
675
|
-
|
676
|
-
def document_set_user_agent(document, agent_string)
|
677
|
-
raise Isomorfeus::Puppetmaster::NotSupported
|
678
|
-
end
|
679
|
-
|
680
|
-
def document_title(document)
|
681
|
-
@context.eval "AllDomHandles[#{document.handle}].window.document.title"
|
682
|
-
end
|
683
|
-
|
684
|
-
def document_type_keys(document, *keys)
|
685
|
-
cjs = <<~JAVASCRIPT
|
686
|
-
var window = AllDomHandles[#{document.handle}].window;
|
687
|
-
var events = [];
|
688
|
-
var options = {bubbles: true, cancelable: true};
|
689
|
-
JAVASCRIPT
|
690
|
-
top_modifiers = []
|
691
|
-
keys.each do |key|
|
692
|
-
if key.is_a?(String)
|
693
|
-
key.each_char do |c|
|
694
|
-
shift = !! /[[:upper:]]/.match(c)
|
695
|
-
cjs << <<~JAVASCRIPT
|
696
|
-
events.push(new window.KeyboardEvent('keydown', { bubbles: true, cancelable: true, key: '#{c}'.charCodeAt(0), char: '#{c}',
|
697
|
-
altKey: #{need_alt?(top_modifiers)}, ctrlKey: #{need_control?(top_modifiers)}, metaKey: #{need_meta?(top_modifiers)},
|
698
|
-
shiftKey: #{shift || need_shift?(top_modifiers)}}));
|
699
|
-
JAVASCRIPT
|
700
|
-
cjs << <<~JAVASCRIPT
|
701
|
-
events.push(new window.KeyboardEvent('keypress', { bubbles: true, cancelable: true, key: '#{c}'.charCodeAt(0), char: '#{c}',
|
702
|
-
altKey: #{need_alt?(top_modifiers)}, ctrlKey: #{need_control?(top_modifiers)}, metaKey: #{need_meta?(top_modifiers)},
|
703
|
-
shiftKey: #{shift || need_shift?(top_modifiers)}}));
|
704
|
-
JAVASCRIPT
|
705
|
-
cjs << <<~JAVASCRIPT
|
706
|
-
events.push(new window.KeyboardEvent('keyup', { bubbles: true, cancelable: true, key: '#{c}'.charCodeAt(0), char: '#{c}',
|
707
|
-
altKey: #{need_alt?(top_modifiers)}, ctrlKey: #{need_control?(top_modifiers)}, metaKey: #{need_meta?(top_modifiers)},
|
708
|
-
shiftKey: #{shift || need_shift?(top_modifiers)}}));
|
709
|
-
JAVASCRIPT
|
710
|
-
end
|
711
|
-
elsif key.is_a?(Symbol)
|
712
|
-
if %i[ctrl Ctrl].include?(key)
|
713
|
-
key = :control
|
714
|
-
elsif %i[command Command Meta].include?(key)
|
715
|
-
key = :meta
|
716
|
-
elsif %i[divide Divide].include?(key)
|
717
|
-
key = :numpad_divide
|
718
|
-
elsif %i[decimal Decimal].include?(key)
|
719
|
-
key = :numpad_decimal
|
720
|
-
elsif %i[left right up down].include?(key)
|
721
|
-
key = "arrow_#{key}".to_sym
|
722
|
-
end
|
723
|
-
if %i[alt alt_left alt_right control control_left control_rigth meta meta_left meta_right shift shift_left shift_right].include?(key)
|
724
|
-
top_modifiers << key
|
725
|
-
cjs << <<~JAVASCRIPT
|
726
|
-
events.push(new window.KeyboardEvent('keydown', { bubbles: true, cancelable: true, key: '#{key.to_s.camelize}', code: '#{key.to_s.camelize}',
|
727
|
-
altKey: #{need_alt?(top_modifiers)}, ctrlKey: #{need_control?(top_modifiers)}, metaKey: #{need_meta?(top_modifiers)},
|
728
|
-
shiftKey: #{need_shift?(top_modifiers)}}));
|
729
|
-
JAVASCRIPT
|
730
|
-
else
|
731
|
-
cjs << <<~JAVASCRIPT
|
732
|
-
events.push(new window.KeyboardEvent('keydown', { bubbles: true, cancelable: true, key: '#{key.to_s.camelize}', code: '#{key.to_s.camelize}',
|
733
|
-
altKey: #{need_alt?(top_modifiers)}, ctrlKey: #{need_control?(top_modifiers)}, metaKey: #{need_meta?(top_modifiers)},
|
734
|
-
shiftKey: #{need_shift?(top_modifiers)}}));
|
735
|
-
JAVASCRIPT
|
736
|
-
cjs << <<~JAVASCRIPT
|
737
|
-
events.push(new window.KeyboardEvent('keypress', { bubbles: true, cancelable: true, key: '#{key.to_s.camelize}', code: '#{key.to_s.camelize}',
|
738
|
-
altKey: #{need_alt?(top_modifiers)}, ctrlKey: #{need_control?(top_modifiers)}, metaKey: #{need_meta?(top_modifiers)},
|
739
|
-
shiftKey: #{need_shift?(top_modifiers)}}));
|
740
|
-
JAVASCRIPT
|
741
|
-
cjs << <<~JAVASCRIPT
|
742
|
-
events.push(new window.KeyboardEvent('keyup', { bubbles: true, cancelable: true, key: '#{key.to_s.camelize}', code: '#{key.to_s.camelize}',
|
743
|
-
altKey: #{need_alt?(top_modifiers)}, ctrlKey: #{need_control?(top_modifiers)}, metaKey: #{need_meta?(top_modifiers)},
|
744
|
-
shiftKey: #{need_shift?(top_modifiers)}}));
|
745
|
-
JAVASCRIPT
|
746
|
-
end
|
747
|
-
elsif key.is_a?(Array)
|
748
|
-
modifiers = []
|
749
|
-
key.each do |k|
|
750
|
-
if k.is_a?(Symbol)
|
751
|
-
if %i[ctrl Ctrl].include?(k)
|
752
|
-
k = :control
|
753
|
-
elsif %i[command Command Meta].include?(k)
|
754
|
-
k = :meta
|
755
|
-
elsif %i[divide Divide].include?(k)
|
756
|
-
k = :numpad_divide
|
757
|
-
elsif %i[decimal Decimal].include?(k)
|
758
|
-
k = :numpad_decimal
|
759
|
-
elsif %i[left right up down].include?(key)
|
760
|
-
k = "arrow_#{key}".to_sym
|
761
|
-
end
|
762
|
-
if %i[alt alt_left alt_right control control_left control_rigth meta meta_left meta_right shift shift_left shift_right].include?(k)
|
763
|
-
modifiers << k
|
764
|
-
cjs << <<~JAVASCRIPT
|
765
|
-
events.push(new window.KeyboardEvent('keydown', { bubbles: true, cancelable: true, key: '#{k.to_s.camelize}', code: '#{k.to_s.camelize}',
|
766
|
-
altKey: #{need_alt?(modifiers)}, ctrlKey: #{need_control?(modifiers)}, metaKey: #{need_meta?(modifiers)},
|
767
|
-
shiftKey: #{need_shift?(modifiers)}}));
|
768
|
-
JAVASCRIPT
|
769
|
-
else
|
770
|
-
cjs << <<~JAVASCRIPT
|
771
|
-
events.push(new window.KeyboardEvent('keydown', { bubbles: true, cancelable: true, key: '#{k.to_s.camelize}', code: '#{k.to_s.camelize}',
|
772
|
-
altKey: #{need_alt?(modifiers)}, ctrlKey: #{need_control?(modifiers)}, metaKey: #{need_meta?(modifiers)},
|
773
|
-
shiftKey: #{need_shift?(modifiers)}}));
|
774
|
-
JAVASCRIPT
|
775
|
-
cjs << <<~JAVASCRIPT
|
776
|
-
events.push(new window.KeyboardEvent('keypress', { bubbles: true, cancelable: true, key: '#{k.to_s.camelize}', code: '#{k.to_s.camelize}',
|
777
|
-
altKey: #{need_alt?(modifiers)}, ctrlKey: #{need_control?(modifiers)}, metaKey: #{need_meta?(modifiers)},
|
778
|
-
shiftKey: #{need_shift?(modifiers)}}));
|
779
|
-
JAVASCRIPT
|
780
|
-
cjs << <<~JAVASCRIPT
|
781
|
-
events.push(new window.KeyboardEvent('keyup', { bubbles: true, cancelable: true, key: '#{k.to_s.camelize}', code: '#{k.to_s.camelize}',
|
782
|
-
altKey: #{need_alt?(modifiers)}, ctrlKey: #{need_control?(modifiers)}, metaKey: #{need_meta?(modifiers)},
|
783
|
-
shiftKey: #{need_shift?(modifiers)}}));
|
784
|
-
JAVASCRIPT
|
785
|
-
end
|
786
|
-
elsif k.is_a?(String)
|
787
|
-
k.each_char do |c|
|
788
|
-
shift = !! /[[:upper:]]/.match(c)
|
789
|
-
cjs << <<~JAVASCRIPT
|
790
|
-
events.push(new window.KeyboardEvent('keydown', { bubbles: true, cancelable: true, key: '#{c}'.charCodeAt(0), char: '#{c}',
|
791
|
-
altKey: #{need_alt?(modifiers)}, ctrlKey: #{need_control?(modifiers)}, metaKey: #{need_meta?(modifiers)},
|
792
|
-
shiftKey: #{shift || need_shift?(modifiers)}}));
|
793
|
-
JAVASCRIPT
|
794
|
-
cjs << <<~JAVASCRIPT
|
795
|
-
events.push(new window.KeyboardEvent('keypress', { bubbles: true, cancelable: true, key: '#{c}'.charCodeAt(0), char: '#{c}',
|
796
|
-
altKey: #{need_alt?(modifiers)}, ctrlKey: #{need_control?(modifiers)}, metaKey: #{need_meta?(modifiers)},
|
797
|
-
shiftKey: #{shift || need_shift?(modifiers)}}));
|
798
|
-
JAVASCRIPT
|
799
|
-
cjs << <<~JAVASCRIPT
|
800
|
-
events.push(new window.KeyboardEvent('keyup', { bubbles: true, cancelable: true, key: '#{c}'.charCodeAt(0), char: '#{c}',
|
801
|
-
altKey: #{need_alt?(modifiers)}, ctrlKey: #{need_control?(modifiers)}, metaKey: #{need_meta?(modifiers)},
|
802
|
-
shiftKey: #{shift || need_shift?(modifiers)}}));
|
803
|
-
JAVASCRIPT
|
804
|
-
end
|
805
|
-
end
|
806
|
-
end
|
807
|
-
modifiers.reverse.each do |k|
|
808
|
-
cjs << <<~JAVASCRIPT
|
809
|
-
events.push(new window.KeyboardEvent('keyup', { bubbles: true, cancelable: true, key: '#{k.to_s.camelize}', code: '#{k.to_s.camelize}',
|
810
|
-
altKey: #{need_alt?(modifiers)}, ctrlKey: #{need_control?(modifiers)}, metaKey: #{need_meta?(modifiers)},
|
811
|
-
shiftKey: #{need_shift?(modifiers)}}));
|
812
|
-
JAVASCRIPT
|
813
|
-
end
|
814
|
-
end
|
815
|
-
end
|
816
|
-
top_modifiers.reverse.each do |key|
|
817
|
-
cjs << <<~JAVASCRIPT
|
818
|
-
events.push(new window.KeyboardEvent('keyup', { bubbles: true, cancelable: true, key: '#{key.to_s.camelize}', code: '#{key.to_s.camelize}',
|
819
|
-
altKey: #{need_alt?(top_modifiers)}, ctrlKey: #{need_control?(top_modifiers)}, metaKey: #{need_meta?(top_modifiers)},
|
820
|
-
shiftKey: #{need_shift?(top_modifiers)}}));
|
821
|
-
JAVASCRIPT
|
822
|
-
end
|
823
|
-
cjs << <<~JAVASCRIPT
|
824
|
-
for (i=0; i<events.length; i++) {
|
825
|
-
window.document.dispatchEvent(events[i]);
|
826
|
-
}
|
827
|
-
JAVASCRIPT
|
828
|
-
@context.exec cjs
|
829
|
-
end
|
830
|
-
|
831
|
-
def document_url(document)
|
832
|
-
@context.eval "AllDomHandles[#{document.handle}].window.location.href"
|
833
|
-
end
|
834
|
-
|
835
|
-
def document_user_agent(document)
|
836
|
-
@context.eval "AllDomHandles[#{document.handle}].window.navigator.userAgent"
|
837
|
-
end
|
838
|
-
|
839
|
-
def document_viewport_maximize(document)
|
840
|
-
document_viewport_resize(document, @max_width, @max_height)
|
841
|
-
end
|
842
|
-
|
843
|
-
def document_viewport_resize(document, width, height)
|
844
|
-
width = @max_width if width > @max_width
|
845
|
-
height = @max_height if width > @max_height
|
846
|
-
@context.exec <<~JAVASCRIPT
|
847
|
-
AllDomHandles[#{document.handle}].window.innerWidth = #{width};
|
848
|
-
AllDomHandles[#{document.handle}].window.innerHeight = #{height};
|
849
|
-
JAVASCRIPT
|
850
|
-
end
|
851
|
-
|
852
|
-
def document_viewport_size(document)
|
853
|
-
@context.eval "[AllDomHandles[#{document.handle}].window.innerWidth, AllDomHandles[#{document.handle}].window.innerHeight]"
|
854
|
-
end
|
855
|
-
|
856
|
-
def document_wait_for(document, selector)
|
857
|
-
js_escaped_selector = selector.gsub('\\', '\\\\\\').gsub('"', '\"')
|
858
|
-
node_data = await <<~JAVASCRIPT
|
859
|
-
var node = null;
|
860
|
-
var start_time = new Date();
|
861
|
-
var resolver = function(resolve) {
|
862
|
-
node = AllDomHandles[#{document.handle}].window.document.querySelector("#{js_escaped_selector}");
|
863
|
-
if (node) {
|
864
|
-
var node_handle = RegisterElementHandle(node);
|
865
|
-
var name = node.nodeName;
|
866
|
-
var tag = node.tagName.toLowerCase();
|
867
|
-
var type = null;
|
868
|
-
if (tag === 'input') { type = node.getAttribute('type'); }
|
869
|
-
LastResult = {handle: node_handle, name: name, tag: tag, type: type, content_editable: node.isContentEditable};
|
870
|
-
resolve(true);
|
871
|
-
}
|
872
|
-
else if ((new Date() - start_time) > #{@jsdom_timeout}) { resolve(true); }
|
873
|
-
else { setTimeout(resolver, #{@jsdom_reaction_timeout}, resolve) }
|
874
|
-
};
|
875
|
-
var promise = new Promise(function(resolve, reject){ resolver(resolve); });
|
876
|
-
await promise;
|
877
|
-
JAVASCRIPT
|
878
|
-
if node_data
|
879
|
-
node_data[:css_selector] = selector
|
880
|
-
Isomorfeus::Puppetmaster::Node.new_by_tag(self, document, node_data)
|
881
|
-
end
|
882
|
-
end
|
883
|
-
|
884
|
-
def document_wait_for_xpath(document, query)
|
885
|
-
js_escaped_query = query.gsub('\\', '\\\\\\').gsub('"', '\"')
|
886
|
-
node_data = await <<~JAVASCRIPT
|
887
|
-
var node = null;
|
888
|
-
var start_time = new Date();
|
889
|
-
var resolver = function(resolve) {
|
890
|
-
var window = AllDomHandles[#{document.handle}].window;
|
891
|
-
var document = window.document;
|
892
|
-
var xpath_result = document.evaluate("#{js_escaped_query}", document, null, window.XPathResult.FIRST_ORDERED_NODE_TYPE, null);
|
893
|
-
node = xpath_result.singleNodeValue;
|
894
|
-
if (node) {
|
895
|
-
var node_handle = RegisterElementHandle(node);
|
896
|
-
var name = node.nodeName;
|
897
|
-
var tag = node.tagName.toLowerCase();
|
898
|
-
var type = null;
|
899
|
-
if (tag === 'input') { type = node.getAttribute('type'); }
|
900
|
-
LastResult = {handle: node_handle, name: name, tag: tag, type: type, content_editable: node.isContentEditable};
|
901
|
-
resolve(true);
|
902
|
-
}
|
903
|
-
else if ((new Date() - start_time) > #{@jsdom_timeout}) { resolve(true); }
|
904
|
-
else { setTimeout(resolver, #{@jsdom_reaction_timeout}, resolve) }
|
905
|
-
};
|
906
|
-
var promise = new Promise(function(resolve, reject){ resolver(resolve); });
|
907
|
-
await promise;
|
908
|
-
JAVASCRIPT
|
909
|
-
if node_data
|
910
|
-
node_data[:xpath_query] = query
|
911
|
-
Isomorfeus::Puppetmaster::Node.new_by_tag(self, document, node_data)
|
912
|
-
end
|
913
|
-
end
|
914
|
-
end
|
915
|
-
end
|
916
|
-
end
|
917
|
-
end
|