Class: Puppeteer::Page

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

Defined Under Namespace

Classes: FileChooserTimeoutError, JavaScriptExpression, JavaScriptFunction, Metrics, MetricsEvent, PDFOptions, PageError, PrintToPdfIsNotImplementedError, ScreenshotOptions, ScreenshotTaskQueue, TargetCrashedError

Constant Summary collapse

VISION_DEFICIENCY_TYPES =
%w[
  none
  achromatopsia
  blurredVision
  deuteranopia
  protanopia
  tritanopia
].freeze

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, #observe_first, #on_event, #remove_event_listener

Methods included from DebugPrint

#debug_print, #debug_puts

Constructor Details

#initialize(client, target, ignore_https_errors) ⇒ Page

Returns a new instance of Page.

Parameters:



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
117
118
119
120
121
122
# File 'lib/puppeteer/page.rb', line 33

def initialize(client, target, ignore_https_errors)
  @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 = Puppeteer::Tracing.new(client)
  @page_bindings = {}
  @coverage = Puppeteer::Coverage.new(client)
  @javascript_enabled = true
  @screenshot_task_queue = ScreenshotTaskQueue.new

  @workers = {}
  @user_drag_interception_enabled = false

  @target.target_manager.add_target_interceptor(@client, method(:handle_attached_to_target))
  @target_gone_listener_id = @target.target_manager.add_event_listener(
    TargetManagerEmittedEvents::TargetGone,
    &method(:handle_detached_from_target)
  )

  @frame_manager.on_event(FrameManagerEmittedEvents::FrameAttached) do |event|
    emit_event(PageEmittedEvents::FrameAttached, event)
  end
  @frame_manager.on_event(FrameManagerEmittedEvents::FrameDetached) do |event|
    emit_event(PageEmittedEvents::FrameDetached, event)
  end
  @frame_manager.on_event(FrameManagerEmittedEvents::FrameNavigated) do |event|
    emit_event(PageEmittedEvents::FrameNavigated, event)
  end

  network_manager = @frame_manager.network_manager
  network_manager.on_event(NetworkManagerEmittedEvents::Request) do |event|
    emit_event(PageEmittedEvents::Request, event)
  end
  network_manager.on_event(NetworkManagerEmittedEvents::Response) do |event|
    emit_event(PageEmittedEvents::Response, event)
  end
  network_manager.on_event(NetworkManagerEmittedEvents::RequestFailed) do |event|
    emit_event(PageEmittedEvents::RequestFailed, event)
  end
  network_manager.on_event(NetworkManagerEmittedEvents::RequestFinished) do |event|
    emit_event(PageEmittedEvents::RequestFinished, event)
  end
  @file_chooser_interception_is_disabled = false
  @file_chooser_interceptors = Set.new

  @client.on_event('Page.domContentEventFired') do |event|
    emit_event(PageEmittedEvents::DOMContentLoaded)
  end
  @client.on_event('Page.loadEventFired') do |event|
    emit_event(PageEmittedEvents::Load)
  end
  @client.add_event_listener('Runtime.consoleAPICalled') do |event|
    handle_console_api(event)
  end
  @client.add_event_listener('Runtime.bindingCalled') do |event|
    handle_binding_called(event)
  end
  @client.on_event('Page.javascriptDialogOpening') do |event|
    handle_dialog_opening(event)
  end
  @client.on_event('Runtime.exceptionThrown') do |exception|
    handle_exception(exception['exceptionDetails'])
  end
  @client.on_event('Inspector.targetCrashed') do |event|
    handle_target_crashed
  end
  @client.on_event('Performance.metrics') do |event|
    emit_event(PageEmittedEvents::Metrics, MetricsEvent.new(event))
  end
  @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
    @target.target_manager.remove_target_interceptor(@client, method(:handle_attached_to_target))
    @target.target_manager.remove_event_listener(@target_gone_listener_id)

    emit_event(PageEmittedEvents::Close)
    @closed = true
  end
end

Instance Attribute Details

#accessibilityObject (readonly)

Returns the value of attribute accessibility.



282
283
284
# File 'lib/puppeteer/page.rb', line 282

def accessibility
  @accessibility
end

#clientObject (readonly)

Returns the value of attribute client.



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

def client
  @client
end

#coverageObject (readonly)

Returns the value of attribute coverage.



282
283
284
# File 'lib/puppeteer/page.rb', line 282

