Class: Puppeteer::Browser

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

Constant Summary collapse

EVENT_MAPPINGS =
{
  disconnected: 'Events.Browser.Disconnected',
  targetcreated: 'Events.Browser.TargetCreated',
  targetchanged: 'Events.Browser.TargetChanged',
  targetdestroyed: 'Events.Browser.TargetDestroyed',
}

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

Methods included from DebugPrint

#debug_print, #debug_puts

Constructor Details

#initialize(connection:, context_ids:, ignore_https_errors:, default_viewport:, process:, close_callback:) ⇒ Browser

Returns a new instance of Browser.

Parameters:



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/puppeteer/browser.rb', line 35

def initialize(connection:, context_ids:, ignore_https_errors:, default_viewport:, process:, close_callback:)
  @ignore_https_errors = ignore_https_errors
  @default_viewport = default_viewport
  @process = process
  # @screenshot_task_queue = TaskQueue.new
  @connection = connection
  @close_callback = close_callback

  @default_context = Puppeteer::BrowserContext.new(@connection, self, nil)
  @contexts = {}
  context_ids.each do |context_id|
    @contexts[context_id] = Puppeteer::BrowserContext.new(@connection, self. context_id)
  end
  @targets = {}
  @connection.on_event 'Events.Connection.Disconnected' do
    emit_event 'Events.Browser.Disconnected'
  end
  @connection.on_event 'Target.targetCreated', &method(:handle_target_created)
  @connection.on_event 'Target.targetDestroyed', &method(:handle_target_destroyed)
  @connection.on_event 'Target.targetInfoChanged', &method(:handle_target_info_changed)
end

Class Method Details

.create(connection:, context_ids:, ignore_https_errors:, default_viewport:, process:, close_callback:) ⇒ Object

Parameters:



16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/puppeteer/browser.rb', line 16

def self.create(connection:, context_ids:, ignore_https_errors:, default_viewport:, process:, close_callback:)
  browser = Puppeteer::Browser.new(
    connection: connection,
    context_ids: context_ids,
    ignore_https_errors: ignore_https_errors,
    default_viewport: default_viewport,
    process: process,
    close_callback: close_callback,
  )
  connection.send_message('Target.setDiscoverTargets', discover: true)
  browser
end

Instance Method Details

#browser_contextsObject



85
86
87
# File 'lib/puppeteer/browser.rb', line 85

def browser_contexts
  [@default_context].concat(@contexts.values)
end

#closeObject



259
260
261
262
# File 'lib/puppeteer/browser.rb', line 259

def close
  @close_callback.call
  disconnect
end

#connected?Boolean

Returns:

  • (Boolean)


268
269
270
# File 'lib/puppeteer/browser.rb', line 268

def connected?
  !@connection.closed?
end

#create_incognito_browser_contextPuppeteer::BrowserContext



79
80
81
82
83
# File 'lib/puppeteer/browser.rb', line 79

def create_incognito_browser_context
  result = @connection.send_message('Target.createBrowserContext')
  browser_context_id = result['browserContextId']
  @contexts[browser_context_id] = Puppeteer::BrowserContext.new(@connection, self, browser_context_id)
end

#create_page_in_context(context_id) ⇒ !Promise<!Puppeteer.Page>

Parameters:

  • contextId (?string)

Returns:



187
188
189
190
191
192
193
194
195
196
197
# File 'lib/puppeteer/browser.rb', line 187

def create_page_in_context(context_id)
  create_target_params = { url: 'about:blank' }
  if context_id
    create_target_params[:browserContextId] = context_id
  end
  result = @connection.send_message('Target.createTarget', **create_target_params)
  target_id = result['targetId']
  target = @targets[target_id]
  await target.initialized_promise
  await target.page
end

#default_browser_contextPuppeteer::BrowserContext



90
91
92
# File 'lib/puppeteer/browser.rb', line 90

def default_browser_context
  @default_context
end

#disconnectObject



264
265
266
# File 'lib/puppeteer/browser.rb', line 264

def disconnect
  @connection.dispose
end

#dispose_context(context_id) ⇒ Object

Parameters:

  • context_id (String)


95
96
97
98
# File 'lib/puppeteer/browser.rb', line 95

def dispose_context(context_id)
  @connection.send_message('Target.disposeBrowserContext', browserContextId: context_id)
  @contexts.remove(context_id)
end

#handle_target_created(event) ⇒ Object

Parameters:

  • event (!Protocol.Target.targetCreatedPayload)


101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/puppeteer/browser.rb', line 101

def handle_target_created(event)
  target_info = Puppeteer::Target::TargetInfo.new(event['targetInfo'])
  browser_context_id = target_info.browser_context_id
  context =
    if browser_context_id && @contexts.has_key?(browser_context_id)
      @contexts[browser_context_id]
    else
      @default_context
    end

  target = Puppeteer::Target.new(
    target_info: target_info,
    browser_context: context,
    session_factory: -> { @connection.create_session(target_info) },
    ignore_https_errors: @ignore_https_errors,
    default_viewport: @default_viewport,
    screenshot_task_queue: @screenshot_task_queue,
  )
  #   assert(!this._targets.has(event.targetInfo.targetId), 'Target should not exist before targetCreated');
  @targets[target_info.target_id] = target
  if await target.initialized_promise
    emit_event 'Events.Browser.TargetCreated', target
    context.emit_event 'Events.BrowserContext.TargetCreated', target
  end

  if_present(pending_target_info_changed_event.delete(target_info.target_id)) do |pending_event|
    handle_target_info_changed(pending_event)
  end
