apparition 0.1.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +40 -4
  3. data/lib/capybara/apparition.rb +0 -2
  4. data/lib/capybara/apparition/browser.rb +75 -133
  5. data/lib/capybara/apparition/browser/cookie.rb +4 -16
  6. data/lib/capybara/apparition/browser/header.rb +2 -2
  7. data/lib/capybara/apparition/browser/launcher.rb +25 -0
  8. data/lib/capybara/apparition/browser/launcher/local.rb +213 -0
  9. data/lib/capybara/apparition/browser/launcher/remote.rb +55 -0
  10. data/lib/capybara/apparition/browser/page_manager.rb +90 -0
  11. data/lib/capybara/apparition/browser/window.rb +29 -29
  12. data/lib/capybara/apparition/configuration.rb +100 -0
  13. data/lib/capybara/apparition/console.rb +8 -1
  14. data/lib/capybara/apparition/dev_tools_protocol/remote_object.rb +23 -7
  15. data/lib/capybara/apparition/dev_tools_protocol/session.rb +3 -4
  16. data/lib/capybara/apparition/driver.rb +107 -35
  17. data/lib/capybara/apparition/driver/chrome_client.rb +13 -8
  18. data/lib/capybara/apparition/driver/response.rb +1 -1
  19. data/lib/capybara/apparition/driver/web_socket_client.rb +1 -0
  20. data/lib/capybara/apparition/errors.rb +3 -3
  21. data/lib/capybara/apparition/network_traffic/error.rb +1 -0
  22. data/lib/capybara/apparition/network_traffic/request.rb +5 -5
  23. data/lib/capybara/apparition/node.rb +142 -50
  24. data/lib/capybara/apparition/node/drag.rb +165 -65
  25. data/lib/capybara/apparition/page.rb +180 -142
  26. data/lib/capybara/apparition/page/frame.rb +3 -0
  27. data/lib/capybara/apparition/page/frame_manager.rb +2 -1
  28. data/lib/capybara/apparition/page/keyboard.rb +29 -7
  29. data/lib/capybara/apparition/page/mouse.rb +20 -6
  30. data/lib/capybara/apparition/utility.rb +1 -1
  31. data/lib/capybara/apparition/version.rb +1 -1
  32. metadata +53 -23
  33. data/lib/capybara/apparition/dev_tools_protocol/target.rb +0 -64
  34. data/lib/capybara/apparition/dev_tools_protocol/target_manager.rb +0 -48
  35. data/lib/capybara/apparition/driver/launcher.rb +0 -217
@@ -47,10 +47,12 @@ module Capybara::Apparition
47
47
  end
48
48
 
49
49
  def loading(id)
50
+ puts "Setting loading to #{id}" if ENV['DEBUG']
50
51
  self.loader_id = id
51
52
  end
52
53
 
53
54
  def reloading!
55
+ puts 'Reloading' if ENV['DEBUG']
54
56
  self.loader_id = @prev_loader_id
55
57
  end
56
58
 
@@ -64,6 +66,7 @@ module Capybara::Apparition
64
66
 
65
67
  def loaded!
66
68
  @prev_loader_id = loader_id
69
+ puts "Setting loaded - was #{loader_id}" if ENV['DEBUG']
67
70
  self.loader_id = nil
68
71
  end
69
72
 
@@ -7,7 +7,7 @@ module Capybara::Apparition
7
7
  def initialize(id)
8
8
  @frames = {}
9
9
  @frames_mutex = Mutex.new
10
- add(id)
10
+ add(id).loading(-1)
11
11
  @main_id = @current_id = id
12
12
  end
13
13
 
@@ -43,6 +43,7 @@ module Capybara::Apparition
43
43
  @frames[id]
44
44
  end
45
45
  end
46
+ alias :[] :get
46
47
 
47
48
  def delete(id)
48
49
  @frames_mutex.synchronize do
@@ -66,16 +66,30 @@ module Capybara::Apparition
66
66
 
67
67
  private
68
68
 
69
+ def insert_emoji(str)
70
+ @page.command('Input.insertText', text: str)
71
+ end
72
+
69
73
  def type_with_modifiers(keys, delay:)