def coverage
  @coverage
end

#javascript_enabledObject Also known as: javascript_enabled?

Returns the value of attribute javascript_enabled.



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

def javascript_enabled
  @javascript_enabled
end

#mouseObject (readonly)

Returns the value of attribute mouse.



1214
1215
1216
# File 'lib/puppeteer/page.rb', line 1214

def mouse
  @mouse
end

#targetObject (readonly)

Returns the value of attribute target.



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

def target
  @target
end

#touch_screenObject (readonly)

Returns the value of attribute touch_screen.



282
283
284
# File 'lib/puppeteer/page.rb', line 282

def touch_screen
  @touch_screen
end

#tracingObject (readonly)

Returns the value of attribute tracing.



282
283
284
# File 'lib/puppeteer/page.rb', line 282

def tracing
  @tracing
end

#viewportObject

Returns the value of attribute viewport.



972
973
974
# File 'lib/puppeteer/page.rb', line 972

def viewport
  @viewport
end

Class Method Details

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

Parameters:

Returns:



21
22
23
24
25
26
27
28
# File 'lib/puppeteer/page.rb', line 21

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

Instance Method Details

#add_script_tag(url: nil, path: nil, content: nil, type: nil, id: nil) ⇒ Object

Parameters:

  • url (String?) (defaults to: nil)
  • path (String?) (defaults to: nil)
  • content (String?) (defaults to: nil)
  • type (String?) (defaults to: nil)
  • id (String?) (defaults to: nil)


442
443
444
# File 'lib/puppeteer/page.rb', line 442

def add_script_tag(url: nil, path: nil, content: nil, type: nil, id: nil)
  main_frame.add_script_tag(url: url, path: path, content: content, type: type, id: id)
end

#add_style_tag(url: nil, path: nil, content: nil) ⇒ Object

Parameters:

  • url (String?) (defaults to: nil)
  • path (String?) (defaults to: nil)
  • content (String?) (defaults to: nil)


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

def add_style_tag(url: nil, path: nil, content: nil)
  main_frame.add_style_tag(url: url, path: path, content: content)
end

#async_wait_for_frame(url: nil, predicate: nil, timeout: nil) ⇒ Object

Parameters:

  • url (String) (defaults to: nil)
  • predicate (Proc(Puppeteer::Frame -> Boolean) (defaults to: nil)

    ]



841
# File 'lib/puppeteer/page.rb', line 841

define_async_method :async_wait_for_frame

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

Parameters:

  • timeout (number|nil) (defaults to: nil)
  • wait_until (string|nil) (defaults to: nil)

    ‘load’ | ‘domcontentloaded’ | ‘networkidle0’ | ‘networkidle2’



691
# File 'lib/puppeteer/page.rb', line 691

define_async_method :async_wait_for_navigation

#async_wait_for_request(url: nil, predicate: nil, timeout: nil) ⇒ Object

Waits until request URL matches or request matches the given predicate.

Waits until request URL matches

wait_for_request(url: 'https://example.com/awesome')

Waits until request matches the given predicate

wait_for_request(predicate: -> (req){ req.url.start_with?('https://example.com/search') })

Parameters:



783
# File 'lib/puppeteer/page.rb', line 783

define_async_method :async_wait_for_request

#async_wait_for_response(url: nil, predicate: nil, timeout: nil) ⇒ Object

Parameters:



809
# File 'lib/puppeteer/page.rb', line 809

define_async_method :async_wait_for_response

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

Parameters:

  • username (String?) (defaults to: nil)
  • password (String?) (defaults to: nil)


501
502
503
# File 'lib/puppeteer/page.rb', line 501

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

#bring_to_frontObject

Brings page to front (activates tab).



867
868
869
# File 'lib/puppeteer/page.rb', line 867

def bring_to_front
  @client.send_message('Page.bringToFront')
end

#browserObject



241
242
243
# File 'lib/puppeteer/page.rb', line 241

def browser
  @target.browser
end

#browser_contextObject



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

def browser_context
  @target.browser_context
end

#bypass_csp=(enabled) ⇒ Object

Parameters:

  • enabled (Boolean)


885
886
887
# File 'lib/puppeteer/page.rb', line 885

def bypass_csp=(enabled)
  @client.send_message('Page.setBypassCSP', enabled: enabled)
end

#cache_enabled=(enabled) ⇒ Object

Parameters:

  • enabled (boolean)


