Class: Puppeteer::Bidi::BaseQueryHandler

Inherits:
Object
  • Object
show all
Defined in:
lib/puppeteer/bidi/query_handler.rb,
sig/puppeteer/bidi/query_handler.rbs

Instance Method Summary collapse

Instance Method Details

#query_all_scriptObject

Returns:

  • (Object)

Raises:

  • (NotImplementedError)


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

def query_all_script
  raise NotImplementedError, "#{self.class}#query_all_script must be implemented"
end

#query_one_scriptObject

Returns:

  • (Object)

Raises:

  • (NotImplementedError)


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

def query_one_script
  raise NotImplementedError, "#{self.class}#query_one_script must be implemented"
end

#run_query_all(element, selector) ⇒ Array<ElementHandle>

Query for all elements matching the selector

Parameters:

  • element (ElementHandle)

    Element to query from

  • selector (String)

    Selector to match

Returns:



189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/puppeteer/bidi/query_handler.rb', line 189

def run_query_all(element, selector)
  realm = element.frame.isolated_realm

  # Adopt the element into the isolated realm first.
  # This ensures the realm is valid and triggers puppeteer_util reset if needed
  # after navigation (mirrors Puppeteer's @bindIsolatedHandle decorator pattern).
  adopted_element = realm.adopt_handle(element)

  result = realm.call_function(
    query_all_script,
    true,
    arguments: [
      Serializer.serialize(realm.puppeteer_util_lazy_arg),
      adopted_element.remote_value,
      Serializer.serialize(selector)
    ]
  )

  return [] if result['type'] == 'exception'

  result_value = result['result']
  return [] unless result_value['type'] == 'array'

  handles = result_value['value'].map do |element_value|
    JSHandle.from(element_value, realm.core_realm)
  end.select { |h| h.is_a?(ElementHandle) }

  handles.map { |h| element.frame.main_realm.transfer_handle(h) }
ensure
  adopted_element&.dispose
end

#run_query_one(element, selector) ⇒ ElementHandle?

Query for a single element matching the selector

Parameters:

  • element (ElementHandle)

    Element to query from

  • selector (String)

    Selector to match

Returns:



154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/puppeteer/bidi/query_handler.rb', line 154

def run_query_one(element, selector)
  realm = element.frame.isolated_realm

  # Adopt the element into the isolated realm first.
  # This ensures the realm is valid and triggers puppeteer_util reset if needed
  # after navigation (mirrors Puppeteer's @bindIsolatedHandle decorator pattern).
  adopted_element = realm.adopt_handle(element)

  result = realm.call_function(
    query_one_script,
    false,
    arguments: [
      Serializer.serialize(realm.puppeteer_util_lazy_arg),
      adopted_element.remote_value,
      Serializer.serialize(selector)
    ]
  )

  return nil if result['type'] == 'exception'

  result_value = result['result']
  return nil if result_value['type'] == 'null' || result_value['type'] == 'undefined'

  handle = JSHandle.from(result_value, realm.core_realm)
  return nil unless handle.is_a?(ElementHandle)

  element.frame.main_realm.transfer_handle(handle)
ensure
  adopted_element&.dispose
end

#wait_for(element_or_frame, selector, visible: nil, hidden: nil, timeout: nil, polling: nil, &block) ⇒ void

This method returns an undefined value.

Parameters:

  • element_or_frame (Object)
  • selector (Object)
  • visible: (Object) (defaults to: nil)
  • hidden: (Object) (defaults to: nil)
  • timeout: (Object) (defaults to: nil)
  • polling: (Object) (defaults to: nil)


221
222
223
224
225
226
227
228
229
230
231
# File 'lib/puppeteer/bidi/query_handler.rb', line 221

def wait_for(element_or_frame, selector, visible: nil, hidden: nil, timeout: nil, polling: nil, &block)
  if element_or_frame.is_a?(Frame)
    wait_for_in_frame(element_or_frame, nil, selector, visible: visible, hidden: hidden, timeout: timeout, polling: polling, &block)
  elsif element_or_frame.is_a?(ElementHandle)
    frame = element_or_frame.frame
    root = frame.isolated_realm.adopt_handle(element_or_frame)
    wait_for_in_frame(frame, root, selector, visible: visible, hidden: hidden, timeout: timeout, polling: polling, &block)
  else
    raise ArgumentError, "Unsupported query root: #{element_or_frame.class}"
  end
end

#wait_for_in_frame(frame, root, selector, visible:, hidden:, timeout:, polling:, &block) ⇒ void

This method returns an undefined value.

Parameters:

  • frame (Object)
  • root (Object)
  • selector (Object)
  • visible: (Object)
  • hidden: (Object)
  • timeout: (Object)
  • polling: (Object)

Raises:



247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
# File 'lib/puppeteer/bidi/query_handler.rb', line 247

def wait_for_in_frame(frame, root, selector, visible:, hidden:, timeout:, polling:, &block)
  raise FrameDetachedError if frame.detached?

  visibility = if visible
                  true
                elsif hidden
                  false
                end

  resolved_polling = (visible || hidden ? 'raf' : polling)

  options = {}
  options[:polling] = resolved_polling if resolved_polling
  options[:timeout] = timeout unless timeout.nil?

  begin
    handle = frame.isolated_realm.wait_for_function(
      wait_for_selector_script,
      options,
      frame.isolated_realm.puppeteer_util_lazy_arg,
      selector,
      root,
      visibility,
      &block
    )

    return nil unless handle

    unless handle.is_a?(ElementHandle)
      begin
        handle.dispose
      rescue StandardError
        # Ignored: primitive handles may not support dispose.
      end
      return nil
    end

    frame.main_realm.transfer_handle(handle)
  rescue Puppeteer::Bidi::TimeoutError => e
    raise Puppeteer::Bidi::TimeoutError,
          "Waiting for selector `#{selector}` failed: Waiting failed: #{e.message.split(': ').last}"
  rescue StandardError => e
    message = "Waiting for selector `#{selector}` failed"
    alias_selector = selector.sub('//*', '//')
    if alias_selector != selector
      message = "#{message} | alias: Waiting for selector `#{alias_selector}` failed"
    end
    raise StandardError.new(message), cause: e
  end
end

#wait_for_selector_scriptObject

Returns:

  • (Object)

Raises:

  • (NotImplementedError)


243
244
245
# File 'lib/puppeteer/bidi/query_handler.rb', line 243

def wait_for_selector_script
  raise NotImplementedError, "#{self.class}#wait_for_selector_script must be implemented"
end