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 =
<<~JAVASCRIPT async (url, id, type) => { const script = document.createElement('script'); script.src = url; if (id) script.id = id; if (type) script.type = type; const promise = new Promise((res, rej) => { script.onload = res; script.onerror = rej; }); document.head.appendChild(script); await promise; return script; } JAVASCRIPT
- ADD_SCRIPT_CONTENT =
<<~JAVASCRIPT (content, id, type) => { const script = document.createElement('script'); script.type = type; script.text = content; if (id) script.id = id; let error = null; script.onerror = e => error = e; document.head.appendChild(script); if (error) throw error; return script; } JAVASCRIPT
- ADD_STYLE_URL =
<<~JAVASCRIPT async (url) => { const link = document.createElement('link'); link.rel = 'stylesheet'; link.href = url; const promise = new Promise((res, rej) => { link.onload = res; link.onerror = rej; }); document.head.appendChild(link); await promise; return link; } JAVASCRIPT
- ADD_STYLE_CONTENT =
<<~JAVASCRIPT async (content) => { const style = document.createElement('style'); style.type = 'text/css'; style.appendChild(document.createTextNode(content)); const promise = new Promise((res, rej) => { style.onload = res; style.onerror = rej; }); document.head.appendChild(style); await promise; return style; } JAVASCRIPT
Instance Attribute Summary collapse
-
#frame ⇒ Object
readonly
Returns the value of attribute frame.
-
#origin ⇒ Object
Returns the value of attribute origin.
-
#task_manager ⇒ Object
readonly
Returns the value of attribute task_manager.
-
#world_id ⇒ Object
Returns the value of attribute world_id.
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, count: nil) ⇒ Object
- #content ⇒ String
- #context=(context) ⇒ Object
- #delete_context(context_or_id) ⇒ Object
- #detach ⇒ Object
- #detached? ⇒ Boolean
- #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>
- #extension ⇒ Object
- #focus(selector) ⇒ Object
- #has_context? ⇒ Boolean
-
#hover(selector) ⇒ Object
/** * @param string selector */ async hover(selector) { const handle = await this.$(selector); assert(handle, ‘No node found for selector: ’ + selector); await handle.hover(); await handle.dispose(); }.
-
#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, isolate: nil) ⇒ !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 67 68 69 |
# 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 = Async::Promise.new @task_manager = Puppeteer::TaskManager.new @bound_functions = {} @ctx_bindings = Set.new @detached = false @context = nil @origin = nil @world_id = nil @client.on_event('Runtime.bindingCalled', &method(:handle_binding_called)) end |
Instance Attribute Details
#frame ⇒ Object (readonly)
Returns the value of attribute frame.
71 72 73 |
# File 'lib/puppeteer/isolated_world.rb', line 71 def frame @frame end |
#origin ⇒ Object
Returns the value of attribute origin.
71 72 73 |
# File 'lib/puppeteer/isolated_world.rb', line 71 def origin @origin end |
#task_manager ⇒ Object (readonly)
Returns the value of attribute task_manager.
71 72 73 |
# File 'lib/puppeteer/isolated_world.rb', line 71 def task_manager @task_manager end |
#world_id ⇒ Object
Returns the value of attribute world_id.
71 72 73 |
# File 'lib/puppeteer/isolated_world.rb', line 71 def world_id @world_id end |
Instance Method Details
#add_binding_to_context(context, binding_function) ⇒ Object
462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 |
# File 'lib/puppeteer/isolated_world.rb', line 462 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
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 |
# File 'lib/puppeteer/isolated_world.rb', line 278 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, Puppeteer::Connection::ProtocolError 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
340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 |
# File 'lib/puppeteer/isolated_world.rb', line 340 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, Puppeteer::Connection::ProtocolError 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
627 628 629 630 631 632 633 634 635 636 |
# File 'lib/puppeteer/isolated_world.rb', line 627 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
641 642 643 644 645 646 647 648 |
# File 'lib/puppeteer/isolated_world.rb', line 641 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, count: nil) ⇒ Object
403 404 405 406 407 |
# File 'lib/puppeteer/isolated_world.rb', line 403 def click(selector, delay: nil, button: nil, click_count: nil, count: nil) handle = query_selector(selector) or raise ElementNotFoundError.new(selector) handle.click(delay: delay, button: , click_count: click_count, count: count) handle.dispose end |
#content ⇒ String
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 |
# File 'lib/puppeteer/isolated_world.rb', line 225 def content evaluate(<<-JAVASCRIPT) () => { let content = ''; for (const node of document.childNodes) { switch (node) { case document.documentElement: content += document.documentElement.outerHTML; break; default: content += new XMLSerializer().serializeToString(node); break; } } return content; } JAVASCRIPT end |
#context=(context) ⇒ Object
79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/puppeteer/isolated_world.rb', line 79 def context=(context) if context @ctx_bindings.clear @context = context unless @context_promise.resolved? @context_promise.resolve(context) end @task_manager.async_rerun_all else raise ArgumentError.new("context should now be nil. Use #delete_context for clearing document.") end end |
#delete_context(context_or_id) ⇒ Object
92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/puppeteer/isolated_world.rb', line 92 def delete_context(context_or_id) @document = nil if context_or_id if context_or_id.is_a?(Puppeteer::ExecutionContext) return unless @context.equal?(context_or_id) elsif @context && @context.respond_to?(:_context_id, true) return unless @context.send(:_context_id).to_s == context_or_id.to_s end end @context = nil @context_promise = Async::Promise.new end |
#detach ⇒ Object
109 110 111 112 |
# File 'lib/puppeteer/isolated_world.rb', line 109 def detach @detached = true @task_manager.terminate_all(Puppeteer::WaitTask::TerminatedError.new('waitForFunction failed: frame got detached.')) end |
#detached? ⇒ Boolean
133 134 135 |
# File 'lib/puppeteer/isolated_world.rb', line 133 def detached? @detached end |
#document ⇒ Object
185 186 187 |
# File 'lib/puppeteer/isolated_world.rb', line 185 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.
201 202 203 |
# File 'lib/puppeteer/isolated_world.rb', line 201 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.
211 212 213 |
# File 'lib/puppeteer/isolated_world.rb', line 211 def eval_on_selector_all(selector, page_function, *args) document.eval_on_selector_all(selector, page_function, *args) end |
#evaluate(page_function, *args) ⇒ !Promise<*>
159 160 161 |
# File 'lib/puppeteer/isolated_world.rb', line 159 def evaluate(page_function, *args) execution_context.evaluate(page_function, *args) end |
#evaluate_handle(page_function, *args) ⇒ !Promise<!Puppeteer.JSHandle>
152 153 154 |
# File 'lib/puppeteer/isolated_world.rb', line 152 def evaluate_handle(page_function, *args) execution_context.evaluate_handle(page_function, *args) end |
#execution_context ⇒ !Promise<!Puppeteer.ExecutionContext>
140 141 142 143 144 145 146 147 |
# File 'lib/puppeteer/isolated_world.rb', line 140 def execution_context if @detached raise DetachedError.new("Execution Context is not available in detached frame \"#{@frame.url}\" (are you trying to evaluate?)") end return @context if @context @context = @context_promise.wait end |
#extension ⇒ Object
127 128 129 130 131 |
# File 'lib/puppeteer/isolated_world.rb', line 127 def extension return nil unless @world_id.is_a?(String) frame.page.browser.extensions[@world_id] end |
#focus(selector) ⇒ Object
410 411 412 413 414 |
# File 'lib/puppeteer/isolated_world.rb', line 410 def focus(selector) handle = query_selector(selector) or raise ElementNotFoundError.new(selector) handle.focus handle.dispose end |
#has_context? ⇒ Boolean
105 106 107 |
# File 'lib/puppeteer/isolated_world.rb', line 105 def has_context? @context_promise.resolved? end |
#hover(selector) ⇒ Object
/**
* @param {string} selector
*/
async hover(selector)
const handle = await this.$(selector);
assert(handle, 'No node found for selector: ' + selector);
await handle.hover();
await handle.dispose();
425 426 427 428 429 |
# File 'lib/puppeteer/isolated_world.rb', line 425 def hover(selector) handle = query_selector(selector) or raise ElementNotFoundError.new(selector) handle.hover handle.dispose end |
#query_selector(selector) ⇒ !Promise<?Puppeteer.ElementHandle> Also known as: S
‘$()` in JavaScript.
166 167 168 |
# File 'lib/puppeteer/isolated_world.rb', line 166 def query_selector(selector) document.query_selector(selector) end |
#query_selector_all(selector, isolate: nil) ⇒ !Promise<!Array<!Puppeteer.ElementHandle>> Also known as: SS
‘$$()` in JavaScript.
219 220 221 |
# File 'lib/puppeteer/isolated_world.rb', line 219 def query_selector_all(selector, isolate: nil) document.query_selector_all(selector, isolate: isolate) end |
#select(selector, *values) ⇒ Array<String>
433 434 435 436 437 438 439 |
# File 'lib/puppeteer/isolated_world.rb', line 433 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
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 |
# File 'lib/puppeteer/isolated_world.rb', line 247 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 = <<-JAVASCRIPT (html) => { document.open(); document.write(html); document.close(); } JAVASCRIPT evaluate(js, html) watcher = Puppeteer::LifecycleWatcher.new(@frame_manager, @frame, option_wait_until, option_timeout) begin Puppeteer::AsyncUtils.await_promise_race( watcher.timeout_or_termination_promise, watcher.lifecycle_promise, ) ensure watcher.dispose end end |
#Sx(expression) ⇒ !Promise<!Array<!Puppeteer.ElementHandle>>
‘$x()` in JavaScript. $ is not allowed to use as a method name in Ruby.
192 193 194 |
# File 'lib/puppeteer/isolated_world.rb', line 192 def Sx(expression) document.Sx(expression) end |
#tap(selector) ⇒ Object
442 443 444 445 446 |
# File 'lib/puppeteer/isolated_world.rb', line 442 def tap(selector) handle = query_selector(selector) or raise ElementNotFoundError.new(selector) handle.tap handle.dispose end |
#title ⇒ String
585 586 587 |
# File 'lib/puppeteer/isolated_world.rb', line 585 def title evaluate('() => document.title') end |
#transfer_handle(element_handle) ⇒ Object
650 651 652 653 654 |
# File 'lib/puppeteer/isolated_world.rb', line 650 def transfer_handle(element_handle) result = adopt_handle(element_handle) element_handle.dispose result end |
#type_text(selector, text, delay: nil) ⇒ Object
451 452 453 454 455 |
# File 'lib/puppeteer/isolated_world.rb', line 451 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
569 570 571 572 573 574 575 576 577 578 579 580 581 |
# File 'lib/puppeteer/isolated_world.rb', line 569 def wait_for_function(page_function, args: [], polling: nil, timeout: nil) option_polling = polling || 'raf' option_timeout = timeout.nil? ? @timeout_settings.timeout : timeout Puppeteer::WaitTask.new( dom_world: self, predicate_body: page_function, title: 'function', polling: option_polling, timeout: option_timeout, args: args, ).await_promise end |