1020
1021
1022
# File 'lib/puppeteer/page.rb', line 1020

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

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

Parameters:

  • selector (String)
  • delay (Number) (defaults to: nil)
  • button (String) (defaults to: nil)

    “left”|“right”|“middle”

  • click_count (Number) (defaults to: nil)


1220
1221
1222
# File 'lib/puppeteer/page.rb', line 1220

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

#close(run_before_unload: false) ⇒ Object

Parameters:

  • run_before_unload (Boolean) (defaults to: false)


1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
# File 'lib/puppeteer/page.rb', line 1190

def close(run_before_unload: false)
  unless @client.connection
    raise 'Protocol error: Connection closed. Most likely the page has been closed.'
  end

  if run_before_unload
    @client.send_message('Page.close')
  else
    @client.connection.send_message('Target.closeTarget', targetId: @target.target_id)
    await @target.is_closed_promise

    # @closed sometimes remains false, so wait for @closed = true with 100ms timeout.
    25.times do
      break if @closed
      sleep 0.004
    end
  end
end

#closed?boolean

Returns:

  • (boolean)


1210
1211
1212
# File 'lib/puppeteer/page.rb', line 1210

def closed?
  @closed
end

#contentString

Returns:

  • (String)


650
651
652
# File 'lib/puppeteer/page.rb', line 650

def content
  main_frame.content
end

#content=(html) ⇒ Object

Parameters:

  • html (String)


662
663
664
# File 'lib/puppeteer/page.rb', line 662

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

#cookies(*urls) ⇒ Array<Hash>

Returns:

  • (Array<Hash>)


396
397
398
# File 'lib/puppeteer/page.rb', line 396

def cookies(*urls)
  @client.send_message('Network.getCookies', urls: (urls.empty? ? [url] : urls))['cookies']
end

#create_pdf_stream(options = {}) ⇒ Enumerable<String>

Returns:

  • (Enumerable<String>)


1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
# File 'lib/puppeteer/page.rb', line 1139

def create_pdf_stream(options = {})
  timeout_helper = Puppeteer::TimeoutHelper.new('Page.printToPDF',
                    timeout_ms: options[:timeout],
                    default_timeout_ms: 30000)
  pdf_options = PDFOptions.new(options)
  omit_background = options[:omit_background]
  set_transparent_background_color if omit_background
  result =
    begin
      timeout_helper.with_timeout do
        @client.send_message('Page.printToPDF', pdf_options.page_print_args)
      end
    ensure
      reset_default_background_color if omit_background
    end

  Puppeteer::ProtocolStreamReader.new(
    client: @client,
    handle: result['stream'],
  ).read_as_chunks
end

#default_navigation_timeout=(timeout) ⇒ Object

Parameters:

  • timeout (number)


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

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

#default_timeout=(timeout) ⇒ Object

Parameters:

  • timeout (number)


323
324
325
# File 'lib/puppeteer/page.rb', line 323

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


409
410
411
412
413
414
415
416
417
418
# File 'lib/puppeteer/page.rb', line 409

def delete_cookie(*cookies)
  assert_cookie_params(cookies, requires: %i(name))

  page_url = url
  starts_with_http = page_url.start_with?("http")
  cookies.each do |cookie|
    item = (starts_with_http ? { url: page_url } : {}).merge(cookie)
    @client.send_message("Network.deleteCookies", item)
  end
end

#drag_interception_enabled=(enabled) ⇒ Object



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

def drag_interception_enabled=(enabled)
  @user_drag_interception_enabled = enabled
  @client.send_message('Input.setInterceptDrags', enabled: enabled)
end

#drag_interception_enabled?Boolean Also known as: drag_interception_enabled

Returns:

  • (Boolean)


161
162
163
# File 'lib/puppeteer/page.rb', line 161

def drag_interception_enabled?
  @user_drag_interception_enabled
end

#emulate(device) ⇒ Object

Parameters:



872
873
874
875
# File 'lib/puppeteer/page.rb', line 872

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

#emulate_cpu_throttling(factor) ⇒ Object

