Class: Puppeteer::Page

Inherits:
Object
  • Object
show all
Includes:
EventCallbackable, IfPresent
Defined in:
lib/puppeteer/page.rb,
lib/puppeteer/page/screenshot_options.rb

Defined Under Namespace

Classes: FileChooserTimeoutError, ScreenshotOptions, ScriptTag, StyleTag, TargetCrashedError

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from IfPresent

#if_present

Methods included from EventCallbackable

#add_event_listener, #emit_event, #on_event, #remove_event_listener

Constructor Details

#initialize(client, target, ignore_https_errors, screenshot_task_queue) ⇒ Page



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/puppeteer/page.rb', line 29

def initialize(client, target, ignore_https_errors, screenshot_task_queue)
  @closed = false
  @client = client
  @target = target
  @keyboard = Puppeteer::Keyboard.new(client)
  @mouse = Puppeteer::Mouse.new(client, @keyboard)
  @timeout_settings = Puppeteer::TimeoutSettings.new
  @touchscreen = Puppeteer::TouchScreen.new(client, @keyboard)
  # @accessibility = Accessibility.new(client)
  @frame_manager = Puppeteer::FrameManager.new(client, self, ignore_https_errors, @timeout_settings)
  @emulation_manager = Puppeteer::EmulationManager.new(client)
  # @tracing = Tracing.new(client)
  @page_bindings = {}
  # @coverage = Coverage.new(client)
  @javascript_enabled = true
  @screenshot_task_queue = screenshot_task_queue

  @workers = {}
  @client.on_event 'Target.attachedToTarget' do |event|
    if event['targetInfo']['type'] != 'worker'
      # If we don't detach from service workers, they will never die.
      await @client.send_message('Target.detachFromTarget', sessionId: event['sessionId'])
      next
    end

    session = Puppeteer::Connection.from_session(@client).session(event['sessionId']) # rubocop:disable Lint/UselessAssignment
    #   const worker = new Worker(session, event.targetInfo.url, this._addConsoleMessage.bind(this), this._handleException.bind(this));
    #   this._workers.set(event.sessionId, worker);
    #   this.emit(Events.Page.WorkerCreated, worker);
  end
  @client.on_event 'Target.detachedFromTarget' do |event|
    session_id = event['sessionId']
    worker = @workers[session_id]
    next unless worker

    emit_event('Events.Page.WorkerDestroyed', worker)
    @workers.delete(session_id)
  end

  @frame_manager.on_event 'Events.FrameManager.FrameAttached' do |event|
    emit_event 'Events.Page.FrameAttached', event
  end
  @frame_manager.on_event 'Events.FrameManager.FrameDetached' do |event|
    emit_event 'Events.Page.FrameDetached', event
  end
  @frame_manager.on_event 'Events.FrameManager.FrameNavigated' do |event|
    emit_event 'Events.Page.FrameNavigated', event
  end

  network_manager = @frame_manager.network_manager
  network_manager.on_event 'Events.NetworkManager.Request' do |event|
    emit_event 'Events.Page.Request', event
  end
  network_manager.on_event 'Events.NetworkManager.Response' do |event|
    emit_event 'Events.Page.Response', event
  end
  network_manager.on_event 'Events.NetworkManager.RequestFailed' do |event|
    emit_event 'Events.Page.RequestFailed', event
  end
  network_manager.on_event 'Events.NetworkManager.RequestFinished' do |event|
    emit_event 'Events.Page.RequestFinished', event
  end
  @file_chooser_interception_is_disabled = false
  @file_chooser_interceptors = Set.new

  @client.on_event 'Page.domContentEventFired' do |event|
    emit_event 'Events.Page.DOMContentLoaded'
  end
  @client.on_event 'Page.loadEventFired' do |event|
    emit_event 'Events.Page.Load'
  end
  # client.on('Runtime.consoleAPICalled', event => this._onConsoleAPI(event));
  # client.on('Runtime.bindingCalled', event => this._onBindingCalled(event));
  # client.on('Page.javascriptDialogOpening', event => this._onDialog(event));
  # client.on('Runtime.exceptionThrown', exception => this._handleException(exception.exceptionDetails));
  # client.on('Inspector.targetCrashed', event => this._onTargetCrashed());
  # client.on('Performance.metrics', event => this._emitMetrics(event));
  @client.on_event 'Log.entryAdded' do |event|
    handle_log_entry_added(event)
  end
  @client.on_event 'Page.fileChooserOpened' do |event|
    handle_file_chooser(event)
  end
  @target.is_closed_promise.then do
    emit_event 'Events.Page.Close'
    @closed = true
  end