70
74
  old_pressed_keys, @pressed_keys = @pressed_keys, {}
71
75
 
72
76
  Array(keys).each do |sequence|
73
77
  case sequence
74
- when Array then type_with_modifiers(sequence, delay: delay)
75
- when String then sequence.each_char do |char|
76
- press char
77
- sleep delay
78
- end
78
+ when Array
79
+ type_with_modifiers(sequence, delay: delay)
80
+ when String
81
+ clusters = sequence.grapheme_clusters.chunk { |gc| gc.match?(/\p{Emoji Presentation}/) }
82
+ clusters.each do |emoji, chars|
83
+ if emoji
84
+ insert_emoji(chars.join)
85
+ sleep delay
86
+ else
87
+ chars.each do |char|
88
+ press char
89
+ sleep delay
90
+ end
91
+ end
92
+ end
79
93
  else
80
94
  press sequence
81
95
  sleep delay
@@ -89,7 +103,7 @@ module Capybara::Apparition
89
103
  end
90
104
 
91
105
  def release_pressed_keys
92
- @pressed_keys.values.each { |desc| up(desc) }
106
+ @pressed_keys.each_value { |desc| up(desc) }
93
107
  end
94
108
 
95
109
  def key_description(key)
@@ -102,8 +116,15 @@ module Capybara::Apparition
102
116
  location: 0
103
117
  )
104
118
 
119
+ if key.to_sym == :return
120
+ warn '[DEPRECATION]: Key symbol :return is deprecated in favor of :enter'
121
+ key = :enter
122
+ end
123
+
105
124
  definition = KEY_DEFINITIONS[key.to_sym]
106
- raise KeyError, "Unknown key: #{key}" if definition.nil?
125
+ raise KeyError, "Unknown key: #{key}" if definition.nil? && !key.is_a?(String)
126
+
127
+ definition ||= { text: key }
107
128
 
108
129
  definition = OpenStruct.new definition
109
130
 
@@ -321,6 +342,7 @@ module Capybara::Apparition
321
342
  'z': { 'keyCode': 90, 'code': 'KeyZ', 'shiftKey': 'Z', 'key': 'z' },
322
343
  'meta': { 'keyCode': 91, 'key': 'Meta', 'code': 'MetaLeft' },
323
344
  'command': { 'keyCode': 91, 'key': 'Meta', 'code': 'MetaLeft' },
345
+ 'cmd': { 'keyCode': 91, 'key': 'Meta', 'code': 'MetaLeft' },
324
346
  '*': { 'keyCode': 106, 'key': '*', 'code': 'NumpadMultiply', 'location': 3 },
325
347
  '+': { 'keyCode': 107, 'key': '+', 'code': 'NumpadAdd', 'location': 3 },
326
348
  '-': { 'keyCode': 109, 'key': '-', 'code': 'NumpadSubtract', 'location': 3 },
@@ -6,15 +6,17 @@ module Capybara::Apparition
6
6
  @page = page
7
7
  @keyboard = keyboard
8
8
  @current_pos = { x: 0, y: 0 }
9
+ @current_buttons = BUTTONS[:none]
9
10
  end
10
11
 
11
- def click_at(x:, y:, button: 'left', count: 1, modifiers: [])
12
+ def click_at(x:, y:, button: 'left', count: 1, delay: 0, modifiers: [])
12
13
  move_to x: x, y: y
13
14
  count.times do |num|
14
15
  @keyboard.with_keys(modifiers) do
15
16
  mouse_params = { x: x, y: y, button: button, count: num + 1 }
16
- down mouse_params
17
- up mouse_params
17
+ down(**mouse_params)
18
+ sleep(delay || 0)
19
+ up(**mouse_params)
18
20
  end
19
21
  end
20
22
  self
@@ -28,13 +30,15 @@ module Capybara::Apparition
28
30
 
29
31
  def down(button: 'left', **options)
30
32
  options = @current_pos.merge(button: button).merge(options)