Parameters:

  • factor (Number|nil)

    Factor at which the CPU will be throttled (2x, 2.5x. 3x, …). Passing ‘nil` disables cpu throttling.



899
900
901
902
903
904
905
# File 'lib/puppeteer/page.rb', line 899

def emulate_cpu_throttling(factor)
  if factor.nil? || factor >= 1
    @client.send_message('Emulation.setCPUThrottlingRate', rate: factor || 1)
  else
    raise ArgumentError.new('Throttling rate should be greater or equal to 1')
  end
end

#emulate_idle_state(is_user_active: nil, is_screen_unlocked: nil) ⇒ Object

Parameters:

  • is_user_active (Boolean) (defaults to: nil)
  • is_screen_unlocked (Boolean) (defaults to: nil)


952
953
954
955
956
957
958
959
960
961
962
963
# File 'lib/puppeteer/page.rb', line 952

def emulate_idle_state(is_user_active: nil, is_screen_unlocked: nil)
  overrides = {
    isUserActive: is_user_active,
    isScreenUnlocked: is_screen_unlocked,
  }.compact

  if overrides.empty?
    @client.send_message('Emulation.clearIdleOverride')
  else
    @client.send_message('Emulation.setIdleOverride', overrides)
  end
end

#emulate_media_features(features) ⇒ Object

Parameters:

  • features (Array)


908
909
910
911
912
913
914
915
916
917
918
919
920
# File 'lib/puppeteer/page.rb', line 908

def emulate_media_features(features)
  if features.nil?
    @client.send_message('Emulation.setEmulatedMedia', features: nil)
  elsif features.is_a?(Array)
    features.each do |media_feature|
      name = media_feature[:name]
      unless /^(?:prefers-(?:color-scheme|reduced-motion)|color-gamut)$/.match?(name)
        raise ArgumentError.new("Unsupported media feature: #{name}")
      end
    end
    @client.send_message('Emulation.setEmulatedMedia', features: features)
  end
end

#emulate_media_type(media_type) ⇒ Object

Parameters:

  • media_type (String|Symbol|nil)

    either of (media, print, nil)



890
891
892
893
894
895
896
# File 'lib/puppeteer/page.rb', line 890

def emulate_media_type(media_type)
  media_type_str = media_type.to_s
  unless ['screen', 'print', ''].include?(media_type_str)
    raise ArgumentError.new("Unsupported media type: #{media_type}")
  end
  @client.send_message('Emulation.setEmulatedMedia', media: media_type_str)
end

#emulate_network_conditions(network_condition) ⇒ Object

Parameters:



313
314
315
# File 'lib/puppeteer/page.rb', line 313

def emulate_network_conditions(network_condition)
  @frame_manager.network_manager.emulate_network_conditions(network_condition)
end

#emulate_timezone(timezone_id) ⇒ Object

Parameters:

  • timezone_id (String?)


923
924
925
926
927
928
929
930
931
# File 'lib/puppeteer/page.rb', line 923

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

#emulate_vision_deficiency(vision_deficiency_type) ⇒ Object



942
943
944
945
946
947
948
# File 'lib/puppeteer/page.rb', line 942

def emulate_vision_deficiency(vision_deficiency_type)
  value = vision_deficiency_type || 'none'
  unless VISION_DEFICIENCY_TYPES.include?(value)
    raise ArgumentError.new("Unsupported vision deficiency: #{vision_deficiency_type}")
  end
  @client.send_message('Emulation.setEmulatedVisionDeficiency', type: value)
end

#eval_on_selector(selector, page_function, *args) ⇒ Object Also known as: Seval

‘$eval()` in JavaScript.

Parameters:

  • selector (String)
  • page_function (String)

Returns:

  • (Object)


368
369
370
# File 'lib/puppeteer/page.rb', line 368

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

#eval_on_selector_all(selector, page_function, *args) ⇒ Object Also known as: SSeval