end

Instance Attribute Details

#accessibilityObject (readonly)

Returns the value of attribute accessibility.



233
234
235
# File 'lib/puppeteer/page.rb', line 233

def accessibility
  @accessibility
end

#coverageObject (readonly)

Returns the value of attribute coverage.



233
234
235
# File 'lib/puppeteer/page.rb', line 233

def coverage
  @coverage
end

#javascript_enabledObject

/**

* @param {!{longitude: number, latitude: number, accuracy: (number|undefined)}} options
*/

async setGeolocation(options)

const { longitude, latitude, accuracy = 0 = options;
if (longitude < -180 || longitude > 180)
  throw new Error(`Invalid longitude "$longitude": precondition -180 <= LONGITUDE <= 180 failed.`);
if (latitude < -90 || latitude > 90)
  throw new Error(`Invalid latitude "$latitude": precondition -90 <= LATITUDE <= 90 failed.`);
if (accuracy < 0)
  throw new Error(`Invalid accuracy "$accuracy": precondition 0 <= ACCURACY failed.`);
await this._client.send('Emulation.setGeolocationOverride', latitude, accuracy);

}



190
191
192
# File 'lib/puppeteer/page.rb', line 190

def javascript_enabled
  @javascript_enabled
end

#keyboardObject (readonly)

Returns the value of attribute keyboard.



233
234
235
# File 'lib/puppeteer/page.rb', line 233

def keyboard
  @keyboard
end

#mouseObject (readonly)

Returns the value of attribute mouse.



963
964
965
# File 'lib/puppeteer/page.rb', line 963

def mouse
  @mouse
end

#targetObject (readonly)

/**

* @param {!{longitude: number, latitude: number, accuracy: (number|undefined)}} options
*/

async setGeolocation(options)

const { longitude, latitude, accuracy = 0 = options;
if (longitude < -180 || longitude > 180)
  throw new Error(`Invalid longitude "$longitude": precondition -180 <= LONGITUDE <= 180 failed.`);
if (latitude < -90 || latitude > 90)
  throw new Error(`Invalid latitude "$latitude": precondition -90 <= LATITUDE <= 90 failed.`);
if (accuracy < 0)
  throw new Error(`Invalid accuracy "$accuracy": precondition 0 <= ACCURACY failed.`);
await this._client.send('Emulation.setGeolocationOverride', latitude, accuracy);

}



190
191
192
# File 'lib/puppeteer/page.rb', line 190

def target
  @target
end

#touch_screenObject (readonly)

Returns the value of attribute touch_screen.



233
234
235
# File 'lib/puppeteer/page.rb', line 233

def touch_screen
  @touch_screen
end

#viewportObject

Returns the value of attribute viewport.



786
787
788
# File 'lib/puppeteer/page.rb', line 786

def viewport
  @viewport
end

Class Method Details

.create(client, target, ignore_https_errors, default_viewport, screenshot_task_queue) ⇒ !Promise<!Page>



16
17
18
19
20
21
22
23
# File 'lib/puppeteer/page.rb', line 16

def self.create(client, target, ignore_https_errors, default_viewport, screenshot_task_queue)
  page = Puppeteer::Page.new(client, target, ignore_https_errors, screenshot_task_queue)
  page.init
  if default_viewport
    page.viewport = default_viewport
  end
  page
end

Instance Method Details

#add_script_tag(script_tag) ⇒ !Promise<!ElementHandle>



385
386
387
# File 'lib/puppeteer/page.rb', line 385

def add_script_tag(script_tag)
  main_frame.add_script_tag(script_tag)
end

#add_style_tag(style_tag) ⇒ !Promise<!ElementHandle>



401
402
403
# File 'lib/puppeteer/page.rb', line 401

def add_style_tag(style_tag)
  main_frame.add_style_tag(style_tag)
end

#async_clickFuture



978
979
980
# File 'lib/puppeteer/page.rb', line 978

async def async_click(selector, delay: nil, button: nil, click_count: nil)
  click(selector, delay: delay, button: button, click_count: click_count)
end

#async_SevalFuture

‘$eval()` in JavaScript. $ is not allowed to use as a method name in Ruby.



303
304
305
# File 'lib/puppeteer/page.rb', line 303

async def async_Seval(selector, page_function, *args)
  Seval(selector, page_function, *args)
end

#async_SSevalFuture

‘$$eval()` in JavaScript. $ is not allowed to use as a method name in Ruby.



