Class: Capybara::Cuprite::Driver

Inherits:
Driver::Base
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/capybara/cuprite/driver.rb

Constant Summary collapse

DEFAULT_MAXIMIZE_SCREEN_SIZE =
[1366, 768].freeze
EXTENSION =
File.expand_path("javascripts/index.js", __dir__)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app, options = {}) ⇒ Driver

Returns a new instance of Driver.



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/capybara/cuprite/driver.rb', line 26

def initialize(app, options = {})
  @app     = app
  @options = options.dup
  @started = false

  @options[:extensions] ||= []
  @options[:extensions] << EXTENSION

  @screen_size = @options.delete(:screen_size)
  @screen_size ||= DEFAULT_MAXIMIZE_SCREEN_SIZE
  @options[:save_path] ||= File.expand_path(Capybara.save_path) if Capybara.save_path

  # It's set for debug() to make devtools tab open correctly.
  @options[:browser_options] ||= {}
  unless @options[:browser_options][:"remote-allow-origins"]
    @options[:browser_options].merge!("remote-allow-origins": "*")
  end

  super()
end

Instance Attribute Details

#appObject (readonly)

Returns the value of attribute app.



24
25
26
# File 'lib/capybara/cuprite/driver.rb', line 24

def app
  @app
end

#optionsObject (readonly)

Returns the value of attribute options.



24
25
26
# File 'lib/capybara/cuprite/driver.rb', line 24

def options
  @options
end

#paper_size=(value) ⇒ Object (writeonly)

Sets the attribute paper_size

Parameters:

  • value

    the value to set the attribute paper_size to.



165
166
167
# File 'lib/capybara/cuprite/driver.rb', line 165

def paper_size=(value)
  @paper_size = value
end

#screen_sizeObject (readonly)

Returns the value of attribute screen_size.



24
25
26
# File 'lib/capybara/cuprite/driver.rb', line 24

def screen_size
  @screen_size
end

Instance Method Details

#accept_modal(type, options = {}) ⇒ Object



352
353
354
355
356
357
358
359
360
361
362
363
# File 'lib/capybara/cuprite/driver.rb', line 352

def accept_modal(type, options = {})
  case type
  when :alert, :confirm
    browser.accept_confirm
  when :prompt
    browser.accept_prompt(options[:with])
  end

  yield if block_given?

  browser.find_modal(options)
end

#active_elementObject



72
73
74
# File 'lib/capybara/cuprite/driver.rb', line 72

def active_element
  Node.new(self, browser.active_element)
end

#add_header(name, value, permanent: true) ⇒ Object



232
233
234
# File 'lib/capybara/cuprite/driver.rb', line 232

def add_header(name, value, permanent: true)
  browser.headers.add({ name => value }, permanent: permanent)
end

#add_headers(headers) ⇒ Object



228
229
230
# File 'lib/capybara/cuprite/driver.rb', line 228

def add_headers(headers)
  browser.headers.add(headers)
end

#basic_authorize(user, password) ⇒ Object Also known as: authorize



269
270
271
272
273
# File 'lib/capybara/cuprite/driver.rb', line 269

def basic_authorize(user, password)
  browser.network.authorize(user: user, password: password) do |request, _index, _total|
    request.continue
  end
end

#browserObject



51
52
53
# File 'lib/capybara/cuprite/driver.rb', line 51

def browser
  @browser ||= Browser.new(@options)
end

#clear_cookiesObject



257
258
259
# File 'lib/capybara/cuprite/driver.rb', line 257

def clear_cookies
  browser.cookies.clear
end

#clear_memory_cacheObject



265
266
267
# File 'lib/capybara/cuprite/driver.rb', line 265

def clear_memory_cache
  browser.network.clear(:cache)
end

#clear_network_trafficObject



212
213
214
# File 'lib/capybara/cuprite/driver.rb', line 212

def clear_network_traffic
  browser.network.clear(:traffic)