end

#handle_target_destroyed(event) ⇒ Object

Parameters:

  • event ({targetId: string})


133
134
135
136
137
138
139
140
141
142
143
# File 'lib/puppeteer/browser.rb', line 133

def handle_target_destroyed(event)
  target_id = event['targetId']
  target = @targets[target_id]
  target.ignore_initialize_callback_promise
  @targets.delete(target_id)
  target.closed_callback
  if await target.initialized_promise
    emit_event 'Events.Browser.TargetDestroyed', target
    target.browser_context.emit_event 'Events.BrowserContext.TargetDestroyed', target
  end
end

#handle_target_info_changed(event) ⇒ Object

Parameters:

  • event (!Protocol.Target.targetInfoChangedPayload)


146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/puppeteer/browser.rb', line 146

def handle_target_info_changed(event)
  target_info = Puppeteer::Target::TargetInfo.new(event['targetInfo'])
  target = @targets[target_info.target_id]
  if !target
    # targetCreated is sometimes notified after targetInfoChanged.
    # We don't raise error. Instead, keep the event as a pending change,
    # and handle it on handle_target_created.
    #
    # D, [2020-04-22T00:22:26.630328 #79646] DEBUG -- : RECV << {"method"=>"Target.targetInfoChanged", "params"=>{"targetInfo"=>{"targetId"=>"8068CED48357B9557EEC85AA62165A8E", "type"=>"iframe", "title"=>"", "url"=>"", "attached"=>true, "browserContextId"=>"7895BFB24BF22CE40584808713D96E8D"}}}
    # E, [2020-04-22T00:22:26.630448 #79646] ERROR -- : target should exist before targetInfoChanged (StandardError)
    # D, [2020-04-22T00:22:26.630648 #79646] DEBUG -- : RECV << {"method"=>"Target.targetCreated", "params"=>{"targetInfo"=>{"targetId"=>"8068CED48357B9557EEC85AA62165A8E", "type"=>"iframe", "title"=>"", "url"=>"", "attached"=>false, "browserContextId"=>"7895BFB24BF22CE40584808713D96E8D"}}}
    pending_target_info_changed_event[target_info.target_id] = event
    return
    # original implementation is:
    #
    # raise StandardError.new('target should exist before targetInfoChanged')
  end
  previous_url = target.url
  was_initialized = target.initialized?
  target.handle_target_info_changed(target_info)
  if was_initialized && previous_url != target.url
    emit_event 'Events.Browser.TargetChanged', target
    target.browser_context.emit_event 'Events.BrowserContext.TargetChanged', target
  end
end

#new_pageObject



181
182
183
# File 'lib/puppeteer/browser.rb', line 181

def new_page
  @default_context.new_page
end

#on(event_name, &block) ⇒ Object

Parameters:

  • event_name (Symbol)

    either of :disconnected, :targetcreated, :targetchanged, :targetdestroyed



65
66
67
68
69
70
71
# File 'lib/puppeteer/browser.rb', line 65

def on(event_name, &block)
  unless EVENT_MAPPINGS.has_key?(event_name.to_sym)
    raise ArgumentError.new("Unknown event name: #{event_name}. Known events are #{EVENT_MAPPINGS.keys.join(", ")}")
  end

  add_event_listener(EVENT_MAPPINGS[event_name.to_sym], &block)
end

#pages!Promise<!Array<!Puppeteer.Page>>

Returns:



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

def pages
  browser_contexts.flat_map(&:pages)
end

#processPuppeteer::BrowserRunner::BrowserProcess



74
75
76
# File 'lib/puppeteer/browser.rb', line 74

def process
  @process
end

#target!Target

Returns:



206
207
208
# File 'lib/puppeteer/browser.rb', line 206

def target
  targets.first { |target| target.type == 'browser' }
end

#targets!Array<!Target>

Returns:



200
201
202
# File 'lib/puppeteer/browser.rb', line 200

def targets
  @targets.values.select { |target| target.initialized? }
end

#user_agentString

Returns:

  • (String)


255
256
257
# File 'lib/puppeteer/browser.rb', line 255

def user_agent
  get_version.user_agent
end

#versionString

Returns:

  • (String)


250
251
252
# File 'lib/puppeteer/browser.rb', line 250

def version
  get_version.product
end

#wait_for_target(predicate:, timeout: nil) ⇒ !Promise<!Target>

Parameters:

  • predicate (function(!Target):boolean)
  • options ({timeout?: number}=)

Returns:



213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
# File 'lib/puppeteer/browser.rb', line 213

def wait_for_target(predicate:, timeout: nil)
  timeout_in_sec = (timeout || 30000).to_i / 1000.0
  existing_target = targets.first { |target| predicate.call(target) }
  return existing_target if existing_target

  event_listening_ids = []
  target_promise = resolvable_future
  event_listening_ids << add_event_listener('Events.Browser.TargetCreated') do |target|
    if predicate.call(target)
      target_promise.fulfill(target)
    end
  end
  event_listening_ids << add_event_listener('Events.Browser.TargetChanged') do |target|
    if predicate.call(target)
      target_promise.fulfill(target)
    end
  end

  begin
    if timeout_in_sec > 0
      Timeout.timeout(timeout_in_sec) do
        target_promise.value!
      end
    else
      target_promise.value!
    end
  ensure
    remove_event_listener(*event_listening_ids)
  end
end

#websocket_endpointString

Returns:

  • (String)


177
178
179
# File 'lib/puppeteer/browser.rb', line 177

def websocket_endpoint
  @connection.url
end