319
320
321
# File 'lib/puppeteer/page.rb', line 319

async def async_SSeval(selector, page_function, *args)
  SSeval(selector, page_function, *args)
end

#async_wait_for_file_chooserFuture<Puppeteer::FileChooser>



171
172
173
# File 'lib/puppeteer/page.rb', line 171

async def async_wait_for_file_chooser(timeout: nil)
  wait_for_file_chooser(timeout: timeout)
end

#async_wait_for_navigationFuture



660
661
662
# File 'lib/puppeteer/page.rb', line 660

async def async_wait_for_navigation(timeout: nil, wait_until: nil)
  wait_for_navigation(timeout: timeout, wait_until: wait_until)
end

#authenticate(username: nil, password: nil) ⇒ Object



439
440
441
# File 'lib/puppeteer/page.rb', line 439

def authenticate(username: nil, password: nil)
  @frame_manager.network_manager.authenticate(username: username, password: password)
end

#browserObject



192
193
194
# File 'lib/puppeteer/page.rb', line 192

def browser
  @target.browser
end

#browser_contextObject



196
197
198
# File 'lib/puppeteer/page.rb', line 196

def browser_context
  @target.browser_context
end

#cache_enabled=(enabled) ⇒ Object



805
806
807
# File 'lib/puppeteer/page.rb', line 805

def cache_enabled=(enabled)
  @frame_manager.network_manager.cache_enabled = enabled
end

#click(selector, delay: nil, button: nil, click_count: nil) ⇒ Object



969
970
971
# File 'lib/puppeteer/page.rb', line 969

def click(selector, delay: nil, button: nil, click_count: nil)
  main_frame.click(selector, delay: delay, button: button, click_count: click_count)
end

#closeObject



947
948
949
950
951
952
953
954
955
956
# File 'lib/puppeteer/page.rb', line 947

def close
  # assert(!!this._client._connection, 'Protocol error: Connection closed. Most likely the page has been closed.');
  # const runBeforeUnload = !!options.runBeforeUnload;
  # if (runBeforeUnload) {
  #   await this._client.send('Page.close');
  # } else {
  #   await this._client._connection.send('Target.closeTarget', { targetId: this._target._targetId });
  #   await this._target._isClosedPromise;
  # }
end

#closed?boolean



959
960
961
# File 'lib/puppeteer/page.rb', line 959

def closed?
  @closed
end

#contentString



618
619
620
# File 'lib/puppeteer/page.rb', line 618

def content
  main_frame.content
end

#content=(html) ⇒ Object



629
630
631
# File 'lib/puppeteer/page.rb', line 629

def content=(html)
  main_frame.set_content(html)
end

#default_navigation_timeout=(timeout) ⇒ Object



253
254
255
# File 'lib/puppeteer/page.rb', line 253

def default_navigation_timeout=(timeout)
  @timeout_settings.default_navigation_timeout = timeout
end

#default_timeout=(timeout) ⇒ Object



258
259
260
# File 'lib/puppeteer/page.rb', line 258

def default_timeout=(timeout)
  @timeout_settings.default_timeout = timeout
end

#emulate(device) ⇒ Object



725
726
727
728
# File 'lib/puppeteer/page.rb', line 725

def emulate(device)
  self.viewport = device.viewport
  self.user_agent = device.user_agent
end

#emulate_timezone(timezone_id) ⇒ Object



769
770
771
772
773
774
775
776
777
# File 'lib/puppeteer/page.rb', line 769

def emulate_timezone(timezone_id)
  @client.send_message('Emulation.setTimezoneOverride', timezoneId: timezoneId || '')
rescue => err
  if err.message.include?('Invalid timezone')
    raise ArgumentError.new("Invalid timezone ID: #{timezone_id}")
  else
    raise err
  end
end

#evaluate(page_function, *args) ⇒ !Promise<*>



791
792
793
# File 'lib/puppeteer/page.rb', line 791

def evaluate(page_function, *args)
  main_frame.evaluate(page_function, *args)
end

#evaluate_handle(page_function, *args) ⇒ !Promise<!Puppeteer.JSHandle>



279
280
281
282
# File 'lib/puppeteer/page.rb', line 279

def evaluate_handle(page_function, *args)
  context = main_frame.execution_context
  context.evaluate_handle(page_function, *args)
end

#extra_http_headers=(headers) ⇒ Object



