Class: Puppeteer::LifecycleWatcher

Inherits:
Object
  • Object
show all
Includes:
IfPresent
Defined in:
lib/puppeteer/lifecycle_watcher.rb

Overview

Defined Under Namespace

Classes: ExpectedLifecycle, FrameDetachedError, TerminatedError

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from IfPresent

#if_present

Constructor Details

#initialize(frame_manager, frame, wait_until, timeout) ⇒ LifecycleWatcher

  • @param Puppeteer::LifecycleWatcher.!Puppeteer!Puppeteer.FrameManager frameManager

  • @param Puppeteer::LifecycleWatcher.!Puppeteer!Puppeteer.Frame frame

  • @param string|!Array<string> waitUntil

  • @param number timeout



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
# File 'lib/puppeteer/lifecycle_watcher.rb', line 64

def initialize(frame_manager, frame, wait_until, timeout)
  @expected_lifecycle = ExpectedLifecycle.new(wait_until)
  @frame_manager = frame_manager
  @frame = frame
  @initial_loader_id = frame.loader_id
  @timeout = timeout

  @listener_ids = {}
  @listener_ids['client'] = @frame_manager.client.add_event_listener(CDPSessionEmittedEvents::Disconnected) do
    terminate(TerminatedError.new('Navigation failed because browser has disconnected!'))
  end
  @listener_ids['frame_manager'] = [
    @frame_manager.add_event_listener(FrameManagerEmittedEvents::LifecycleEvent) do |_|
      check_lifecycle_complete
    end,
    @frame_manager.add_event_listener(FrameManagerEmittedEvents::FrameNavigatedWithinDocument, &method(:navigated_within_document)),
    @frame_manager.add_event_listener(FrameManagerEmittedEvents::FrameNavigated, &method(:navigated)),
    @frame_manager.add_event_listener(FrameManagerEmittedEvents::FrameSwapped, &method(:handle_frame_swapped)),
    @frame_manager.add_event_listener(FrameManagerEmittedEvents::FrameDetached, &method(:handle_frame_detached)),
  ]
  @listener_ids['network_manager'] = [
    @frame_manager.network_manager.add_event_listener(NetworkManagerEmittedEvents::Request, &method(:handle_request)),
    @frame_manager.network_manager.add_event_listener(NetworkManagerEmittedEvents::Response, &method(:handle_response)),
    @frame_manager.network_manager.add_event_listener(NetworkManagerEmittedEvents::RequestFailed, &method(:handle_request_failed)),
  ]

  @same_document_navigation_promise = resolvable_future
  @lifecycle_promise = resolvable_future
  @new_document_navigation_promise = resolvable_future
  @termination_promise = resolvable_future
  check_lifecycle_complete
end

Instance Attribute Details

#new_document_navigation_promiseObject (readonly)

Returns the value of attribute new_document_navigation_promise.



148
149
150
# File 'lib/puppeteer/lifecycle_watcher.rb', line 148

def new_document_navigation_promise
  @new_document_navigation_promise
end

#same_document_navigation_promiseObject (readonly)

Returns the value of attribute same_document_navigation_promise.



148
149
150
# File 'lib/puppeteer/lifecycle_watcher.rb', line 148

def same_document_navigation_promise
  @same_document_navigation_promise
end

Instance Method Details

#disposeObject



199
200
201
202
203
204
205
206
207
208
209
# File 'lib/puppeteer/lifecycle_watcher.rb', line 199

def dispose
  if_present(@listener_ids['client']) do |id|
    @frame_manager.client.remove_event_listener(id)
  end
  if_present(@listener_ids['frame_manager']) do |ids|
    @frame_manager.remove_event_listener(*ids)
  end
  if_present(@listener_ids['network_manager']) do |ids|
    @frame_manager.network_manager.remove_event_listener(*ids)
  end
end

#handle_frame_detached(frame) ⇒ Object

Parameters:



126
127
128
129
130
131
132
# File 'lib/puppeteer/lifecycle_watcher.rb', line 126

def handle_frame_detached(frame)
  if @frame == frame
    @termination_promise.reject(FrameDetachedError.new)
    return
  end
  check_lifecycle_complete
end

#handle_request(request) ⇒ Object

Parameters:



98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/puppeteer/lifecycle_watcher.rb', line 98

def handle_request(request)
  return if request.frame != @frame || !request.navigation_request?
  @navigation_request = request
  # Resolve previous navigation response in case there are multiple
  # navigation requests reported by the backend. This generally should not
  # happen by it looks like it's possible.
  @navigation_response_received.fulfill(nil) if @navigation_response_received && !@navigation_response_received.resolved?
  @navigation_response_received = resolvable_future
  if request.response && !@navigation_response_received.resolved?
    @navigation_response_received.fulfill(nil)
  end
end

#handle_request_failed(request) ⇒ Object

Parameters:



112
113
114
115
116
# File 'lib/puppeteer/lifecycle_watcher.rb', line 112

def handle_request_failed(request)
  return if @navigation_request&.internal&.request_id != request.internal.request_id

  @navigation_response_received.fulfill(nil) unless @navigation_response_received.resolved?
end

#handle_response(response) ⇒ Object

Parameters:



119
120
121
122
123
# File 'lib/puppeteer/lifecycle_watcher.rb', line 119

def handle_response(response)
  return if @navigation_request&.internal&.request_id != response.request.internal.request_id

  @navigation_response_received.fulfill(nil) unless @navigation_response_received.resolved?
end


135
136
137
138
139
140
141
# File 'lib/puppeteer/lifecycle_watcher.rb', line 135

def navigation_response
  # Continue with a possibly null response.
  @navigation_response_received.value! rescue nil
  if_present(@navigation_request) do |request|
    request.response
  end
end

#timeout_or_termination_promiseObject



154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/puppeteer/lifecycle_watcher.rb', line 154

def timeout_or_termination_promise
  if @timeout > 0
    future do
      Timeout.timeout(@timeout / 1000.0) do
        @termination_promise.value!
      end
    rescue Timeout::Error
      raise Puppeteer::TimeoutError.new("Navigation timeout of #{@timeout}ms exceeded")
    end
  else
    @termination_promise
  end
end