‘$$eval()` in JavaScript.

Parameters:

  • selector (String)
  • page_function (String)

Returns:

  • (Object)


379
380
381
# File 'lib/puppeteer/page.rb', line 379

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

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

Parameters:

  • pageFunction (Function|string)
  • args (!Array<*>)

Returns:

  • (!Promise<*>)


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

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

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

Parameters:

  • pageFunction (Function|string)
  • args (!Array<*>)

Returns:



350
351
352
353
# File 'lib/puppeteer/page.rb', line 350

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

#evaluate_on_new_document(page_function, *args) ⇒ Object



1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
# File 'lib/puppeteer/page.rb', line 1008

def evaluate_on_new_document(page_function, *args)
  source =
    if ['=>', 'async', 'function'].any? { |keyword| page_function.include?(keyword) }
      JavaScriptFunction.new(page_function, args).source
    else
      JavaScriptExpression.new(page_function).source
    end

  @client.send_message('Page.addScriptToEvaluateOnNewDocument', source: source)
end

#expose_function(name, puppeteer_function) ⇒ Object

Parameters:

  • name (String)
  • puppeteer_function (Proc)


455
456
457
458
459
460
461
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
487
488
489
490
491
492
493
494
495
496
497
# File 'lib/puppeteer/page.rb', line 455

def expose_function(name, puppeteer_function)
  if @page_bindings[name]
    raise ArgumentError.new("Failed to add page binding with name `#{name}` already exists!")
  end
  @page_bindings[name] = puppeteer_function

  add_page_binding = <<~JAVASCRIPT
  function (type, bindingName) {
    /* Cast window to any here as we're about to add properties to it
    * via win[bindingName] which TypeScript doesn't like.
    */
    const win = window;
    const binding = win[bindingName];

    win[bindingName] = (...args) => {
      const me = window[bindingName];
      let callbacks = me.callbacks;
      if (!callbacks) {
        callbacks = new Map();
        me.callbacks = callbacks;
      }
      const seq = (me.lastSeq || 0) + 1;
      me.lastSeq = seq;
      const promise = new Promise((resolve, reject) =>
        callbacks.set(seq, { resolve, reject })
      );
      binding(JSON.stringify({ type, name: bindingName, seq, args }));
      return promise;
    };
  }
  JAVASCRIPT

  source = JavaScriptFunction.new(add_page_binding, ['exposedFun', name]).source
  @client.send_message('Runtime.addBinding', name: name)
  @client.send_message('Page.addScriptToEvaluateOnNewDocument', source: source)

  promises = @frame_manager.frames.map do |frame|
    frame.async_evaluate("() => #{source}")
  end
  await_all(*promises)

  nil
end

#extra_http_headers=(headers) ⇒ Object

Parameters:

  • headers (Hash)


506
507
508
# File 'lib/puppeteer/page.rb', line 506

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

#focus(selector) ⇒ Object

Parameters:

  • selector (string)


1227
1228
1229
# File 'lib/puppeteer/page.rb', line 1227

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

#framesObject



290
291
292
# File 'lib/puppeteer/page.rb', line 290

def frames
  @frame_manager.frames
end

#geolocation=(geolocation) ⇒ Object

Parameters:



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

def geolocation=(geolocation)
  @client.send_message('Emulation.setGeolocationOverride', geolocation.to_h)
end

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

Parameters:

  • timeout (number|nil) (defaults to: nil)
  • wait_until (string|nil) (defaults to: nil)

    ‘load’ | ‘domcontentloaded’ | ‘networkidle0’ | ‘networkidle2’



845
846
847
# File 'lib/puppeteer/page.rb', line 845

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

Parameters:

  • timeout (number|nil) (defaults to: nil)
  • wait_until (string|nil) (defaults to: nil)

    ‘load’ | ‘domcontentloaded’ | ‘networkidle0’ | ‘networkidle2’



851
852
853
# File 'lib/puppeteer/page.rb', line 851

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

Parameters:

  • url (String)
  • rederer (String)
  • timeout (number|nil) (defaults to: nil)
  • wait_until (string|nil) (defaults to: nil)

    ‘load’ | ‘domcontentloaded’ | ‘networkidle0’ | ‘networkidle2’



670
671
672
# File 'lib/puppeteer/page.rb', line 670

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

#handle_binding_called(event) ⇒ Object



557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
# File 'lib/puppeteer/page.rb', line 557

def handle_binding_called(event)
  execution_context_id = event['executionContextId']
  payload =
    begin
      JSON.parse(event['payload'])
    rescue
      # The binding was either called by something in the page or it was
      # called before our wrapper was initialized.
      return
    end
  name = payload['name']
  seq = payload['seq']
  args = payload['args']

  if payload['type'] != 'exposedFun' || !@page_bindings[name]
    return
  end

  expression =
    begin
      result = @page_bindings[name].call(*args)

      deliver_result = <<~JAVASCRIPT
      function (name, seq, result) {
        window[name].callbacks.get(seq).resolve(result);
        window[name].callbacks.delete(seq);
      }
      JAVASCRIPT

      JavaScriptFunction.new(deliver_result, [name, seq, result]).source
    rescue => err
      deliver_error = <<~JAVASCRIPT
      function (name, seq, message) {
        const error = new Error(message);
        window[name].callbacks.get(seq).reject(error);
        window[name].callbacks.delete(seq);
      }
      JAVASCRIPT
      JavaScriptFunction.new(deliver_error, [name, seq, err.message]).source
    end

  @client.async_send_message('Runtime.evaluate', expression: expression, contextId: execution_context_id).rescue do |error|
    debug_puts(error)
  end