444
445
446
# File 'lib/puppeteer/page.rb', line 444

def extra_http_headers=(headers)
  @frame_manager.network_manager.extra_http_headers = headers
end

#focus(selector) ⇒ Object



983
984
985
# File 'lib/puppeteer/page.rb', line 983

def focus(selector)
  main_frame.focus(selector)
end

#framesObject



235
236
237
# File 'lib/puppeteer/page.rb', line 235

def frames
  @frame_manager.frames
end

#go_back(timeout: nil, wait_until: nil) ⇒ Object



702
703
704
# File 'lib/puppeteer/page.rb', line 702

def go_back(timeout: nil, wait_until: nil)
  go(-1, timeout: timeout, wait_until: wait_until)
end

#go_forward(timeout: nil, wait_until: nil) ⇒ Object



708
709
710
# File 'lib/puppeteer/page.rb', line 708

def go_forward(timeout: nil, wait_until: nil)
  go(+1, timeout: timeout, wait_until: wait_until)
end

#goto(url, referer: nil, timeout: nil, wait_until: nil) ⇒ Object



637
638
639
# File 'lib/puppeteer/page.rb', line 637

def goto(url, referer: nil, timeout: nil, wait_until: nil)
  main_frame.goto(url, referer: referer, timeout: timeout, wait_until: wait_until)
end

#handle_file_chooser(event) ⇒ Object



127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/puppeteer/page.rb', line 127

def handle_file_chooser(event)
  return if @file_chooser_interceptors.empty?

  frame = @frame_manager.frame(event['frameId'])
  context = frame.execution_context
  element = context.adopt_backend_node_id(event['backendNodeId'])
  interceptors = @file_chooser_interceptors.to_a
  @file_chooser_interceptors.clear
  file_chooser = Puppeteer::FileChooser.new(element, event)
  interceptors.each do |promise|
    promise.fulfill(file_chooser)
  end
end

#hover(selector) ⇒ Object



988
989
990
# File 'lib/puppeteer/page.rb', line 988

def hover(selector)
  main_frame.hover(selector)
end

#initObject



118
119
120
121
122
123
124
125
# File 'lib/puppeteer/page.rb', line 118

def init
  await_all(
    @frame_manager.async_init,
    @client.async_send_message('Target.setAutoAttach', autoAttach: true, waitForDebuggerOnStart: false, flatten: true),
    @client.async_send_message('Performance.enable'),
    @client.async_send_message('Log.enable'),
  )
end

#main_frameObject



229
230
231
# File 'lib/puppeteer/page.rb', line 229

def main_frame
  @frame_manager.main_frame
end

#offline_mode=(enabled) ⇒ Object



248
249
250
# File 'lib/puppeteer/page.rb', line 248

def offline_mode=(enabled)
  @frame_manager.network_manager.offline_mode = enabled
end

#query_objects(prototype_handle) ⇒ !Promise<!Puppeteer.JSHandle>



286
287
288
289
# File 'lib/puppeteer/page.rb', line 286

def query_objects(prototype_handle)
  context = main_frame.execution_context
  context.query_objects(prototype_handle)
end

#reload(timeout: nil, wait_until: nil) ⇒ Puppeteer::Response



644
645
646
647
648
649
# File 'lib/puppeteer/page.rb', line 644

def reload(timeout: nil, wait_until: nil)
  await_all(
    async_wait_for_navigation(timeout: timeout, wait_until: wait_until),
    @client.async_send_message('Page.reload'),
  ).first
end

#request_interception=(value) ⇒ Object



244
245
246
# File 'lib/puppeteer/page.rb', line 244

def request_interception=(value)
  @frame_manager.network_manager.request_interception = value
end

#S(selector) ⇒ !Promise<?Puppeteer.ElementHandle>

‘$()` in JavaScript. $ is not allowed to use as a method name in Ruby.



265
266
267
# File 'lib/puppeteer/page.rb', line 265

def S(selector)
  main_frame.S(selector)
end

#screenshot(options = {}) ⇒ Object

/**

* @param {!ScreenshotOptions=} options
* @return {!Promise<!Buffer|!String>}
*/


818
819
820
821
822
823
# File 'lib/puppeteer/page.rb', line 818

def screenshot(options = {})
  screenshot_options = ScreenshotOptions.new(options)

  # @screenshot_task_queue.post_task(-> { screenshot_task(screenshot_options.type, screenshot_options) })
  screenshot_task(screenshot_options.type, screenshot_options)
end

#select(selector, *values) ⇒ !Promise<!Array<string>>



995
996
997
# File 'lib/puppeteer/page.rb', line 995

def select(selector, *values)
  main_frame.select(selector, *values)
end

#set_content(html, timeout: nil, wait_until: nil) ⇒ Object



624
625
626
# File 'lib/puppeteer/page.rb', line 624

def set_content(html, timeout: nil, wait_until: nil)
  main_frame.set_content(html, timeout: timeout, wait_until: wait_until)
end

#Seval(selector, page_function, *args) ⇒ Object

‘$eval()` in JavaScript. $ is not allowed to use as a method name in Ruby.