end

#click(x, y) ⇒ Object



88
89
90
# File 'lib/capybara/cuprite/driver.rb', line 88

def click(x, y)
  browser.mouse.click(x: x, y: y)
end

#cookiesObject



240
241
242
# File 'lib/capybara/cuprite/driver.rb', line 240

def cookies
  browser.cookies.all
end

#debug(binding = nil) ⇒ Object



285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
# File 'lib/capybara/cuprite/driver.rb', line 285

def debug(binding = nil)
  if @options[:inspector]
    Process.spawn(browser.process.path, debug_url)

    if binding.respond_to?(:pry)
      Pry.start(binding)
    elsif binding.respond_to?(:irb)
      binding.irb
    else
      pause
    end
  else
    raise Error, "To use the remote debugging, you have to launch " \
                 "the driver with `inspector: ENV['INSPECTOR']` " \
                 "configuration option and run your test suite passing " \
                 "env variable"
  end
end

#debug_urlObject



276
277
278
279
280
281
282
283
# File 'lib/capybara/cuprite/driver.rb', line 276

def debug_url
  response = JSON.parse(Net::HTTP.get(URI(build_remote_debug_url(path: "/json"))))

  devtools_frontend_path = response[0]&.[]("devtoolsFrontendUrl")
  raise "Could not generate debug url for remote debugging session" unless devtools_frontend_path

  build_remote_debug_url(path: devtools_frontend_path)
end

#dismiss_modal(type, options = {}) ⇒ Object



365
366
367
368
369
370
371
372
373
374
375
376
# File 'lib/capybara/cuprite/driver.rb', line 365

def dismiss_modal(type, options = {})
  case type
  when :confirm
    browser.dismiss_confirm
  when :prompt
    browser.dismiss_prompt
  end

  yield if block_given?

  browser.find_modal(options)
end

#evaluate_async_script(script, *args) ⇒ Object



97
98
99
100
# File 'lib/capybara/cuprite/driver.rb', line 97

def evaluate_async_script(script, *args)
  result = browser.evaluate_async(script, session_wait_time, *native_args(args))
  unwrap_script_result(result)
end

#evaluate_script(script, *args) ⇒ Object



92
93
94
95
# File 'lib/capybara/cuprite/driver.rb', line 92

def evaluate_script(script, *args)
  result = browser.evaluate(script, *native_args(args))
  unwrap_script_result(result)
end

#execute_script(script, *args) ⇒ Object



102
103
104
105
# File 'lib/capybara/cuprite/driver.rb', line 102

def execute_script(script, *args)
  browser.execute(script, *native_args(args))
  nil
end

#find(method, selector) ⇒ Object



84
85
86
# File 'lib/capybara/cuprite/driver.rb', line 84

def find(method, selector)
  browser.find(method, selector).map { |native| Node.new(self, native) }
end

#find_css(selector) ⇒ Object



80
81
82
# File 'lib/capybara/cuprite/driver.rb', line 80

def find_css(selector)
  find(:css, selector)
end

#find_xpath(selector) ⇒ Object



76
77
78
# File 'lib/capybara/cuprite/driver.rb', line 76

def find_xpath(selector)
  find(:xpath, selector)
end

#frame_titleObject



68
69
70
# File 'lib/capybara/cuprite/driver.rb', line 68

def frame_title
  evaluate_script("document.title")
end

#frame_urlObject



60
61
62
# File 'lib/capybara/cuprite/driver.rb', line 60

def frame_url
  evaluate_script("window.location.href")
end

#fullscreen_window(handle) ⇒ Object



188
189
190
191
192
# File 'lib/capybara/cuprite/driver.rb', line 188

def fullscreen_window(handle)
  within_window(handle) do
    browser.resize(fullscreen: true)
  end
end

#headersObject



220
221
222
# File 'lib/capybara/cuprite/driver.rb', line 220

