Class: Puppeteer::IsolaatedWorld
- Inherits:
-
Object
- Object
- Puppeteer::IsolaatedWorld
- Defined in:
- lib/puppeteer/isolated_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
- #adopt_backend_node(backend_node_id) ⇒ Puppeteer::ElementHandle
- #adopt_handle(element_handle) ⇒ Puppeteer::ElementHandle
- #click(selector, delay: nil, button: nil, click_count: nil) ⇒ Object
- #content ⇒ String
- #context=(context) ⇒ Object
- #delete_context(execution_context_id) ⇒ Object
- #detach ⇒ Object
- #document ⇒ 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) ⇒ IsolaatedWorld
constructor
A new instance of IsolaatedWorld.
-
#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
- #transfer_handle(element_handle) ⇒ Object
- #type_text(selector, text, delay: nil) ⇒ Object
- #wait_for_function(page_function, args: [], polling: nil, timeout: nil) ⇒ Puppeteer::JSHandle
Constructor Details
#initialize(client, frame_manager, frame, timeout_settings) ⇒ IsolaatedWorld
Returns a new instance of IsolaatedWorld.
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/puppeteer/isolated_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/isolated_world.rb', line 68 def frame @frame end |
Instance Method Details
#add_binding_to_context(context, binding_function) ⇒ Object
424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 |
# File 'lib/puppeteer/isolated_world.rb', line 424 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/isolated_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/isolated_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 |
#adopt_backend_node(backend_node_id) ⇒ Puppeteer::ElementHandle
592 593 594 595 596 597 598 599 600 601 |
# File 'lib/puppeteer/isolated_world.rb', line 592 def adopt_backend_node(backend_node_id) response = @client.('DOM.resolveNode', backendNodeId: backend_node_id, executionContextId: execution_context.send(:_context_id), ) Puppeteer::JSHandle.create( context: execution_context, remote_object: Puppeteer::RemoteObject.new(response["object"]), ) end |
#adopt_handle(element_handle) ⇒ Puppeteer::ElementHandle
606 607 608 609 610 611 612 613 |
# File 'lib/puppeteer/isolated_world.rb', line 606 def adopt_handle(element_handle) if element_handle.execution_context == execution_context raise ArgumentError.new('Cannot adopt handle that already belongs to this execution context') end node_info = element_handle.remote_object.node_info(@client) adopt_backend_node(node_info["node"]["backendNodeId"]) end |
#click(selector, delay: nil, button: nil, click_count: nil) ⇒ Object
370 371 372 373 374 |
# File 'lib/puppeteer/isolated_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/isolated_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/isolated_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/isolated_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/isolated_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 |
#document ⇒ Object
155 156 157 |
# File 'lib/puppeteer/isolated_world.rb', line 155 def document @document ||= evaluate_document.as_element end |
#eval_on_selector(selector, page_function, *args) ⇒ !Promise<(!Object|undefined)> Also known as: Seval
‘$eval()` in JavaScript.
171 172 173 |
# File 'lib/puppeteer/isolated_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/isolated_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/isolated_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/isolated_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/isolated_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/isolated_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/isolated_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/isolated_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/isolated_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/isolated_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/isolated_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/isolated_world.rb', line 162 def Sx(expression) document.Sx(expression) end |
#tap(selector) ⇒ Object
404 405 406 407 408 |
# File 'lib/puppeteer/isolated_world.rb', line 404 def tap(selector) handle = query_selector(selector) or raise ElementNotFoundError.new(selector) handle.tap handle.dispose end |
#title ⇒ String
548 549 550 |
# File 'lib/puppeteer/isolated_world.rb', line 548 def title evaluate('() => document.title') end |
#transfer_handle(element_handle) ⇒ Object
615 616 617 618 619 |
# File 'lib/puppeteer/isolated_world.rb', line 615 def transfer_handle(element_handle) result = adopt_handle(element_handle) element_handle.dispose result end |
#type_text(selector, text, delay: nil) ⇒ Object
413 414 415 416 417 |
# File 'lib/puppeteer/isolated_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
532 533 534 535 536 537 538 539 540 541 542 543 544 |
# File 'lib/puppeteer/isolated_world.rb', line 532 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 |