Class: Puppeteer::DOMWorld
- Inherits:
-
Object
- Object
- Puppeteer::DOMWorld
- Defined in:
- lib/puppeteer/dom_world.rb
Overview
Defined Under Namespace
Classes: BindingFunction, DetachedError, ElementNotFoundError
Constant Summary collapse
- ADD_SCRIPT_URL =
"async (url, id, type) => {\n const script = document.createElement('script');\n script.src = url;\n if (id) script.id = id;\n if (type) script.type = type;\n const promise = new Promise((res, rej) => {\n script.onload = res;\n script.onerror = rej;\n });\n document.head.appendChild(script);\n await promise;\n return script;\n}\n"- ADD_SCRIPT_CONTENT =
"(content, id, type) => {\n const script = document.createElement('script');\n script.type = type;\n script.text = content;\n if (id) script.id = id;\n let error = null;\n script.onerror = e => error = e;\n document.head.appendChild(script);\n if (error)\n throw error;\n return script;\n}\n"- ADD_STYLE_URL =
"async (url) => {\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.href = url;\n const promise = new Promise((res, rej) => {\n link.onload = res;\n link.onerror = rej;\n });\n document.head.appendChild(link);\n await promise;\n return link;\n}\n"- ADD_STYLE_CONTENT =
"async (content) => {\n const style = document.createElement('style');\n style.type = 'text/css';\n style.appendChild(document.createTextNode(content));\n const promise = new Promise((res, rej) => {\n style.onload = res;\n style.onerror = rej;\n });\n document.head.appendChild(style);\n await promise;\n return style;\n}\n"
Instance Attribute Summary collapse
-
#frame ⇒ Object
readonly
Returns the value of attribute frame.
Instance Method Summary collapse
- #add_binding_to_context(context, binding_function) ⇒ Object
- #add_script_tag(url: nil, path: nil, content: nil, id: nil, type: nil) ⇒ Object
- #add_style_tag(url: nil, path: nil, content: nil) ⇒ Object
- #click(selector, delay: nil, button: nil, click_count: nil) ⇒ Object
- #content ⇒ String
- #context=(context) ⇒ Object
- #delete_context(execution_context_id) ⇒ Object
- #detach ⇒ Object
-
#eval_on_selector(selector, page_function, *args) ⇒ !Promise<(!Object|undefined)>
(also: #Seval)
‘$eval()` in JavaScript.
-
#eval_on_selector_all(selector, page_function, *args) ⇒ !Promise<(!Object|undefined)>
(also: #SSeval)
‘$$eval()` in JavaScript.
- #evaluate(page_function, *args) ⇒ !Promise<*>
- #evaluate_handle(page_function, *args) ⇒ !Promise<!Puppeteer.JSHandle>
- #execution_context ⇒ !Promise<!Puppeteer.ExecutionContext>
- #focus(selector) ⇒ Object
- #has_context? ⇒ Boolean
-
#initialize(client, frame_manager, frame, timeout_settings) ⇒ DOMWorld
constructor
A new instance of DOMWorld.
-
#query_selector(selector) ⇒ !Promise<?Puppeteer.ElementHandle>
(also: #S)
‘$()` in JavaScript.
-
#query_selector_all(selector) ⇒ !Promise<!Array<!Puppeteer.ElementHandle>>
(also: #SS)
‘$$()` in JavaScript.
- #select(selector, *values) ⇒ Array<String>
- #set_content(html, timeout: nil, wait_until: nil) ⇒ Object
-
#Sx(expression) ⇒ !Promise<!Array<!Puppeteer.ElementHandle>>
‘$x()` in JavaScript.
- #tap(selector) ⇒ Object
- #title ⇒ String
- #type_text(selector, text, delay: nil) ⇒ Object
- #wait_for_function(page_function, args: [], polling: nil, timeout: nil) ⇒ Puppeteer::JSHandle
- #wait_for_selector(selector, visible: nil, hidden: nil, timeout: nil, root: nil) ⇒ Object
- #wait_for_xpath(xpath, visible: nil, hidden: nil, timeout: nil, root: nil) ⇒ Object
Constructor Details
#initialize(client, frame_manager, frame, timeout_settings) ⇒ DOMWorld
Returns a new instance of DOMWorld.
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/puppeteer/dom_world.rb', line 52 def initialize(client, frame_manager, frame, timeout_settings) # Keep own reference to client because it might differ from the FrameManager's # client for OOP iframes. @client = client @frame_manager = frame_manager @frame = frame @timeout_settings = timeout_settings @context_promise = resolvable_future @wait_tasks = Set.new @bound_functions = {} @ctx_bindings = Set.new @detached = false @client.on_event('Runtime.bindingCalled', &method(:handle_binding_called)) end |
Instance Attribute Details
#frame ⇒ Object (readonly)
Returns the value of attribute frame.
68 69 70 |
# File 'lib/puppeteer/dom_world.rb', line 68 def frame @frame end |
Instance Method Details
#add_binding_to_context(context, binding_function) ⇒ Object
434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 |
# File 'lib/puppeteer/dom_world.rb', line 434 def add_binding_to_context(context, binding_function) return if @ctx_bindings.include?(binding_identifier(binding_function.name, context)) expression = binding_function.page_binding_init_string begin context.client.('Runtime.addBinding', name: binding_function.name, executionContextName: context.send(:_context_name)) context.evaluate(expression, 'internal', binding_function.name) rescue => err # We could have tried to evaluate in a context which was already # destroyed. This happens, for example, if the page is navigated while # we are trying to add the binding allowed = [ 'Execution context was destroyed', 'Cannot find context with specified id', ] if allowed.any? { |msg| err..include?(msg) } # ignore else raise end end @ctx_bindings << binding_identifier(binding_function.name, context) end |
#add_script_tag(url: nil, path: nil, content: nil, id: nil, type: nil) ⇒ Object
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 |
# File 'lib/puppeteer/dom_world.rb', line 242 def add_script_tag(url: nil, path: nil, content: nil, id: nil, type: nil) if url begin return execution_context. evaluate_handle(ADD_SCRIPT_URL, url, id, type || ''). as_element rescue Puppeteer::ExecutionContext::EvaluationError # for Chrome raise "Loading script from #{url} failed" rescue Puppeteer::Connection::ProtocolError # for Firefox raise "Loading script from #{url} failed" end end if path contents = File.read(path) contents += "//# sourceURL=#{path.gsub(/\n/, '')}" return execution_context. evaluate_handle(ADD_SCRIPT_CONTENT, contents, id, type || 'text/javascript'). as_element end if content return execution_context. evaluate_handle(ADD_SCRIPT_CONTENT, content, id, type || 'text/javascript'). as_element end raise ArgumentError.new('Provide an object with a `url`, `path` or `content` property') end |
#add_style_tag(url: nil, path: nil, content: nil) ⇒ Object
306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 |
# File 'lib/puppeteer/dom_world.rb', line 306 def add_style_tag(url: nil, path: nil, content: nil) if url begin return execution_context.evaluate_handle(ADD_STYLE_URL, url).as_element rescue Puppeteer::ExecutionContext::EvaluationError # for Chrome raise "Loading style from #{url} failed" rescue Puppeteer::Connection::ProtocolError # for Firefox raise "Loading style from #{url} failed" end end if path contents = File.read(path) contents += "/*# sourceURL=#{path.gsub(/\n/, '')}*/" return execution_context.evaluate_handle(ADD_STYLE_CONTENT, contents).as_element end if content return execution_context.evaluate_handle(ADD_STYLE_CONTENT, content).as_element end raise ArgumentError.new('Provide an object with a `url`, `path` or `content` property') end |
#click(selector, delay: nil, button: nil, click_count: nil) ⇒ Object
370 371 372 373 374 |
# File 'lib/puppeteer/dom_world.rb', line 370 def click(selector, delay: nil, button: nil, click_count: nil) handle = query_selector(selector) or raise ElementNotFoundError.new(selector) handle.click(delay: delay, button: , click_count: click_count) handle.dispose end |
#content ⇒ String
195 196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/puppeteer/dom_world.rb', line 195 def content evaluate(" () => {\n let retVal = '';\n if (document.doctype)\n retVal = new XMLSerializer().serializeToString(document.doctype);\n if (document.documentElement)\n retVal += document.documentElement.outerHTML;\n return retVal;\n }\n JAVASCRIPT\nend\n") |
#context=(context) ⇒ Object
81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/puppeteer/dom_world.rb', line 81 def context=(context) if context @ctx_bindings.clear unless @context_promise.resolved? @context_promise.fulfill(context) end @wait_tasks.each(&:async_rerun) else raise ArgumentError.new("context should now be nil. Use #delete_context for clearing document.") end end |
#delete_context(execution_context_id) ⇒ Object
93 94 95 96 |
# File 'lib/puppeteer/dom_world.rb', line 93 def delete_context(execution_context_id) @document = nil @context_promise = resolvable_future end |
#detach ⇒ Object
102 103 104 105 106 107 |
# File 'lib/puppeteer/dom_world.rb', line 102 def detach @detached = true @wait_tasks.each do |wait_task| wait_task.terminate(Puppeteer::WaitTask::TerminatedError.new('waitForFunction failed: frame got detached.')) end end |
#eval_on_selector(selector, page_function, *args) ⇒ !Promise<(!Object|undefined)> Also known as: Seval
‘$eval()` in JavaScript.
171 172 173 |
# File 'lib/puppeteer/dom_world.rb', line 171 def eval_on_selector(selector, page_function, *args) document.eval_on_selector(selector, page_function, *args) end |
#eval_on_selector_all(selector, page_function, *args) ⇒ !Promise<(!Object|undefined)> Also known as: SSeval
‘$$eval()` in JavaScript.
181 182 183 |
# File 'lib/puppeteer/dom_world.rb', line 181 def eval_on_selector_all(selector, page_function, *args) document.eval_on_selector_all(selector, page_function, *args) end |
#evaluate(page_function, *args) ⇒ !Promise<*>
129 130 131 |
# File 'lib/puppeteer/dom_world.rb', line 129 def evaluate(page_function, *args) execution_context.evaluate(page_function, *args) end |
#evaluate_handle(page_function, *args) ⇒ !Promise<!Puppeteer.JSHandle>
122 123 124 |
# File 'lib/puppeteer/dom_world.rb', line 122 def evaluate_handle(page_function, *args) execution_context.evaluate_handle(page_function, *args) end |
#execution_context ⇒ !Promise<!Puppeteer.ExecutionContext>
112 113 114 115 116 117 |
# File 'lib/puppeteer/dom_world.rb', line 112 def execution_context if @detached raise DetachedError.new("Execution Context is not available in detached frame \"#{@frame.url}\" (are you trying to evaluate?)") end @context_promise.value! end |
#focus(selector) ⇒ Object
377 378 379 380 381 |
# File 'lib/puppeteer/dom_world.rb', line 377 def focus(selector) handle = query_selector(selector) or raise ElementNotFoundError.new(selector) handle.focus handle.dispose end |
#has_context? ⇒ Boolean
98 99 100 |
# File 'lib/puppeteer/dom_world.rb', line 98 def has_context? @context_promise.resolved? end |
#query_selector(selector) ⇒ !Promise<?Puppeteer.ElementHandle> Also known as: S
‘$()` in JavaScript.
136 137 138 |
# File 'lib/puppeteer/dom_world.rb', line 136 def query_selector(selector) document.query_selector(selector) end |
#query_selector_all(selector) ⇒ !Promise<!Array<!Puppeteer.ElementHandle>> Also known as: SS
‘$$()` in JavaScript.
189 190 191 |
# File 'lib/puppeteer/dom_world.rb', line 189 def query_selector_all(selector) document.query_selector_all(selector) end |
#select(selector, *values) ⇒ Array<String>
395 396 397 398 399 400 401 |
# File 'lib/puppeteer/dom_world.rb', line 395 def select(selector, *values) handle = query_selector(selector) or raise ElementNotFoundError.new(selector) result = handle.select(*values) handle.dispose result end |
#set_content(html, timeout: nil, wait_until: nil) ⇒ Object
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 |
# File 'lib/puppeteer/dom_world.rb', line 211 def set_content(html, timeout: nil, wait_until: nil) option_wait_until = [wait_until || 'load'].flatten option_timeout = timeout || @timeout_settings. # We rely upon the fact that document.open() will reset frame lifecycle with "init" # lifecycle event. @see https://crrev.com/608658 js = " (html) => {\n document.open();\n document.write(html);\n document.close();\n }\n JAVASCRIPT\n evaluate(js, html)\n\n watcher = Puppeteer::LifecycleWatcher.new(@frame_manager, @frame, option_wait_until, option_timeout)\n begin\n await_any(\n watcher.timeout_or_termination_promise,\n watcher.lifecycle_promise,\n )\n ensure\n watcher.dispose\n end\nend\n" |
#Sx(expression) ⇒ !Promise<!Array<!Puppeteer.ElementHandle>>
‘$x()` in JavaScript. $ is not allowed to use as a method name in Ruby.
162 163 164 |
# File 'lib/puppeteer/dom_world.rb', line 162 def Sx(expression) document.Sx(expression) end |
#tap(selector) ⇒ Object
404 405 406 407 408 |
# File 'lib/puppeteer/dom_world.rb', line 404 def tap(selector) handle = query_selector(selector) or raise ElementNotFoundError.new(selector) handle.tap handle.dispose end |
#title ⇒ String
606 607 608 |
# File 'lib/puppeteer/dom_world.rb', line 606 def title evaluate('() => document.title') end |
#type_text(selector, text, delay: nil) ⇒ Object
413 414 415 416 417 |
# File 'lib/puppeteer/dom_world.rb', line 413 def type_text(selector, text, delay: nil) handle = query_selector(selector) or raise ElementNotFoundError.new(selector) handle.type_text(text, delay: delay) handle.dispose end |
#wait_for_function(page_function, args: [], polling: nil, timeout: nil) ⇒ Puppeteer::JSHandle
590 591 592 593 594 595 596 597 598 599 600 601 602 |
# File 'lib/puppeteer/dom_world.rb', line 590 def wait_for_function(page_function, args: [], polling: nil, timeout: nil) option_polling = polling || 'raf' option_timeout = timeout || @timeout_settings.timeout Puppeteer::WaitTask.new( dom_world: self, predicate_body: page_function, title: 'function', polling: option_polling, timeout: option_timeout, args: args, ).await_promise end |
#wait_for_selector(selector, visible: nil, hidden: nil, timeout: nil, root: nil) ⇒ Object
423 424 425 426 427 |
# File 'lib/puppeteer/dom_world.rb', line 423 def wait_for_selector(selector, visible: nil, hidden: nil, timeout: nil, root: nil) # call wait_for_selector_in_page with custom query selector. query_selector_manager = Puppeteer::QueryHandlerManager.instance query_selector_manager.detect_query_handler(selector).wait_for(self, visible: visible, hidden: hidden, timeout: timeout, root: root) end |
#wait_for_xpath(xpath, visible: nil, hidden: nil, timeout: nil, root: nil) ⇒ Object
546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 |
# File 'lib/puppeteer/dom_world.rb', line 546 def wait_for_xpath(xpath, visible: nil, hidden: nil, timeout: nil, root: nil) option_wait_for_visible = visible || false option_wait_for_hidden = hidden || false option_timeout = timeout || @timeout_settings.timeout option_root = root polling = if option_wait_for_visible || option_wait_for_hidden 'raf' else 'mutation' end title = "XPath #{xpath}#{option_wait_for_hidden ? 'to be hidden' : ''}" xpath_predicate = make_predicate_string( predicate_arg_def: '(root, selector, waitForVisible, waitForHidden)', predicate_body: " const node = document.evaluate(selector, root, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;\n return checkWaitForOptions(node, waitForVisible, waitForHidden);\n JAVASCRIPT\n )\n\n wait_task = Puppeteer::WaitTask.new(\n dom_world: self,\n predicate_body: xpath_predicate,\n title: title,\n polling: polling,\n timeout: option_timeout,\n args: [xpath, option_wait_for_visible, option_wait_for_hidden],\n root: option_root,\n )\n handle = wait_task.await_promise\n unless handle.as_element\n handle.dispose\n return nil\n end\n handle.as_element\nend\n" |