31
- mouse_event('mousePressed', options)
33
+ mouse_event('mousePressed', **options)
34
+ @current_buttons |= BUTTONS[button.to_sym]
32
35
  self
33
36
  end
34
37
 
35
38
  def up(button: 'left', **options)
36
39
  options = @current_pos.merge(button: button).merge(options)
37
- mouse_event('mouseReleased', options)
40
+ @current_buttons &= ~BUTTONS[button.to_sym]
41
+ mouse_event('mouseReleased', **options)
38
42
  self
39
43
  end
40
44
 
@@ -43,11 +47,21 @@ module Capybara::Apparition
43
47
  def mouse_event(type, x:, y:, button: 'none', count: 1)
44
48
  @page.command('Input.dispatchMouseEvent',
45
49
  type: type,
46
- button: button,
50
+ button: button.to_s,
51
+ buttons: @current_buttons,
47
52
  x: x,
48
53
  y: y,
49
54
  modifiers: @keyboard.modifiers,
50
55
  clickCount: count)
51
56
  end
57
+
58
+ BUTTONS = {
59
+ left: 1,
60
+ right: 2,
61
+ middle: 4,
62
+ back: 8,
63
+ forward: 16,
64
+ none: 0
65
+ }.freeze
52
66
  end
53
67
  end
@@ -4,7 +4,7 @@ module Capybara
4
4
  module Apparition
5
5
  class << self
6
6
  def windows?
7
- RbConfig::CONFIG['host_os'] =~ /mingw|mswin|cygwin/
7
+ RbConfig::CONFIG['host_os'].match?(/mingw|mswin|cygwin/)
8
8
  end
9
9
 
10
10
  def mri?
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Capybara
4
4
  module Apparition
5
- VERSION = '0.1.0'
5
+ VERSION = '0.6.0'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,36 +1,22 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apparition
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas Walpole
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-02-05 00:00:00.000000000 Z
11
+ date: 2020-06-21 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: backports
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '0'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: capybara
29
15
  requirement: !ruby/object:Gem::Requirement
30
16
  requirements:
31
17
  - - "~>"
32
18
  - !ruby/object:Gem::Version
33
- version: '3.12'
19
+ version: '3.13'
34
20
  - - "<"
35
21
  - !ruby/object:Gem::Version
36
22
  version: '4'
@@ -40,7 +26,7 @@ dependencies:
40
26
  requirements:
41
27
  - - "~>"
42
28
  - !ruby/object:Gem::Version
43
- version: '3.12'
29
+ version: '3.13'
44
30
  - - "<"
45
31
  - !ruby/object:Gem::Version
46
32
  version: '4'
@@ -184,6 +170,48 @@ dependencies:
184
170
  - - "~>"
185
171
  - !ruby/object:Gem::Version
186
172
  version: '3.6'
173
+ - !ruby/object:Gem::Dependency
174
+ name: rubocop
175
+ requirement: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - ">="
178
+ - !ruby/object:Gem::Version
179
+ version: '0'
180
+ type: :development
181
+ prerelease: false
182
+ version_requirements: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - ">="
185
+ - !ruby/object:Gem::Version
186
+ version: '0'
187
+ - !ruby/object:Gem::Dependency
188
+ name: rubocop-performance
189
+ requirement: !ruby/object:Gem::Requirement
190
+ requirements:
191
+ - - ">="
192
+ - !ruby/object:Gem::Version
193
+ version: '0'
194
+ type: :development
195
+ prerelease: false
196
+ version_requirements: !ruby/object:Gem::Requirement
197
+ requirements:
198
+ - - ">="
199
+ - !ruby/object:Gem::Version
200
+ version: '0'
201
+ - !ruby/object:Gem::Dependency
202
+ name: rubocop-rspec
203
+ requirement: !ruby/object:Gem::Requirement
204
+ requirements:
205
+ - - ">="
206
+ - !ruby/object:Gem::Version
207
+ version: '0'
208
+ type: :development
209
+ prerelease: false
210
+ version_requirements: !ruby/object:Gem::Requirement
211
+ requirements:
212
+ - - ">="
213
+ - !ruby/object:Gem::Version
214
+ version: '0'
187
215
  - !ruby/object:Gem::Dependency