end

#handle_file_chooser(event) ⇒ Object



190
191
192
193
194
195
196
197
198
199
200
201
# File 'lib/puppeteer/page.rb', line 190

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

  frame = @frame_manager.frame(event['frameId'])
  element = frame.main_world.adopt_backend_node(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

Parameters:

  • selector (string)


1234
1235
1236
# File 'lib/puppeteer/page.rb', line 1234

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

#initObject



153
154
155
156
157
158
159
# File 'lib/puppeteer/page.rb', line 153

def init
  await_all(
    @frame_manager.async_init(@target.target_id),
    @client.async_send_message('Performance.enable'),
    @client.async_send_message('Log.enable'),
  )
end

#keyboard(&block) ⇒ Object



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

def keyboard(&block)
  @keyboard.instance_eval(&block) unless block.nil?

  @keyboard
end

#main_frameObject



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

def main_frame
  @frame_manager.main_frame
end

#metricsObject



517
518
519
520
# File 'lib/puppeteer/page.rb', line 517

def metrics
  response = @client.send_message('Performance.getMetrics')
  Metrics.new(response['metrics'])
end

#offline_mode=(enabled) ⇒ Object



308
309
310
# File 'lib/puppeteer/page.rb', line 308

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

#on(event_name, &block) ⇒ Object

Parameters:

  • event_name (Symbol)


167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/puppeteer/page.rb', line 167

def on(event_name, &block)
  unless PageEmittedEvents.values.include?(event_name.to_s)
    raise ArgumentError.new("Unknown event name: #{event_name}. Known events are #{PageEmittedEvents.values.to_a.join(", ")}")
  end

  if event_name.to_s == 'request'
    super('request') do |req|
      req.enqueue_intercept_action(-> { block.call(req) })
    end
  end

  super(event_name.to_s, &block)
end

#once(event_name, &block) ⇒ Object

Parameters:

  • event_name (Symbol)


182
183
184
185
186
187
188
# File 'lib/puppeteer/page.rb', line 182

def once(event_name, &block)
  unless PageEmittedEvents.values.include?(event_name.to_s)
    raise ArgumentError.new("Unknown event name: #{event_name}. Known events are #{PageEmittedEvents.values.to_a.join(", ")}")
  end

  super(event_name.to_s, &block)
end

#pdf(options = {}) ⇒ String

Returns:

  • (String)


1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
# File 'lib/puppeteer/page.rb', line 1162

def pdf(options = {})
  chunks = create_pdf_stream(options)

  StringIO.open do |stringio|
    if options[:path]
      File.open(options[:path], 'wb') do |f|
        chunks.each do |chunk|
          f.write(chunk)
          stringio.write(chunk)
        end
      end
    else
      chunks.each do |chunk|
        stringio.write(chunk)
      end
    end

    stringio.string
  end
rescue => err
  if err.message.include?('PrintToPDF is not implemented')
    raise PrintToPdfIsNotImplementedError.new
  else
    raise
  end
end

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

Parameters:

Returns:



359
360
361
362
# File 'lib/puppeteer/page.rb', line 359

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

#query_selector(selector) ⇒ !Promise<?Puppeteer.ElementHandle> Also known as: S

‘$()` in JavaScript.

Parameters:

  • selector (string)

Returns:



330
331
332
# File 'lib/puppeteer/page.rb', line 330

def query_selector(selector)
  main_frame.query_selector(selector)
end

#query_selector_all(selector) ⇒ !Promise<!Array<!Puppeteer.ElementHandle>> Also known as: SS

‘$$()` in JavaScript.

Parameters:

  • selector (string)

Returns:



340
341
342
# File 'lib/puppeteer/page.rb', line 340

def query_selector_all(selector)
  main_frame.query_selector_all(selector)
end

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

Parameters:

  • timeout (number|nil) (defaults to: nil)
  • wait_until (string|nil) (defaults to: nil)

    ‘load’ | ‘domcontentloaded’ | ‘networkidle0’ | ‘networkidle2’

Returns:



677
678
679
680
681
# File 'lib/puppeteer/page.rb', line 677

def reload(timeout: nil, wait_until: nil)
  wait_for_navigation(timeout: timeout, wait_until: wait_until) do
    @client.send_message('Page.reload')
  end
end

#request_interception=(value) ⇒ Object

Parameters:

  • value (Bool)


299
300
301
# File 'lib/puppeteer/page.rb', line 299

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

#screenshot(type: nil, path: nil, full_page: nil, clip: nil, quality: nil, omit_background: nil, encoding: nil, capture_beyond_viewport: nil, from_surface: nil) ⇒ Object

Parameters:

  • type (String) (defaults to: nil)

    “png”|“jpeg”|“webp”

  • path (String) (defaults to: nil)
  • full_page (Boolean) (defaults to: nil)
  • clip (Hash) (defaults to: nil)
  • quality (Integer) (defaults to: nil)
  • omit_background (Boolean) (defaults to: nil)
  • encoding (String) (defaults to: nil)


1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
# File 'lib/puppeteer/page.rb', line 1036

def screenshot(type: nil,
               path: nil,
               full_page: nil,
               clip: nil,
               quality: nil,
               omit_background: nil,
               encoding: nil,
               capture_beyond_viewport: nil,
               from_surface: nil)
  options = {
    type: type,
    path: path,
    full_page: full_page,
    clip: clip,
    quality:  quality,
    omit_background: omit_background,
    encoding: encoding,
    capture_beyond_viewport: capture_beyond_viewport,
    from_surface: from_surface,
  }.compact
  screenshot_options = ScreenshotOptions.new(options)

  @screenshot_task_queue.post_task do
    screenshot_task(screenshot_options.type, screenshot_options)
  end
end

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

Parameters:

  • selector (string)
  • values (!Array<string>)

Returns:

  • (!Promise<!Array<string>>)


1241
1242
1243
# File 'lib/puppeteer/page.rb', line 1241

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

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

Parameters:

  • html (String)
  • timeout (Integer) (defaults to: nil)
  • wait_until (String|Array<String>) (defaults to: nil)


657
658
659
# File 'lib/puppeteer/page.rb', line 657

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


420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
# File 'lib/puppeteer/page.rb', line 420

def set_cookie(*cookies)
  assert_cookie_params(cookies, requires: %i(name value))

  page_url = url
  starts_with_http = page_url.start_with?("http")
  items = cookies.map do |cookie|
    (starts_with_http ? { url: page_url } : {}).merge(cookie).tap do |item|
      raise ArgumentError.new("Blank page can not have cookie \"#{item[:name]}\"") if item[:url] == "about:blank"
      raise ArgumentError.new("Data URL page can not have cookie \"#{item[:name]}\"") if item[:url]&.start_with?("data:")
    end
  end
  delete_cookie(*items)
  unless items.empty?
    @client.send_message("Network.setCookies", cookies: items)
  end
end

#set_user_agent(user_agent, user_agent_metadata = nil) ⇒ Object Also known as: user_agent=

Parameters:

  • user_agent (String)
  • user_agent_metadata (Hash) (defaults to: nil)


512
513
514
# File 'lib/puppeteer/page.rb', line 512

def set_user_agent(user_agent,  = nil)
  @frame_manager.network_manager.set_user_agent(user_agent, )
end

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

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

Parameters:

  • expression (string)

Returns:



389
390
391
# File 'lib/puppeteer/page.rb', line 389

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

#tap(selector: nil, &block) ⇒ Object

Parameters:

  • selector (String) (defaults to: nil)


1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
# File 'lib/puppeteer/page.rb', line 1248

def tap(selector: nil, &block)
  # resolves double meaning of tap.
  if selector.nil? && block
    # Original usage of Object#tap.
    #
    # browser.new_page.tap do |page|
    #   ...
    # end
    super(&block)
  else
    # Puppeteer's Page#tap.
    main_frame.tap(selector)
  end
end

#titleString

Returns:

  • (String)


1025
1026
1027
# File 'lib/puppeteer/page.rb', line 1025

def title
  main_frame.title
end

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

Parameters:

  • selector (String)
  • text (String)
  • delay (Number) (defaults to: nil)


1268
1269
1270
# File 'lib/puppeteer/page.rb', line 1268

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

#urlString

Returns:

  • (String)


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

def url
  main_frame.url
end

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

Parameters:

  • timeout (Integer) (defaults to: nil)

Returns:



211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/puppeteer/page.rb', line 211

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_frame(url: nil, predicate: nil, timeout: nil) ⇒ Object



811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
# File 'lib/puppeteer/page.rb', line 811

def wait_for_frame(url: nil, predicate: nil, timeout: nil)
  if !url && !predicate
    raise ArgumentError.new('url or predicate must be specified')
  end
  if predicate && !predicate.is_a?(Proc)
    raise ArgumentError.new('predicate must be a proc.')
  end
  frame_predicate =
    if url
      -> (frame) { frame.url == url }
    else
      predicate
    end

  frames.each do |frame|
    return frame if frame_predicate.call(frame)
  end

  wait_for_frame_manager_event(
    FrameManagerEmittedEvents::FrameAttached,
    FrameManagerEmittedEvents::FrameNavigated,
    predicate: frame_predicate,
    timeout: timeout,
  )
end

#wait_for_function(page_function, args: [], polling: nil, timeout: nil) ⇒ Puppeteer::JSHandle

Parameters:

  • page_function (String)
  • args (Integer|Array) (defaults to: [])
  • polling (String) (defaults to: nil)
  • timeout (Integer) (defaults to: nil)

Returns:



1304
1305
1306
# File 'lib/puppeteer/page.rb', line 1304

def wait_for_function(page_function, args: [], polling: nil, timeout: nil)
  main_frame.wait_for_function(page_function, args: args, polling: polling, timeout: timeout)
end

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



683
684
685
# File 'lib/puppeteer/page.rb', line 683

def wait_for_navigation(timeout: nil, wait_until: nil)
  main_frame.send(:wait_for_navigation, timeout: timeout, wait_until: wait_until)
end

#wait_for_request(url: nil, predicate: nil, timeout: nil) ⇒ Object



751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
# File 'lib/puppeteer/page.rb', line 751

def wait_for_request(url: nil, predicate: nil, timeout: nil)
  if !url && !predicate
    raise ArgumentError.new('url or predicate must be specified')
  end
  if predicate && !predicate.is_a?(Proc)
    raise ArgumentError.new('predicate must be a proc.')
  end
  request_predicate =
    if url
      -> (request) { request.url == url }
    else
      predicate
    end

  wait_for_network_manager_event(NetworkManagerEmittedEvents::Request,
    predicate: request_predicate,
    timeout: timeout,
  )
end

#wait_for_response(url: nil, predicate: nil, timeout: nil) ⇒ Object



785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
# File 'lib/puppeteer/page.rb', line 785

def wait_for_response(url: nil, predicate: nil, timeout: nil)
  if !url && !predicate
    raise ArgumentError.new('url or predicate must be specified')
  end
  if predicate && !predicate.is_a?(Proc)
    raise ArgumentError.new('predicate must be a proc.')
  end
  response_predicate =
    if url
      -> (response) { response.url == url }
    else
      predicate
    end

  wait_for_network_manager_event(NetworkManagerEmittedEvents::Response,
    predicate: response_predicate,
    timeout: timeout,
  )
end

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

Parameters:

  • selector (String)
  • visible (Boolean) (defaults to: nil)

    Wait for element visible (not ‘display: none’ nor ‘visibility: hidden’) on true. default to false.

  • hidden (Boolean) (defaults to: nil)

    Wait for element invisible (‘display: none’ nor ‘visibility: hidden’) on true. default to false.

  • timeout (Integer) (defaults to: nil)


1278
1279
1280
# File 'lib/puppeteer/page.rb', line 1278

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_timeout(milliseconds) ⇒ Object

Parameters:

  • milliseconds (Integer)

    the number of milliseconds to wait.



1285
1286
1287
# File 'lib/puppeteer/page.rb', line 1285

def wait_for_timeout(milliseconds)
  main_frame.wait_for_timeout(milliseconds)
end

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

Parameters:

  • xpath (String)
  • visible (Boolean) (defaults to: nil)

    Wait for element visible (not ‘display: none’ nor ‘visibility: hidden’) on true. default to false.

  • hidden (Boolean) (defaults to: nil)

    Wait for element invisible (‘display: none’ nor ‘visibility: hidden’) on true. default to false.

  • timeout (Integer) (defaults to: nil)


1293
1294
1295
# File 'lib/puppeteer/page.rb', line 1293

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



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

def workers
  @workers.values
end