295
296
297
# File 'lib/puppeteer/page.rb', line 295

def Seval(selector, page_function, *args)
  main_frame.Seval(selector, page_function, *args)
end

#SS(selector) ⇒ !Promise<!Array<!Puppeteer.ElementHandle>>

‘$$()` in JavaScript. $ is not allowed to use as a method name in Ruby.



272
273
274
# File 'lib/puppeteer/page.rb', line 272

def SS(selector)
  main_frame.SS(selector)
end

#SSeval(selector, page_function, *args) ⇒ Object

‘$$eval()` in JavaScript. $ is not allowed to use as a method name in Ruby.



311
312
313
# File 'lib/puppeteer/page.rb', line 311

def SSeval(selector, page_function, *args)
  main_frame.SSeval(selector, page_function, *args)
end

#Sx(expression) ⇒ !Promise<!Array<!Puppeteer.ElementHandle>>

‘$x()` in JavaScript. $ is not allowed to use as a method name in Ruby.



326
327
328
# File 'lib/puppeteer/page.rb', line 326

def Sx(expression)
  main_frame.Sx(expression)
end

#tap(selector) ⇒ Object



1000
1001
1002
# File 'lib/puppeteer/page.rb', line 1000

def tap(selector)
  main_frame.tap(selector)
end

#title!Promise<string>



810
811
812
# File 'lib/puppeteer/page.rb', line 810

def title
  @title
end

#type_text(selector, text, delay: nil) ⇒ Object



1012
1013
1014
# File 'lib/puppeteer/page.rb', line 1012

def type_text(selector, text, delay: nil)
  main_frame.type_text(selector, text, delay: delay)
end

#urlString



613
614
615
# File 'lib/puppeteer/page.rb', line 613

def url
  main_frame.url
end

#user_agent=(user_agent) ⇒ Object



449
450
451
# File 'lib/puppeteer/page.rb', line 449

def user_agent=(user_agent)
  @frame_manager.network_manager.user_agent = user_agent
end

#wait_for_file_chooser(timeout: nil) ⇒ Puppeteer::FileChooser



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/puppeteer/page.rb', line 149

def wait_for_file_chooser(timeout: nil)
  if @file_chooser_interceptors.empty?
    @client.send_message('Page.setInterceptFileChooserDialog', enabled: true)
  end

  option_timeout = timeout || @timeout_settings.timeout
  promise = resolvable_future
  @file_chooser_interceptors << promise

  begin
    Timeout.timeout(option_timeout / 1000.0) do
      promise.value!
    end
  rescue Timeout::Error
    raise FileChooserTimeoutError.new(timeout: option_timeout)
  ensure
    @file_chooser_interceptors.delete(promise)
  end
end

#wait_for_function(page_function, options = {}, *args) ⇒ !Promise<!Puppeteer.JSHandle>



1062
1063
1064
# File 'lib/puppeteer/page.rb', line 1062

def wait_for_function(page_function, options = {}, *args)
  main_frame.wait_for_function(page_function, options, *args)
end

#wait_for_selector(selector, visible: nil, hidden: nil, timeout: nil) ⇒ Object



1030
1031
1032
# File 'lib/puppeteer/page.rb', line 1030

def wait_for_selector(selector, visible: nil, hidden: nil, timeout: nil)
  main_frame.wait_for_selector(selector, visible: visible, hidden: hidden, timeout: timeout)
end

#wait_for_xpath(xpath, visible: nil, hidden: nil, timeout: nil) ⇒ Object



1046
1047
1048
# File 'lib/puppeteer/page.rb', line 1046

def wait_for_xpath(xpath, visible: nil, hidden: nil, timeout: nil)
  main_frame.wait_for_xpath(xpath, visible: visible, hidden: hidden, timeout: timeout)
end

#workersObject



239
240
241
# File 'lib/puppeteer/page.rb', line 239

def workers
  @workers.values
end