188
216
  name: selenium-webdriver
189
217
  requirement: !ruby/object:Gem::Requirement
@@ -228,19 +256,21 @@ files:
228
256
  - lib/capybara/apparition/browser/cookie.rb
229
257
  - lib/capybara/apparition/browser/frame.rb
230
258
  - lib/capybara/apparition/browser/header.rb
259
+ - lib/capybara/apparition/browser/launcher.rb
260
+ - lib/capybara/apparition/browser/launcher/local.rb
261
+ - lib/capybara/apparition/browser/launcher/remote.rb
231
262
  - lib/capybara/apparition/browser/modal.rb
263
+ - lib/capybara/apparition/browser/page_manager.rb
232
264
  - lib/capybara/apparition/browser/render.rb
233
265
  - lib/capybara/apparition/browser/window.rb
266
+ - lib/capybara/apparition/configuration.rb
234
267
  - lib/capybara/apparition/console.rb
235
268
  - lib/capybara/apparition/cookie.rb
236
269
  - lib/capybara/apparition/cookie_jar.rb
237
270
  - lib/capybara/apparition/dev_tools_protocol/remote_object.rb
238
271
  - lib/capybara/apparition/dev_tools_protocol/session.rb
239
- - lib/capybara/apparition/dev_tools_protocol/target.rb
240
- - lib/capybara/apparition/dev_tools_protocol/target_manager.rb
241
272
  - lib/capybara/apparition/driver.rb
242
273
  - lib/capybara/apparition/driver/chrome_client.rb
243
- - lib/capybara/apparition/driver/launcher.rb
244
274
  - lib/capybara/apparition/driver/response.rb
245
275
  - lib/capybara/apparition/driver/web_socket_client.rb
246
276
  - lib/capybara/apparition/errors.rb
@@ -270,14 +300,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
270
300
  requirements:
271
301
  - - ">="
272
302
  - !ruby/object:Gem::Version
273
- version: 2.3.0
303
+ version: 2.5.0
274
304
  required_rubygems_version: !ruby/object:Gem::Requirement
275
305
  requirements:
276
306
  - - ">="
277
307
  - !ruby/object:Gem::Version
278
308
  version: '0'
279
309
  requirements: []
280
- rubygems_version: 3.0.1
310
+ rubygems_version: 3.1.2
281
311
  signing_key:
282
312
  specification_version: 4
283
313
  summary: Chrome driver using CDP for Capybara
