Class: Puppeteer::Locator

Inherits:
Object
  • Object
show all
Includes:
EventCallbackable
Defined in:
lib/puppeteer/locators.rb

Defined Under Namespace

Classes: TimeoutController

Constant Summary collapse

RETRY_DELAY_SECONDS =
0.1

Class Method Summary collapse

Instance Method Summary collapse

Methods included from EventCallbackable

#add_event_listener, #emit_event, #observe_first, #off, #on_event, #remove_event_listener

Constructor Details

#initializeLocator

Returns a new instance of Locator.



49
50
51
52
53
54
55
# File 'lib/puppeteer/locators.rb', line 49

def initialize
  @visibility = nil
  @timeout = 30_000
  @ensure_element_is_in_viewport = true
  @wait_for_enabled = true
  @wait_for_stable_bounding_box = true
end

Class Method Details

.function_string?(input) ⇒ Boolean

Returns:

  • (Boolean)


81
82
83
84
85
86
87
88
89
# File 'lib/puppeteer/locators.rb', line 81

def self.function_string?(input)
  return false unless input.is_a?(String)

  stripped = input.lstrip
  return true if input.include?('=>')
  return true if stripped.start_with?('async function')

  stripped.start_with?('function')
end

.race(locators) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/puppeteer/locators.rb', line 59

def self.race(locators)
  proxy = locators.find { |locator| locator.is_a?(Puppeteer::ReactorRunner::Proxy) }
  return Puppeteer::RaceLocator.create(locators) unless proxy

  runner = proxy.instance_variable_get(:@runner)
  locators.each do |locator|
    next unless locator.is_a?(Puppeteer::ReactorRunner::Proxy)

    locator_runner = locator.instance_variable_get(:@runner)
    unless locator_runner == runner
      raise ArgumentError.new('Locators for race must belong to the same runner')
    end
  end

  runner.sync do
    unwrapped = locators.map { |locator| runner.send(:unwrap, locator) }
    runner.wrap(Puppeteer::RaceLocator.create(unwrapped))
  end
end

Instance Method Details

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



204
205
206
207
208
209
210
211
212
213
# File 'lib/puppeteer/locators.rb', line 204

def click(delay: nil, button: nil, click_count: nil, count: nil, offset: nil)
  perform_action('Locator.click',
    conditions: [
      method(:ensure_element_is_in_viewport_if_needed),
      method(:wait_for_stable_bounding_box_if_needed),
      method(:wait_for_enabled_if_needed),
    ]) do |handle, _options|
    handle.click(delay: delay, button: button, click_count: click_count, count: count, offset: offset)
  end
end

#clone(freeze: nil) ⇒ Object



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

def clone(freeze: nil)
  _clone
end

#copy_options(locator) ⇒ Object



138
139
140
141
142
143
144
145
# File 'lib/puppeteer/locators.rb', line 138

def copy_options(locator)
  @timeout = locator.timeout
  @visibility = locator.instance_variable_get(:@visibility)
  @wait_for_enabled = locator.instance_variable_get(:@wait_for_enabled)
  @ensure_element_is_in_viewport = locator.instance_variable_get(:@ensure_element_is_in_viewport)
  @wait_for_stable_bounding_box = locator.instance_variable_get(:@wait_for_stable_bounding_box)
  self
end

#fill(value, typing_threshold: 100) ⇒ Object



218
219
220
221
222
223
224
225
226
227
# File 'lib/puppeteer/locators.rb', line 218

def fill(value, typing_threshold: 100)
  perform_action('Locator.fill',
    conditions: [
      method(:ensure_element_is_in_viewport_if_needed),
      method(:wait_for_stable_bounding_box_if_needed),
      method(:wait_for_enabled_if_needed),
    ]) do |handle, _options|
    fill_element(handle, value, typing_threshold: typing_threshold)
  end
end

#filter(predicate) ⇒ Object



179
180
181
182
183
184
# File 'lib/puppeteer/locators.rb', line 179

def filter(predicate)
  Puppeteer::FilteredLocator.new(_clone, lambda { |handle, options|
    handle.frame.wait_for_function(predicate, args: [handle], timeout: @timeout)
    true
  })
end

#filter_handle(predicate) ⇒ Object



