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.
-
#task_manager ⇒ Object
readonly
Returns the value of attribute task_manager.
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 @task_manager = Puppeteer::TaskManager.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 |
#task_manager ⇒ Object (readonly)
Returns the value of attribute task_manager.
68 69 70 |
# File 'lib/puppeteer/isolated_world.rb', line 68 def task_manager @task_manager end |
Instance Method Details
#add_binding_to_context(context, binding_function) ⇒ Object
417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 |
# File 'lib/puppeteer/isolated_world.rb', line 417 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
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 |
# File 'lib/puppeteer/isolated_world.rb', line 235 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
299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 |
# File 'lib/puppeteer/isolated_world.rb', line 299 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
583 584 585 586 587 588 589 590 591 592 |
# File 'lib/puppeteer/isolated_world.rb', line 583 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
597 598 599 600 601 602 603 604 |
# File 'lib/puppeteer/isolated_world.rb', line 597 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
363 364 365 366 367 |
# File 'lib/puppeteer/isolated_world.rb', line 363 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
188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/puppeteer/isolated_world.rb', line 188 def content evaluate(<<-JAVASCRIPT) () => { let retVal = ''; if (document.doctype) retVal = new XMLSerializer().serializeToString(document.doctype); if (document.documentElement) retVal += document.documentElement.outerHTML; return retVal; } JAVASCRIPT end |
#context=(context) ⇒ Object
76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/puppeteer/isolated_world.rb', line 76 def context=(context) if context @ctx_bindings.clear unless @context_promise.resolved? @context_promise.fulfill(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(execution_context_id) ⇒ Object
88 89 90 91 |
# File 'lib/puppeteer/isolated_world.rb', line 88 def delete_context(execution_context_id) @document = nil @context_promise = resolvable_future end |
#detach ⇒ Object
97 98 99 100 |
# File 'lib/puppeteer/isolated_world.rb', line 97 def detach @detached = true @task_manager.terminate_all(Puppeteer::WaitTask::TerminatedError.new('waitForFunction failed: frame got detached.')) end |
#document ⇒ Object
148 149 150 |
# File 'lib/puppeteer/isolated_world.rb', line 148 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.
164 165 166 |
# File 'lib/puppeteer/isolated_world.rb', line 164 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.
174 175 176 |
# File 'lib/puppeteer/isolated_world.rb', line 174 def eval_on_selector_all(selector, page_function, *args) document.eval_on_selector_all(selector, page_function, *args) end |
#evaluate(page_function, *args) ⇒ !Promise<*>
122 123 124 |
# File 'lib/puppeteer/isolated_world.rb', line 122 def evaluate(page_function, *args) execution_context.evaluate(page_function, *args) end |
#evaluate_handle(page_function, *args) ⇒ !Promise<!Puppeteer.JSHandle>
115 116 117 |
# File 'lib/puppeteer/isolated_world.rb', line 115 def evaluate_handle(page_function, *args) execution_context.evaluate_handle(page_function, *args) end |
#execution_context ⇒ !Promise<!Puppeteer.ExecutionContext>
105 106 107 108 109 110 |
# File 'lib/puppeteer/isolated_world.rb', line 105 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
370 371 372 373 374 |
# File 'lib/puppeteer/isolated_world.rb', line 370 def focus(selector) handle = query_selector(selector) or raise ElementNotFoundError.new(selector) handle.focus handle.dispose end |
#has_context? ⇒ Boolean
93 94 95 |
# File 'lib/puppeteer/isolated_world.rb', line 93 def has_context? @context_promise.resolved? end |
#query_selector(selector) ⇒ !Promise<?Puppeteer.ElementHandle> Also known as: S
‘$()` in JavaScript.
129 130 131 |
# File 'lib/puppeteer/isolated_world.rb', line 129 def query_selector(selector) document.query_selector(selector) end |
#query_selector_all(selector) ⇒ !Promise<!Array<!Puppeteer.ElementHandle>> Also known as: SS
‘$$()` in JavaScript.
182 183 184 |
# File 'lib/puppeteer/isolated_world.rb', line 182 def query_selector_all(selector) document.query_selector_all(selector) end |
#select(selector, *values) ⇒ Array<String>
388 389 390 391 392 393 394 |
# File 'lib/puppeteer/isolated_world.rb', line 388 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
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 |
# File 'lib/puppeteer/isolated_world.rb', line 204 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 await_any( 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.
155 156 157 |
# File 'lib/puppeteer/isolated_world.rb', line 155 def Sx(expression) document.Sx(expression) end |
#tap(selector) ⇒ Object
397 398 399 400 401 |
# File 'lib/puppeteer/isolated_world.rb', line 397 def tap(selector) handle = query_selector(selector) or raise ElementNotFoundError.new(selector) handle.tap handle.dispose end |
#title ⇒ String
541 542 543 |
# File 'lib/puppeteer/isolated_world.rb', line 541 def title evaluate('() => document.title') end |
#transfer_handle(element_handle) ⇒ Object
606 607 608 609 610 |
# File 'lib/puppeteer/isolated_world.rb', line 606 def transfer_handle(element_handle) result = adopt_handle(element_handle) element_handle.dispose result end |
#type_text(selector, text, delay: nil) ⇒ Object
406 407 408 409 410 |
# File 'lib/puppeteer/isolated_world.rb', line 406 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
525 526 527 528 529 530 531 532 533 534 535 536 537 |
# File 'lib/puppeteer/isolated_world.rb', line 525 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 |