def headers
  browser.headers.get
end

#headers=(headers) ⇒ Object



224
225
226
# File 'lib/capybara/cuprite/driver.rb', line 224

def headers=(headers)
  browser.headers.set(headers)
end

#invalid_element_errorsObject



344
345
346
347
348
349
350
# File 'lib/capybara/cuprite/driver.rb', line 344

def invalid_element_errors
  [Capybara::Cuprite::ObsoleteNode,
   Capybara::Cuprite::MouseEventFailed,
   Ferrum::CoordinatesNotFoundError,
   Ferrum::NoExecutionContextError,
   Ferrum::NodeNotFoundError]
end

#maximize_window(handle) ⇒ Object



178
179
180
# File 'lib/capybara/cuprite/driver.rb', line 178

def maximize_window(handle)
  resize_window_to(handle, *screen_size)
end

#needs_server?Boolean

Returns:

  • (Boolean)


47
48
49
# File 'lib/capybara/cuprite/driver.rb', line 47

def needs_server?
  true
end

#network_traffic(type = nil) ⇒ Object



198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'lib/capybara/cuprite/driver.rb', line 198

def network_traffic(type = nil)
  traffic = browser.network.traffic

  case type.to_s
  when "all"
    traffic
  when "blocked"
    traffic.select(&:blocked?)
  else
    # when request isn't blocked
    traffic.reject(&:blocked?)
  end
end

#no_such_window_errorObject



125
126
127
# File 'lib/capybara/cuprite/driver.rb', line 125

def no_such_window_error
  Ferrum::NoSuchPageError
end

#open_new_windowObject



118
119
120
121
122
123
# File 'lib/capybara/cuprite/driver.rb', line 118

def open_new_window
  target = browser.default_context.create_target
  target.maybe_sleep_if_new_window
  target.page = Page.new(target.client, context_id: target.context_id, target_id: target.id)
  target.page
end

#pauseObject



304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
# File 'lib/capybara/cuprite/driver.rb', line 304

def pause
  # STDIN is not necessarily connected to a keyboard. It might even be closed.
  # So we need a method other than keypress to continue.

  # In jRuby - STDIN returns immediately from select
  # see https://github.com/jruby/jruby/issues/1783
  read, write = IO.pipe
  thread = Thread.new do
    IO.copy_stream($stdin, write)
    write.close
  end

  warn "Cuprite execution paused. Press enter (or run 'kill -CONT #{Process.pid}') to continue."

  signal = false
  old_trap = trap("SIGCONT") do
    signal = true
    warn "\nSignal SIGCONT received"
  end
  keyboard = read.wait_readable(1) until keyboard || signal # wait for data on STDIN or signal SIGCONT received

  unless signal
    begin
      input = read.read_nonblock(80) # clear out the read buffer
      puts unless input&.end_with?("\n")
    rescue EOFError, IO::WaitReadable
      # Ignore problems reading from STDIN.
    end
  end
ensure
  thread.kill
  read.close
  trap("SIGCONT", old_trap) # Restore the previous signal handler, if there was one.
  warn "Continuing"
end


252
253
254
255
# File 'lib/capybara/cuprite/driver.rb', line 252

def remove_cookie(name, **options)
  options[:domain] = default_domain if options.empty?
  browser.cookies.remove(**options.merge(name: name))
end

#render_base64(format = :png, options = {}) ⇒ Object



151
152
153
154
155
156
157
158
159
# File 'lib/capybara/cuprite/driver.rb', line 151

def render_base64(format = :png, options = {})
  if pdf?(nil, options)
    options[:paperWidth] = @paper_size[:width].to_f if @paper_size
    options[:paperHeight] = @paper_size[:height].to_f if @paper_size
    browser.pdf(encoding: :base64, **options)
  else
    browser.screenshot(format: format, encoding: :base64, **options)
  end
end

#reset!Object



