lib/puppeteer/page.rb in puppeteer-ruby-0.0.15 vs lib/puppeteer/page.rb in puppeteer-ruby-0.0.16
- old
+ new
@@ -687,46 +687,99 @@
main_frame.send(:wait_for_navigation, timeout: timeout, wait_until: wait_until)
end
define_async_method :async_wait_for_navigation
- # /**
- # * @param {(string|Function)} urlOrPredicate
- # * @param {!{timeout?: number}=} options
- # * @return {!Promise<!Puppeteer.Request>}
- # */
- # async waitForRequest(urlOrPredicate, options = {}) {
- # const {
- # timeout = this._timeoutSettings.timeout(),
- # } = options;
- # return helper.waitForEvent(this._frameManager.networkManager(), Events.NetworkManager.Request, request => {
- # if (helper.isString(urlOrPredicate))
- # return (urlOrPredicate === request.url());
- # if (typeof urlOrPredicate === 'function')
- # return !!(urlOrPredicate(request));
- # return false;
- # }, timeout, this._sessionClosePromise());
- # }
+ private def wait_for_network_manager_event(event_name, predicate:, timeout:)
+ option_timeout = timeout || @timeout_settings.timeout
- # /**
- # * @param {(string|Function)} urlOrPredicate
- # * @param {!{timeout?: number}=} options
- # * @return {!Promise<!Puppeteer.Response>}
- # */
- # async waitForResponse(urlOrPredicate, options = {}) {
- # const {
- # timeout = this._timeoutSettings.timeout(),
- # } = options;
- # return helper.waitForEvent(this._frameManager.networkManager(), Events.NetworkManager.Response, response => {
- # if (helper.isString(urlOrPredicate))
- # return (urlOrPredicate === response.url());
- # if (typeof urlOrPredicate === 'function')
- # return !!(urlOrPredicate(response));
- # return false;
- # }, timeout, this._sessionClosePromise());
- # }
+ @wait_for_network_manager_event_listener_ids ||= {}
+ if_present(@wait_for_network_manager_event_listener_ids[event_name]) do |listener_id|
+ @frame_manager.network_manager.remove_event_listener(listener_id)
+ end
+ promise = resolvable_future
+
+ @wait_for_network_manager_event_listener_ids[event_name] =
+ @frame_manager.network_manager.add_event_listener(event_name) do |event_target|
+ if predicate.call(event_target)
+ promise.fulfill(nil)
+ end
+ end
+
+ begin
+ Timeout.timeout(option_timeout / 1000.0) do
+ await_any(promise, session_close_promise)
+ end
+ rescue Timeout::Error
+ raise Puppeteer::TimeoutError.new("waiting for #{event_name} failed: timeout #{timeout}ms exceeded")
+ ensure
+ @frame_manager.network_manager.remove_event_listener(@wait_for_network_manager_event_listener_ids[event_name])
+ end
+ end
+
+ private def session_close_promise
+ @disconnect_promise ||= resolvable_future do |future|
+ @client.observe_first('Events.CDPSession.Disconnected') do
+ future.reject(Puppeteer::CDPSession::Error.new('Target Closed'))
+ end
+ end
+ end
+
+ # - 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') })`
+ #
+ # @param url [String]
+ # @param predicate [Proc(Puppeteer::Request -> Boolean)]
+ private 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
+ -> (request) { predicate.call(request) }
+ end
+
+ wait_for_network_manager_event('Events.NetworkManager.Request',
+ predicate: request_predicate,
+ timeout: timeout,
+ )
+ end
+
+ define_async_method :async_wait_for_request
+
+ # @param url [String]
+ # @param predicate [Proc(Puppeteer::Request -> Boolean)]
+ private 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
+ -> (response) { predicate.call(response) }
+ end
+
+ wait_for_network_manager_event('Events.NetworkManager.Response',
+ predicate: response_predicate,
+ timeout: timeout,
+ )
+ end
+
+ define_async_method :async_wait_for_response
+
# @param timeout [number|nil]
# @param wait_until [string|nil] 'load' | 'domcontentloaded' | 'networkidle0' | 'networkidle2'
def go_back(timeout: nil, wait_until: nil)
go(-1, timeout: timeout, wait_until: wait_until)
end
@@ -760,24 +813,23 @@
return if @javascript_enabled == enabled
@javascript_enabled = enabled
@client.send_message('Emulation.setScriptExecutionDisabled', value: !enabled)
end
- # /**
- # * @param {boolean} enabled
- # */
- # async setBypassCSP(enabled) {
- # await this._client.send('Page.setBypassCSP', { enabled });
- # }
+ # @param enabled [Boolean]
+ def bypass_csp=(enabled)
+ @client.send_message('Page.setBypassCSP', enabled: enabled)
+ end
- # /**
- # * @param {?string} type
- # */
- # async emulateMediaType(type) {
- # assert(type === 'screen' || type === 'print' || type === null, 'Unsupported media type: ' + type);
- # await this._client.send('Emulation.setEmulatedMedia', {media: type || ''});
- # }
+ # @param media_type [String|Symbol|nil] either of (media, print, nil)
+ 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
# /**
# * @param {?Array<MediaFeature>} features
# */
# async emulateMediaFeatures(features) {
@@ -793,11 +845,11 @@
# }
# }
# @param timezone_id [String?]
def emulate_timezone(timezone_id)
- @client.send_message('Emulation.setTimezoneOverride', timezoneId: timezoneId || '')
+ @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
@@ -1031,19 +1083,9 @@
def type_text(selector, text, delay: nil)
main_frame.type_text(selector, text, delay: delay)
end
define_async_method :async_type_text
-
- # /**
- # * @param {(string|number|Function)} selectorOrFunctionOrTimeout
- # * @param {!{visible?: boolean, hidden?: boolean, timeout?: number, polling?: string|number}=} options
- # * @param {!Array<*>} args
- # * @return {!Promise<!Puppeteer.JSHandle>}
- # */
- # waitFor(selectorOrFunctionOrTimeout, options = {}, ...args) {
- # return this.mainFrame().waitFor(selectorOrFunctionOrTimeout, options, ...args);
- # }
# @param selector [String]
# @param visible [Boolean] Wait for element visible (not 'display: none' nor 'visibility: hidden') on true. default to false.
# @param hidden [Boolean] Wait for element invisible ('display: none' nor 'visibility: hidden') on true. default to false.
# @param timeout [Integer]