Class: Puppeteer::ElementHandle

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

Defined Under Namespace

Classes: ElementNotFoundError, ElementNotVisibleError, Point, ScrollIntoViewError

Instance Attribute Summary

Attributes inherited from JSHandle

#context, #remote_object

Instance Method Summary collapse

Methods included from IfPresent

#if_present

Methods inherited from JSHandle

#async_evaluate, #async_evaluate_handle, create, #dispose, #disposed?, #evaluate, #evaluate_handle, #execution_context, #json_value, #properties

Constructor Details

#initialize(context:, client:, remote_object:, page:, frame_manager:) ⇒ ElementHandle

Returns a new instance of ElementHandle.

Parameters:



10
11
12
13
14
15
# File 'lib/puppeteer/element_handle.rb', line 10

def initialize(context:, client:, remote_object:, page:, frame_manager:)
  super(context: context, client: client, remote_object: remote_object)
  @page = page
  @frame_manager = frame_manager
  @disposed = false
end

Instance Method Details

#as_elementObject



17
18
19
# File 'lib/puppeteer/element_handle.rb', line 17

def as_element
  self
end

#async_pressFuture

Parameters:

  • key (String)
  • delay (number|nil)

Returns:

  • (Future)


270
271
272
# File 'lib/puppeteer/element_handle.rb', line 270

async def async_press(key, delay: nil)
  press(key, delay: delay)
end

#async_type_textFuture

Parameters:

  • text (String)
  • delay (number|nil)

Returns:

  • (Future)


256
257
258
# File 'lib/puppeteer/element_handle.rb', line 256

async def async_type_text(text, delay: nil)
  type_text(text, delay: delay)
end

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

Parameters:

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

    “left”|“right”|“middle”

  • click_count (Number) (defaults to: nil)


154
155
156
157
158
# File 'lib/puppeteer/element_handle.rb', line 154

def click(delay: nil, button: nil, click_count: nil)
  scroll_into_view_if_needed
  point = clickable_point
  @page.mouse.click(point.x, point.y, delay: delay, button: button, click_count: click_count)
end

#clickable_pointObject



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/puppeteer/element_handle.rb', line 92

def clickable_point
  result = @remote_object.content_quads(@client)
  if !result || result["quads"].empty?
    raise ElementNotVisibleError.new
  end

  # Filter out quads that have too small area to click into.
  layout_metrics = @client.send_message('Page.getLayoutMetrics')
  client_width = layout_metrics["layoutViewport"]["clientWidth"]
  client_height = layout_metrics["layoutViewport"]["clientHeight"]

  quads = result["quads"].
            map { |quad| from_protocol_quad(quad) }.
            map { |quad| intersect_quad_with_viewport(quad, client_width, client_height) }.
            select { |quad| compute_quad_area(quad) > 1 }
  if quads.empty?
    raise ElementNotVisibleError.new
  end

  # Return the middle point of the first quad.
  quads.first.reduce(:+) / 4
end

#content_frameObject



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

def content_frame
  node_info = @remote_object.node_info
  frame_id = node_info['node']['frameId']
  if frame_id.is_a?(String)
    @frame_manager.frame(frame_id)
  else
    nil
  end
end

#focusObject



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

def focus
  evaluate('element => element.focus()')
end

#press(key, delay: nil) ⇒ Object

Parameters:

  • key (String)
  • delay (number|nil) (defaults to: nil)


262
263
264
265
# File 'lib/puppeteer/element_handle.rb', line 262

def press(key, delay: nil)
  focus
  @page.keyboard.press(key, delay: delay)
end

#S(selector) ⇒ Object

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

Parameters:

  • selector (String)


360
361
362
363
364
365
366
367
368
369
370
371
372
# File 'lib/puppeteer/element_handle.rb', line 360

def S(selector)
  handle = evaluate_handle(
    '(element, selector) => element.querySelector(selector)',
    selector,
  )
  element = handle.as_element

  if element
    return element
  end
  handle.dispose
  nil
end

#scroll_into_view_if_neededObject



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

def scroll_into_view_if_needed
  js = <<~JAVASCRIPT
    async(element, pageJavascriptEnabled) => {
      if (!element.isConnected)
        return 'Node is detached from document';
      if (element.nodeType !== Node.ELEMENT_NODE)
        return 'Node is not of type HTMLElement';
      // force-scroll if page's javascript is disabled.
      if (!pageJavascriptEnabled) {
        element.scrollIntoView({block: 'center', inline: 'center', behavior: 'instant'});
        return false;
      }
      const visibleRatio = await new Promise(resolve => {
        const observer = new IntersectionObserver(entries => {
          resolve(entries[0].intersectionRatio);
          observer.disconnect();
        });
        observer.observe(element);
      });
      if (visibleRatio !== 1.0)
        element.scrollIntoView({block: 'center', inline: 'center', behavior: 'instant'});
      return false;
    }
  JAVASCRIPT
  error = evaluate(js, @page.javascript_enabled) # returns String or false
  if error
    raise ScrollIntoViewError.new(error)
  end
end

#Seval(selector, page_function, *args) ⇒ Object

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

Parameters:

  • selector (String)
  • page_function (String)

Returns:

  • (Object)


396
397
398
399
400
401
402
403
404
405
# File 'lib/puppeteer/element_handle.rb', line 396

def Seval(selector, page_function, *args)
  element_handle = S(selector)
  unless element_handle
    raise ElementNotFoundError.new(selector)
  end
  result = element_handle.evaluate(page_function, *args)
  element_handle.dispose

  result
end

#SS(selector) ⇒ Object

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

Parameters:

  • selector (String)


376
377
378
379
380
381
382
383
384
# File 'lib/puppeteer/element_handle.rb', line 376

def SS(selector)
  handles = evaluate_handle(
    '(element, selector) => element.querySelectorAll(selector)',
    selector,
  )
  properties = handles.properties
  handles.dispose
  properties.values.map(&:as_element).compact
end

#SSeval(selector, page_function, *args) ⇒ Object

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

Parameters:

  • selector (String)
  • page_function (String)

Returns:

  • (Object)


411
412
413
414
415
416
417
418
419
# File 'lib/puppeteer/element_handle.rb', line 411

def SSeval(selector, page_function, *args)
  handles = evaluate_handle(
              '(element, selector) => Array.from(element.querySelectorAll(selector))',
              selector)
  result = handles.evaluate(page_function, *args)
  handles.dispose

  result
end

#type_text(text, delay: nil) ⇒ Object

Parameters:

  • text (String)
  • delay (number|nil) (defaults to: nil)


248
249
250
251
# File 'lib/puppeteer/element_handle.rb', line 248

def type_text(text, delay: nil)
  focus
  @page.keyboard.type_text(text, delay: delay)
end