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
-
#context ⇒ Object
Returns the value of attribute context.
-
#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, count: nil) ⇒ Object
- #content ⇒ String
- #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
#context ⇒ Object
Returns the value of attribute context.
71 72 73 |
# File 'lib/puppeteer/isolated_world.rb', line 71 def context @context end |
#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
468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 |
# File 'lib/puppeteer/isolated_world.rb', line 468 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
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 |
# File 'lib/puppeteer/isolated_world.rb', line 285 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
347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 |
# File 'lib/puppeteer/isolated_world.rb', line 347 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
633 634 635 636 637 638 639 640 641 642 |
# File 'lib/puppeteer/isolated_world.rb', line 633 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
647 648 649 650 651 652 653 654 |
# File 'lib/puppeteer/isolated_world.rb', line 647 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, count: nil) ⇒ Object
409 410 411 412 413 |
# File 'lib/puppeteer/isolated_world.rb', line 409 def click(selector, delay: nil, button: nil, count: nil) handle = query_selector(selector) or raise ElementNotFoundError.new(selector) handle.click(delay: delay, button: , 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 |
#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
416 417 418 419 420 |
# File 'lib/puppeteer/isolated_world.rb', line 416 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(); }
431 432 433 434 435 |
# File 'lib/puppeteer/isolated_world.rb', line 431 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>
439 440 441 442 443 444 445 |
# File 'lib/puppeteer/isolated_world.rb', line 439 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 272 273 274 275 276 277 278 |
# File 'lib/puppeteer/isolated_world.rb', line 247 def set_content(html, timeout: nil, wait_until: nil) option_wait_until = [wait_until || 'load'].flatten unsupported_events = option_wait_until & ['networkidle0', 'networkidle2'] unless unsupported_events.empty? raise ArgumentError.new( "set_content does not support #{unsupported_events.join(', ')}; " \ 'compose set_content with wait_for_network_idle instead.', ) end 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
448 449 450 451 452 |
# File 'lib/puppeteer/isolated_world.rb', line 448 def tap(selector) handle = query_selector(selector) or raise ElementNotFoundError.new(selector) handle.tap handle.dispose end |
#title ⇒ String
591 592 593 |
# File 'lib/puppeteer/isolated_world.rb', line 591 def title evaluate('() => document.title') end |
#transfer_handle(element_handle) ⇒ Object
656 657 658 659 660 |
# File 'lib/puppeteer/isolated_world.rb', line 656 def transfer_handle(element_handle) result = adopt_handle(element_handle) element_handle.dispose result end |
#type_text(selector, text, delay: nil) ⇒ Object
457 458 459 460 461 |
# File 'lib/puppeteer/isolated_world.rb', line 457 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
575 576 577 578 579 580 581 582 583 584 585 586 587 |
# File 'lib/puppeteer/isolated_world.rb', line 575 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 |