129
130
131
132
133
134
135
136
# File 'lib/capybara/cuprite/driver.rb', line 129

def reset!
  @zoom_factor = nil
  @paper_size = nil
  browser.url_blacklist = @options[:url_blacklist]
  browser.url_whitelist = @options[:url_whitelist]
  browser.reset
  @started = false
end

#resize(width, height) ⇒ Object Also known as: resize_window



167
168
169
# File 'lib/capybara/cuprite/driver.rb', line 167

def resize(width, height)
  browser.resize(width: width, height: height)
end

#resize_window_to(handle, width, height) ⇒ Object



172
173
174
175
176
# File 'lib/capybara/cuprite/driver.rb', line 172

def resize_window_to(handle, width, height)
  within_window(handle) do
    resize(width, height)
  end
end

#response_headersObject



236
237
238
# File 'lib/capybara/cuprite/driver.rb', line 236

def response_headers
  browser.network.response&.headers
end

#save_screenshot(path, options = {}) ⇒ Object Also known as: render



138
139
140
141
142
143
144
145
146
147
148
# File 'lib/capybara/cuprite/driver.rb', line 138

def save_screenshot(path, options = {})
  options[:scale] = @zoom_factor if @zoom_factor

  if pdf?(path, options)
    options[:paperWidth] = @paper_size[:width].to_f if @paper_size
    options[:paperHeight] = @paper_size[:height].to_f if @paper_size
    browser.pdf(path: path, **options)
  else
    browser.screenshot(path: path, **options)
  end
end

#scroll_to(left, top) ⇒ Object



194
195
196
# File 'lib/capybara/cuprite/driver.rb', line 194

def scroll_to(left, top)
  browser.mouse.scroll_to(left, top)
end


244
245
246
247
248
249
250
# File 'lib/capybara/cuprite/driver.rb', line 244

def set_cookie(name, value, options = {})
  options = options.dup
  options[:name]   ||= name
  options[:value]  ||= value
  options[:domain] ||= default_domain
  browser.cookies.set(**options)
end

#set_proxy(host, port, user = nil, password = nil, bypass = nil) ⇒ Object



216
217
218
# File 'lib/capybara/cuprite/driver.rb', line 216

def set_proxy(host, port, user = nil, password = nil, bypass = nil)
  @options.merge!(proxy: { host: host, port: port, user: user, password: password, bypass: bypass })
end

#sourceObject



64
65
66
# File 'lib/capybara/cuprite/driver.rb', line 64

def source
  browser.source.to_s
end

#switch_to_frame(locator) ⇒ Object



107
108
109
110
111
112
113
114
115
116
# File 'lib/capybara/cuprite/driver.rb', line 107

def switch_to_frame(locator)
  handle = case locator
           when Capybara::Node::Element
             locator.native.description["frameId"]
           when :parent, :top
             locator
           end

  browser.switch_to_frame(handle)
end

#visit(url) ⇒ Object



55
56
57
58
# File 'lib/capybara/cuprite/driver.rb', line 55

def visit(url)
  @started = true
  browser.visit(url)
end

#wait?Boolean

Returns:

  • (Boolean)


340
341
342
# File 'lib/capybara/cuprite/driver.rb', line 340

def wait?
  true
end

#wait_for_network_idle(**options) ⇒ Object



261
262
263
# File 'lib/capybara/cuprite/driver.rb', line 261

def wait_for_network_idle(**options)
  browser.network.wait_for_idle(**options)
end

#window_size(handle) ⇒ Object



182
183
184
185
186
# File 'lib/capybara/cuprite/driver.rb', line 182

def window_size(handle)
  within_window(handle) do
    evaluate_script("[window.innerWidth, window.innerHeight]")
  end
end

#zoom_factor=(value) ⇒ Object



161
162
163
# File 'lib/capybara/cuprite/driver.rb', line 161

def zoom_factor=(value)
  @zoom_factor = value.to_f
end