188
189
190
# File 'lib/puppeteer/locators.rb', line 188

def filter_handle(predicate)
  Puppeteer::FilteredLocator.new(_clone, predicate)
end

#hoverObject



230
231
232
233
234
235
236
237
238
# File 'lib/puppeteer/locators.rb', line 230

def hover
  perform_action('Locator.hover',
    conditions: [
      method(:ensure_element_is_in_viewport_if_needed),
      method(:wait_for_stable_bounding_box_if_needed),
    ]) do |handle, _options|
    handle.hover
  end
end

#map(mapper) ⇒ Object



171
172
173
174
175
# File 'lib/puppeteer/locators.rb', line 171

def map(mapper)
  Puppeteer::MappedLocator.new(_clone, lambda { |handle, _options|
    handle.evaluate_handle(mapper)
  })
end

#map_handle(mapper) ⇒ Object



194
195
196
# File 'lib/puppeteer/locators.rb', line 194

def map_handle(mapper)
  Puppeteer::MappedLocator.new(_clone, mapper)
end

#on(event_name, &block) ⇒ Object



266
267
268
269
# File 'lib/puppeteer/locators.rb', line 266

def on(event_name, &block)
  add_event_listener(event_name, &block)
  self
end

#once(event_name, &block) ⇒ Object



274
275
276
277
# File 'lib/puppeteer/locators.rb', line 274

def once(event_name, &block)
  observe_first(event_name, &block)
  self
end

#scroll(scroll_top: nil, scroll_left: nil) ⇒ Object



243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
# File 'lib/puppeteer/locators.rb', line 243

def scroll(scroll_top: nil, scroll_left: nil)
  perform_action('Locator.scroll',
    conditions: [
      method(:ensure_element_is_in_viewport_if_needed),
      method(:wait_for_stable_bounding_box_if_needed),
    ]) do |handle, _options|
    js = <<~JAVASCRIPT
      (el, scrollTop, scrollLeft) => {
        if (scrollTop !== undefined && scrollTop !== null) {
          el.scrollTop = scrollTop;
        }
        if (scrollLeft !== undefined && scrollLeft !== null) {
          el.scrollLeft = scrollLeft;
        }
      }
    JAVASCRIPT
    handle.evaluate(js, scroll_top, scroll_left)
  end
end

#set_ensure_element_is_in_the_viewport(value) ⇒ Object



122
123
124
125
126
# File 'lib/puppeteer/locators.rb', line 122

def set_ensure_element_is_in_the_viewport(value)
  locator = _clone
  locator.instance_variable_set(:@ensure_element_is_in_viewport, value)
  locator
end

#set_timeout(timeout) ⇒ Object



98
99
100
101
102
# File 'lib/puppeteer/locators.rb', line 98

def set_timeout(timeout)
  locator = _clone
  locator.instance_variable_set(:@timeout, timeout)
  locator
end

#set_visibility(visibility) ⇒ Object



106
107
108
109
110
# File 'lib/puppeteer/locators.rb', line 106

def set_visibility(visibility)
  locator = _clone
  locator.instance_variable_set(:@visibility, visibility&.to_s)
  locator
end

#set_wait_for_enabled(value) ⇒ Object



114
115
116
117
118
# File 'lib/puppeteer/locators.rb', line 114

def set_wait_for_enabled(value)
  locator = _clone
  locator.instance_variable_set(:@wait_for_enabled, value)
  locator
end

#set_wait_for_stable_bounding_box(value) ⇒ Object



130
131
132
133
134
# File 'lib/puppeteer/locators.rb', line 130

def set_wait_for_stable_bounding_box(value)
  locator = _clone
  locator.instance_variable_set(:@wait_for_stable_bounding_box, value)
  locator
end

#timeoutObject



92
93
94
# File 'lib/puppeteer/locators.rb', line 92

def timeout
  @timeout
end

#waitObject



160
161
162
163
164
165
166
167
# File 'lib/puppeteer/locators.rb', line 160

def wait
  handle = wait_handle
  begin
    handle.json_value
  ensure
    handle.dispose
  end
end

#wait_handleObject



153
154
155
156
157
# File 'lib/puppeteer/locators.rb', line 153

def wait_handle
  with_retry('Locator.waitHandle') do |options|
    _wait(options)
  end
end