@@ -1,64 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'capybara/apparition/dev_tools_protocol/session'
4
-
5
- module Capybara::Apparition
6
- module DevToolsProtocol
7
- class Target
8
- def initialize(browser, info)
9
- @browser = browser
10
- @info = info.dup
11
- @page = nil
12
- end
13
-
14
- def info
15
- @info.dup.freeze
16
- end
17
-
18
- def update(new_info)
19
- @info ||= {}
20
- @info.merge!(new_info)
21
- info
22
- end
23
-
24
- def id
25
- @info['targetId']
26
- end
27
-
28
- def context_id
29
- @info['browserContextId']
30
- end
31
-
32
- def title
33
- @info['title']
34
- end
35
-
36
- def url
37
- @info['url']
38
- end
39
-
40
- def page
41
- @page ||= begin
42
- if info['type'] == 'page'
43
- Page.create(@browser, create_session, id,
44
- ignore_https_errors: @browser.ignore_https_errors,
45
- js_errors: @browser.js_errors).inherit(@info.delete('inherit'))
46
- else
47
- nil
48
- end
49
- end
50
- end
51
-
52
- def close
53
- @browser.command('Target.closeTarget', targetId: id)
54
- end
55
-
56
- private
57
-
58
- def create_session
59
- session_id = @browser.command('Target.attachToTarget', targetId: id)['sessionId']
60
- Session.new(@browser, @browser.client, id, session_id)
61
- end
62
- end
63
- end
64
- end
@@ -1,48 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'capybara/apparition/dev_tools_protocol/target'
4
-
5
- module Capybara::Apparition
6
- module DevToolsProtocol
7
- class TargetManager
8
- def initialize(browser)
9
- @browser = browser
10
- @targets = {}
11
- end
12
-
13
- def get(id)
14
- @targets[id]
15
- end
16
-
17
- def of_type(type)
18
- @targets.select { |_id, target| target.info['type'] == type }
19
- end
20
-
21
- def add(id, target)
22
- raise ArgumentError, 'Target already exists' if @targets.key?(id)
23
-
24
- @targets[id] = if target.is_a? DevToolsProtocol::Target
25
- target
26
- else
27
- DevToolsProtocol::Target.new(@browser, target)
28
- end
29
- end
30
-
31
- def delete(id)
32
- @targets.delete(id)
33
- end
34
-
35
- def pages
36
- @targets.values.select { |target| target.info['type'] == 'page' }.map(&:page)
37
- end
38
-
39
- def target?(id)
40
- @targets.key?(id)
41
- end
42
-
43
- def window_handles
44
- @targets.values.select { |target| target.info['type'] == 'page' }.map(&:id).compact
45
- end
46
- end
47
- end
48
- end
@@ -1,217 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Capybara::Apparition
4
- class Browser
5
- class Launcher
6
- KILL_TIMEOUT = 2
7
-
8
- def self.start(*args)
9
- new(*args).tap(&:start)
10
- end
11
-
12
- def self.process_killer(pid)
13
- proc do
14
- begin
15
- if Capybara::Apparition.windows?
16
- ::Process.kill('KILL', pid)
17
- else
18
- ::Process.kill('TERM', pid)
19
- timer = Capybara::Helpers.timer(expire_in: KILL_TIMEOUT)
20
- while ::Process.wait(pid, ::Process::WNOHANG).nil?
21
- sleep 0.05
22
- next unless timer.expired?
23
-
24
- ::Process.kill('KILL', pid)
25
- ::Process.wait(pid)
26
- break
27
- end
28
- end
29
- rescue Errno::ESRCH, Errno::ECHILD # rubocop:disable Lint/HandleExceptions
30
- end
31
- end
32
- end
33
-
34
- def initialize(headless:, **options)
35
- @path = ENV['BROWSER_PATH']
36
- @options = DEFAULT_OPTIONS.merge(options[:browser_options] || {})
37
- if headless
38
- @options.merge!(HEADLESS_OPTIONS)
39
- @options['disable-gpu'] = nil if Capybara::Apparition.windows?
40
- end
41
- @options['user-data-dir'] = Dir.mktmpdir
42
- end
43
-
44
- def start
45
- @output = Queue.new
46
- @read_io, @write_io = IO.pipe
47
-
48
- @out_thread = Thread.new do
49
- while !@read_io.eof? && (data = @read_io.readpartial(512))
50
- @output << data
51
- end
52
- end
53
-
54
- process_options = { in: File::NULL }
55
- process_options[:pgroup] = true unless Capybara::Apparition.windows?
56
- process_options[:out] = process_options[:err] = @write_io if Capybara::Apparition.mri?
57
-
58
- redirect_stdout do
59
- cmd = [path] + @options.map { |k, v| v.nil? ? "--#{k}" : "--#{k}=#{v}" }
60
- @pid = ::Process.spawn(*cmd, process_options)
61
- ObjectSpace.define_finalizer(self, self.class.process_killer(@pid))
62
- end
63
- end
64
-
65
- def stop
66
- return unless @pid
67
-
68
- kill
69
- ObjectSpace.undefine_finalizer(self)
70
- end
71
-
72
- def restart
73
- stop
74
- start
75
- end
76
-
77
- def host
78
- @host ||= ws_url.host
79
- end
80
-
81
- def port
82
- @port ||= ws_url.port
83
- end
84
-
85
- def ws_url
86
- @ws_url ||= begin
87
- regexp = %r{DevTools listening on (ws://.*)}
88
- url = nil
89
- loop do
90
- break if (url = @output.pop.scan(regexp)[0])
91
- end
92
- @out_thread.kill
93
- close_io
94
- Addressable::URI.parse(url[0])
95
- end
96
- end
97
-
98
- private
99
-
100
- def redirect_stdout
101
- if Capybara::Apparition.mri?
102
- yield
103
- else
104
- begin
105
- prev = STDOUT.dup
106
- $stdout = @write_io
107
- STDOUT.reopen(@write_io)
108
- yield
109
- ensure
110
- STDOUT.reopen(prev)
111
- $stdout = STDOUT
112
- prev.close
113
- end
114
- end
115
- end
116
-
117
- def kill
118
- self.class.process_killer(@pid).call
119
- @pid = nil
120
- end
121
-
122
- def close_io
123
- [@write_io, @read_io].each do |io|
124
- begin
125
- io.close unless io.closed?
126
- rescue IOError
127
- raise unless RUBY_ENGINE == 'jruby'
128
- end
129
- end
130
- end
131
-
132
- def path
133
- host_os = RbConfig::CONFIG['host_os']
134
- @path ||= case RbConfig::CONFIG['host_os']
135
- when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
136
- windows_path
137
- when /darwin|mac os/
138
- macosx_path
139
- when /linux|solaris|bsd/
140
- find_first_binary('google-chrome', 'chrome') || '/usr/bin/chrome'
141
- else
142
- raise ArgumentError, "unknown os: #{host_os.inspect}"
143
- end
144
-
145
- raise ArgumentError, 'Unable to find Chrome executeable' unless File.file?(@path.to_s) && File.executable?(@path.to_s)
146
-
147
- @path
148
- end
149
-
150
- def windows_path
151
- raise ArgumentError, 'Not yet Implemented'
152
- end
153
-
154
- def macosx_path
155
- path = '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'
156
- path = File.expand_path("~#{path}") unless File.exist?(path)
157
- path = find_first_binary('Google Chrome') unless File.exist?(path)
158
- path
159
- end
160
-
161
- def find_first_binary(*binaries)
162
- paths = ENV['PATH'].split(File::PATH_SEPARATOR)
163
-
164
- binaries.each do |binary|
165
- paths.each do |path|
166
- full_path = File.join(path, binary)
167
- exe = Dir.glob(full_path).find { |f| File.executable?(f) }
168
- return exe if exe
169
- end
170
- end
171
- end
172
-
173
- # Chromium command line options
174
- # https://peter.sh/experiments/chromium-command-line-switches/
175
- DEFAULT_BOOLEAN_OPTIONS = %w[
176
- disable-background-networking
177
- disable-background-timer-throttling
178
- disable-breakpad
179
- disable-client-side-phishing-detection
180
- disable-default-apps
181
- disable-dev-shm-usage
182
- disable-extensions
183
- disable-features=site-per-process
184
- disable-hang-monitor
185
- disable-infobars
186
- disable-popup-blocking
187
- disable-prompt-on-repost
188
- disable-sync
189
- disable-translate
190
- metrics-recording-only
191
- no-first-run
192
- safebrowsing-disable-auto-update
193
- enable-automation
194
- password-store=basic
195
- use-mock-keychain
196
- keep-alive-for-test
197
- ].freeze
198
- # Note: --no-sandbox is not needed if you properly setup a user in the container.
199
- # https://github.com/ebidel/lighthouse-ci/blob/master/builder/Dockerfile#L35-L40
200
- # no-sandbox
201
- # disable-web-security
202
- DEFAULT_VALUE_OPTIONS = {
203
- 'window-size' => '1024,768',
204
- 'homepage' => 'about:blank',
205
- 'remote-debugging-address' => '127.0.0.1'
206
- }.freeze
207
- DEFAULT_OPTIONS = DEFAULT_BOOLEAN_OPTIONS.each_with_object({}) { |opt, hsh| hsh[opt] = nil }
208
- .merge(DEFAULT_VALUE_OPTIONS)
209
- .freeze
210
- HEADLESS_OPTIONS = {
211
- 'headless' => nil,
212
- 'hide-scrollbars' => nil,
213
- 'mute-audio' => nil
214
- }.freeze
215
- end
216
- end
217
- end