puppeteer-ruby 0.0.18 → 0.0.19

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 63cde4d139f1dc95710efb059310822219b905ef4b44ec8a1347b4bdc97a6b2e
4
- data.tar.gz: '0989de5d246bb1c2bcb5ab625eb0702f608ec6ec667db9bbcf4282cf419314fa'
3
+ metadata.gz: 6e6a29713aa4dd143bdd6c4fd1cc84df1bd7037aa920b0d660a62267f6321515
4
+ data.tar.gz: 46a433d484dfabd019cc0874b8dd6c17182e374fb53d6f6905fde7c1d120d5e6
5
5
  SHA512:
6
- metadata.gz: 96aaf3dc540e160dd983660f2ea4fa10a8c3a2126e9c56f57f9c7a11c31c956376f556473c2d6c591b4cf4253c92e91055cc564e1910fe6dbaf3eb8244d2e852
7
- data.tar.gz: c2195746ce0ed09fb2be8e66cb842cc2fb9487c51cb2232e51f3970df0234aec97fce173627bbedd1c4d113cd82154c134a69d0f9eb02c23826ab0bc0ad7ee18
6
+ metadata.gz: 9c5796c2331a9218c1191e1c2869aa5b02c6affdd19f5af23324ee1b257e93d3f328688b19ac14b4060f050c3649a82f6074f0a2b5d66c4bb71f34f46d51557a
7
+ data.tar.gz: 70bfa15d8c788ab11dbf8cf240a3967a906a15777294b1f8be2be22a64d5f2123a3c4bf44226c35c58bed0614a9b7703d6db498ce283309aa36bb30c5587cea6
@@ -5,7 +5,7 @@ orbs:
5
5
  jobs:
6
6
  rspec:
7
7
  docker:
8
- - image: circleci/ruby:2.6.3-stretch-node-browsers
8
+ - image: circleci/ruby:2.6.6-buster-node-browsers
9
9
  executor: ruby/default
10
10
  steps:
11
11
  - checkout
@@ -18,6 +18,28 @@ jobs:
18
18
  --out test_results/rspec.xml \
19
19
  --format documentation
20
20
 
21
+ rspec_firefox:
22
+ docker:
23
+ - image: circleci/ruby:2.6.6-buster-node-browsers
24
+ executor: ruby/default
25
+ steps:
26
+ - checkout
27
+ - ruby/bundle-install
28
+ - run:
29
+ name: install firefox-nightly
30
+ command: |
31
+ wget -O nightly.tar.bz2 "https://download.mozilla.org/?product=firefox-nightly-latest-ssl&os=linux64&lang=en-US"
32
+ tar xf nightly.tar.bz2
33
+ - run:
34
+ name: rspec
35
+ command: |
36
+ DEBUG=1 PUPPETEER_PRODUCT_RSPEC=firefox \
37
+ PUPPETEER_EXECUTABLE_PATH_RSPEC=${CIRCLE_WORKING_DIRECTORY/#\~/$HOME}/firefox/firefox \
38
+ bundle exec rspec --profile 10 \
39
+ --format RspecJunitFormatter \
40
+ --out test_results/rspec.xml \
41
+ --format documentation spec/integration/
42
+
21
43
  deploy:
22
44
  docker:
23
45
  - image: circleci/ruby:2.6.3-stretch-node
@@ -49,6 +71,7 @@ workflows:
49
71
  ci:
50
72
  jobs:
51
73
  - rspec
74
+ - rspec_firefox
52
75
  rubygems-deploy:
53
76
  jobs:
54
77
  - deploy:
@@ -12,4 +12,4 @@ jobs:
12
12
  with:
13
13
  github_token: ${{ secrets.github_token }}
14
14
  reporter: github-pr-review
15
- rubocop_version: 0.86.0
15
+ rubocop_version: 0.90.0
@@ -35,6 +35,9 @@ Layout/EndAlignment:
35
35
  Layout/EmptyLineAfterMagicComment:
36
36
  Enabled: true
37
37
 
38
+ Layout/EmptyLineAfterMultilineCondition:
39
+ Enabled: true
40
+
38
41
  Layout/EmptyLinesAroundAccessModifier:
39
42
  Enabled: true
40
43
  EnforcedStyle: only_before
@@ -102,6 +105,10 @@ Layout/SpaceBeforeComment:
102
105
  Layout/SpaceBeforeFirstArg:
103
106
  Enabled: true
104
107
 
108
+ Style/ClassMethodsDefinitions:
109
+ Enabled: true
110
+ EnforcedStyle: def_self
111
+
105
112
  Style/DefWithParentheses:
106
113
  Enabled: true
107
114
 
@@ -112,6 +119,12 @@ Style/MethodDefParentheses:
112
119
  Style/RedundantFreeze:
113
120
  Enabled: true
114
121
 
122
+ Style/RedundantSelf:
123
+ Enabled: true
124
+
125
+ Style/RedundantSelfAssignment:
126
+ Enabled: true
127
+
115
128
  # Use `foo {}` not `foo{}`.
116
129
  Layout/SpaceBeforeBlockBraces:
117
130
  Enabled: true
@@ -164,9 +177,6 @@ Lint/EmptyConditionalBody:
164
177
  Lint/FloatComparison:
165
178
  Enabled: true
166
179
 
167
- Lint/MissingSuper:
168
- Enabled: true
169
-
170
180
  Lint/OutOfRangeRegexpRef:
171
181
  Enabled: true
172
182
 
@@ -0,0 +1,9 @@
1
+ FROM circleci/ruby:2.6.6-buster-node-browsers
2
+
3
+ USER root
4
+
5
+ RUN wget -O nightly.tar.bz2 "https://download.mozilla.org/?product=firefox-nightly-latest-ssl&os=linux64&lang=en-US" \
6
+ && tar xf nightly.tar.bz2 \
7
+ && ln -s $(pwd)/firefox/firefox /usr/bin/firefox
8
+
9
+ USER circleci
@@ -0,0 +1,34 @@
1
+ version: "3"
2
+ services:
3
+ chrome:
4
+ tty: true
5
+ stdin_open: true
6
+ build: .
7
+ environment:
8
+ BUNDLE_PATH: /usr/local/bundle
9
+ DEBUG: 1
10
+ CI: 1
11
+ volumes:
12
+ - .:/puppeteer-ruby
13
+ - bundle-data:/usr/local/bundle
14
+ working_dir: /puppeteer-ruby
15
+ command: bundle exec rspec
16
+
17
+ firefox:
18
+ tty: true
19
+ stdin_open: true
20
+ build: .
21
+ environment:
22
+ BUNDLE_PATH: /usr/local/bundle
23
+ PUPPETEER_PRODUCT_RSPEC: firefox
24
+ DEBUG: 1
25
+ CI: 1
26
+ volumes:
27
+ - .:/puppeteer-ruby
28
+ - bundle-data:/usr/local/bundle
29
+ working_dir: /puppeteer-ruby
30
+ command: bundle exec rspec spec/integration/
31
+
32
+ volumes:
33
+ bundle-data:
34
+ driver: local
@@ -53,18 +53,14 @@ require 'puppeteer/element_handle'
53
53
 
54
54
  # ref: https://github.com/puppeteer/puppeteer/blob/master/lib/Puppeteer.js
55
55
  class Puppeteer
56
- class << self
57
- def method_missing(method, *args, **kwargs, &block)
58
- instance.send(method, *args, **kwargs, &block)
59
- end
56
+ def self.method_missing(method, *args, **kwargs, &block)
57
+ @puppeteer ||= Puppeteer.new(
58
+ project_root: __dir__,
59
+ preferred_revision: '706915',
60
+ is_puppeteer_core: true,
61
+ )
60
62
 
61
- def instance
62
- @instance ||= Puppeteer.new(
63
- project_root: __dir__,
64
- preferred_revision: '706915',
65
- is_puppeteer_core: true,
66
- )
67
- end
63
+ @puppeteer.send(method, *args, **kwargs, &block)
68
64
  end
69
65
 
70
66
  # @param project_root [String]
@@ -156,6 +156,6 @@ class Puppeteer::BrowserRunner
156
156
  end
157
157
  end
158
158
  rescue Timeout::Error
159
- raise Puppeteer::TimeoutError.new("Timed out after #{timeout} ms while trying to connect to the browser! Only Chrome at revision r#{preferredRevision} is guaranteed to work.")
159
+ raise Puppeteer::TimeoutError.new("Timed out after #{timeout} ms while trying to connect to the browser! Only Chrome at revision r#{preferred_revision} is guaranteed to work.")
160
160
  end
161
161
  end
@@ -3,7 +3,7 @@ require 'logger'
3
3
  module Puppeteer::DebugPrint
4
4
  if Puppeteer.env.debug?
5
5
  def debug_puts(*args, **kwargs)
6
- @__debug_logger ||= Logger.new(STDOUT)
6
+ @__debug_logger ||= Logger.new($stdout)
7
7
  @__debug_logger.debug(*args, **kwargs)
8
8
  end
9
9
 
@@ -14,7 +14,7 @@ module Puppeteer::DefineAsyncMethod
14
14
  Concurrent::Promises.future do
15
15
  original_method.bind(self).call(*args)
16
16
  rescue => err
17
- Logger.new(STDERR).warn(err)
17
+ Logger.new($stderr).warn(err)
18
18
  raise err
19
19
  end
20
20
  end
@@ -43,7 +43,24 @@ class Puppeteer::ElementHandle < Puppeteer::JSHandle
43
43
  if (element.nodeType !== Node.ELEMENT_NODE)
44
44
  return 'Node is not of type HTMLElement';
45
45
 
46
- element.scrollIntoViewIfNeeded({block: 'center', inline: 'center', behavior: 'instant'});
46
+ if (element.scrollIntoViewIfNeeded) {
47
+ element.scrollIntoViewIfNeeded({block: 'center', inline: 'center', behavior: 'instant'});
48
+ } else {
49
+ // force-scroll if page's javascript is disabled.
50
+ if (!pageJavascriptEnabled) {
51
+ element.scrollIntoView({block: 'center', inline: 'center', behavior: 'instant'});
52
+ return false;
53
+ }
54
+ const visibleRatio = await new Promise(resolve => {
55
+ const observer = new IntersectionObserver(entries => {
56
+ resolve(entries[0].intersectionRatio);
57
+ observer.disconnect();
58
+ });
59
+ observer.observe(element);
60
+ });
61
+ if (visibleRatio !== 1.0)
62
+ element.scrollIntoView({block: 'center', inline: 'center', behavior: 'instant'});
63
+ }
47
64
  return false;
48
65
  }
49
66
  JAVASCRIPT
@@ -9,6 +9,11 @@ class Puppeteer::Env
9
9
  def ci?
10
10
  ['1', 'true'].include?(ENV['CI'].to_s)
11
11
  end
12
+
13
+ # check if running on macOS
14
+ def darwin?
15
+ RUBY_PLATFORM.include?('darwin')
16
+ end
12
17
  end
13
18
 
14
19
  class Puppeteer
@@ -2,6 +2,7 @@ require_relative './launcher/base'
2
2
  require_relative './launcher/browser_options'
3
3
  require_relative './launcher/chrome'
4
4
  require_relative './launcher/chrome_arg_options'
5
+ require_relative './launcher/firefox'
5
6
  require_relative './launcher/launch_options'
6
7
 
7
8
  # https://github.com/puppeteer/puppeteer/blob/main/src/node/Launcher.ts
@@ -9,10 +10,19 @@ module Puppeteer::Launcher
9
10
  # @param project_root [String]
10
11
  # @param prefereed_revision [String]
11
12
  # @param is_puppeteer_core [String]
12
- # @param product [String] 'chrome' or 'firefox' (not implemented yet)
13
+ # @param product [String] 'chrome' or 'firefox'
13
14
  # @return [Puppeteer::Launcher::Chrome]
14
15
  module_function def new(project_root:, preferred_revision:, is_puppeteer_core:, product:)
16
+ unless is_puppeteer_core
17
+ product ||= ENV['PUPPETEER_PRODUCT']
18
+ end
19
+
15
20
  if product == 'firefox'
21
+ return Firefox.new(
22
+ project_root: project_root,
23
+ preferred_revision: preferred_revision,
24
+ is_puppeteer_core: is_puppeteer_core,
25
+ )
16
26
  raise NotImplementedError.new('FirefoxLauncher is not implemented yet.')
17
27
  end
18
28
 
@@ -20,15 +20,25 @@ module Puppeteer::Launcher
20
20
  return executable_path
21
21
  end
22
22
  raise ExecutablePathNotFound.new(
23
- "Tried to use PUPPETEER_EXECUTABLE_PATH env variable to launch browser but did not find any executable at: #{executablePath}",
23
+ "Tried to use PUPPETEER_EXECUTABLE_PATH env variable to launch browser but did not find any executable at: #{executable_path}",
24
24
  )
25
25
  end
26
26
 
27
27
  # temporal logic.
28
- if RUBY_PLATFORM.include?('darwin') # MacOS
29
- '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'
28
+ if Puppeteer.env.darwin?
29
+ case self
30
+ when Chrome
31
+ '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'
32
+ when Firefox
33
+ '/Applications/Firefox Nightly.app/Contents/MacOS/firefox'
34
+ end
30
35
  else
31
- '/usr/bin/google-chrome'
36
+ case self
37
+ when Chrome
38
+ '/usr/bin/google-chrome'
39
+ when Firefox
40
+ '/usr/bin/firefox'
41
+ end
32
42
  end
33
43
 
34
44
  # const browserFetcher = new BrowserFetcher(launcher._projectRoot);
@@ -34,7 +34,7 @@ module Puppeteer::Launcher
34
34
 
35
35
  temporary_user_data_dir = nil
36
36
  if chrome_arguments.none? { |arg| arg.start_with?('--user-data-dir') }
37
- temporary_user_data_dir = Dir.mktmpdir('puppeteer_dev_profile-')
37
+ temporary_user_data_dir = Dir.mktmpdir('puppeteer_dev_chrome_profile-')
38
38
  chrome_arguments << "--user-data-dir=#{temporary_user_data_dir}"
39
39
  end
40
40
 
@@ -0,0 +1,392 @@
1
+ require 'tmpdir'
2
+
3
+ # https://github.com/puppeteer/puppeteer/blob/main/src/node/Launcher.ts
4
+ module Puppeteer::Launcher
5
+ class Firefox < Base
6
+ # @param {!(Launcher.LaunchOptions & Launcher.ChromeArgOptions & Launcher.BrowserOptions)=} options
7
+ # @return {!Promise<!Browser>}
8
+ def launch(options = {})
9
+ @chrome_arg_options = ChromeArgOptions.new(options)
10
+ @launch_options = LaunchOptions.new(options)
11
+ @browser_options = BrowserOptions.new(options)
12
+
13
+ firefox_arguments =
14
+ if !@launch_options.ignore_default_args
15
+ default_args.to_a
16
+ elsif @launch_options.ignore_default_args.is_a?(Enumerable)
17
+ default_args.reject do |arg|
18
+ @launch_options.ignore_default_args.include?(arg)
19
+ end.to_a
20
+ else
21
+ @chrome_arg_options.args.dup
22
+ end
23
+
24
+ if firefox_arguments.none? { |arg| arg.start_with?('--remote-debugging-') }
25
+ firefox_arguments << '--remote-debugging-port=0'
26
+ end
27
+
28
+ temporary_user_data_dir = nil
29
+ if firefox_arguments.none? { |arg| arg.start_with?('--profile') || arg.start_with?('-profile') }
30
+ temporary_user_data_dir = create_profile
31
+ firefox_arguments << "--profile"
32
+ firefox_arguments << temporary_user_data_dir
33
+ end
34
+
35
+ firefox_executable = @launch_options.executable_path || resolve_executable_path
36
+ runner = Puppeteer::BrowserRunner.new(firefox_executable, firefox_arguments, temporary_user_data_dir)
37
+ runner.start(
38
+ handle_SIGHUP: @launch_options.handle_SIGHUP?,
39
+ handle_SIGTERM: @launch_options.handle_SIGTERM?,
40
+ handle_SIGINT: @launch_options.handle_SIGINT?,
41
+ dumpio: @launch_options.dumpio?,
42
+ env: @launch_options.env,
43
+ pipe: @launch_options.pipe?,
44
+ )
45
+
46
+ begin
47
+ connection = runner.setup_connection(
48
+ use_pipe: @launch_options.pipe?,
49
+ timeout: @launch_options.timeout,
50
+ slow_mo: @browser_options.slow_mo,
51
+ preferred_revision: @preferred_revision,
52
+ )
53
+
54
+ browser = Puppeteer::Browser.create(
55
+ connection: connection,
56
+ context_ids: [],
57
+ ignore_https_errors: @browser_options.ignore_https_errors?,
58
+ default_viewport: @browser_options.default_viewport,
59
+ process: runner.proc,
60
+ close_callback: -> { runner.close },
61
+ )
62
+
63
+ browser.wait_for_target(predicate: ->(target) { target.type == 'page' })
64
+
65
+ browser
66
+ rescue
67
+ runner.kill
68
+ raise
69
+ end
70
+ end
71
+
72
+ # @return [Puppeteer::Browser]
73
+ def connect(options = {})
74
+ @browser_options = BrowserOptions.new(options)
75
+ browser_ws_endpoint = options[:browser_ws_endpoint]
76
+ browser_url = options[:browser_url]
77
+ transport = options[:transport]
78
+
79
+ connection =
80
+ if browser_ws_endpoint && browser_url.nil? && transport.nil?
81
+ connect_with_browser_ws_endpoint(browser_ws_endpoint)
82
+ elsif browser_ws_endpoint.nil? && browser_url && transport.nil?
83
+ connect_with_browser_url(browser_url)
84
+ elsif browser_ws_endpoint.nil? && browser_url.nil? && transport
85
+ connect_with_transport(transport)
86
+ else
87
+ raise ArgumentError.new("Exactly one of browserWSEndpoint, browserURL or transport must be passed to puppeteer.connect")
88
+ end
89
+
90
+ result = connection.send_message('Target.getBrowserContexts')
91
+ browser_context_ids = result['browserContextIds']
92
+
93
+ Puppeteer::Browser.create(
94
+ connection: connection,
95
+ context_ids: browser_context_ids,
96
+ ignore_https_errors: @browser_options.ignore_https_errors?,
97
+ default_viewport: @browser_options.default_viewport,
98
+ process: nil,
99
+ close_callback: -> { connection.send_message('Browser.close') },
100
+ )
101
+ end
102
+
103
+ # @return [Puppeteer::Connection]
104
+ private def connect_with_browser_ws_endpoint(browser_ws_endpoint)
105
+ transport = Puppeteer::WebSocketTransport.create(browser_ws_endpoint)
106
+ Puppeteer::Connection.new(browser_ws_endpoint, transport, @browser_options.slow_mo)
107
+ end
108
+
109
+ # @return [Puppeteer::Connection]
110
+ private def connect_with_browser_url(browser_url)
111
+ require 'net/http'
112
+ uri = URI(browser_url)
113
+ uri.path = '/json/version'
114
+ response_body = Net::HTTP.get(uri)
115
+ json = JSON.parse(response_body)
116
+ connection_url = json['webSocketDebuggerUrl']
117
+ connect_with_browser_ws_endpoint(connection_url)
118
+ end
119
+
120
+ # @return [Puppeteer::Connection]
121
+ private def connect_with_transport(transport)
122
+ Puppeteer::Connection.new('', transport, @browser_options.slow_mo)
123
+ end
124
+
125
+ # @return {string}
126
+ def executable_path
127
+ resolve_executable_path
128
+ end
129
+
130
+ private def product
131
+ 'firefox'
132
+ end
133
+
134
+ class DefaultArgs
135
+ include Enumerable
136
+
137
+ # @param options [Launcher::ChromeArgOptions]
138
+ def initialize(chrome_arg_options)
139
+ firefox_arguments = ['--no-remote', '--foreground']
140
+
141
+ # if (os.platform().startsWith('win')) {
142
+ # firefoxArguments.push('--wait-for-browser');
143
+ # }
144
+
145
+ if chrome_arg_options.user_data_dir
146
+ firefox_arguments << "--profile"
147
+ firefox_arguments << chrome_arg_options.user_data_dir
148
+ end
149
+
150
+ if chrome_arg_options.headless?
151
+ firefox_arguments << '--headless'
152
+ end
153
+
154
+ if chrome_arg_options.devtools?
155
+ firefox_arguments << '--devtools'
156
+ end
157
+
158
+ if chrome_arg_options.args.all? { |arg| arg.start_with?('-') }
159
+ firefox_arguments << 'about:blank'
160
+ end
161
+
162
+ firefox_arguments.concat(chrome_arg_options.args)
163
+
164
+ @firefox_arguments = firefox_arguments
165
+ end
166
+
167
+ def each(&block)
168
+ @firefox_arguments.each do |opt|
169
+ block.call(opt)
170
+ end
171
+ end
172
+ end
173
+
174
+ # @return [DefaultArgs]
175
+ def default_args(options = nil)
176
+ if options.nil?
177
+ @default_args ||= DefaultArgs.new(@chrome_arg_options)
178
+ else
179
+ DefaultArgs.new(ChromeArgOptions.new(options))
180
+ end
181
+ end
182
+
183
+ private def create_profile(extra_prefs = {})
184
+ Dir.mktmpdir('puppeteer_dev_firefox_profile-').tap do |profile_path|
185
+ server = 'dummy.test'
186
+ default_preferences = {
187
+ # Make sure Shield doesn't hit the network.
188
+ 'app.normandy.api_url': '',
189
+ # Disable Firefox old build background check
190
+ 'app.update.checkInstallTime': false,
191
+ # Disable automatically upgrading Firefox
192
+ 'app.update.disabledForTesting': true,
193
+
194
+ # Increase the APZ content response timeout to 1 minute
195
+ 'apz.content_response_timeout': 60000,
196
+
197
+ # Prevent various error message on the console
198
+ # jest-puppeteer asserts that no error message is emitted by the console
199
+ 'browser.contentblocking.features.standard': '-tp,tpPrivate,cookieBehavior0,-cm,-fp',
200
+
201
+ # Enable the dump function: which sends messages to the system
202
+ # console
203
+ # https://bugzilla.mozilla.org/show_bug.cgi?id=1543115
204
+ 'browser.dom.window.dump.enabled': true,
205
+ # Disable topstories
206
+ 'browser.newtabpage.activity-stream.feeds.section.topstories': false,
207
+ # Always display a blank page
208
+ 'browser.newtabpage.enabled': false,
209
+ # Background thumbnails in particular cause grief: and disabling
210
+ # thumbnails in general cannot hurt
211
+ 'browser.pagethumbnails.capturing_disabled': true,
212
+
213
+ # Disable safebrowsing components.
214
+ 'browser.safebrowsing.blockedURIs.enabled': false,
215
+ 'browser.safebrowsing.downloads.enabled': false,
216
+ 'browser.safebrowsing.malware.enabled': false,
217
+ 'browser.safebrowsing.passwords.enabled': false,
218
+ 'browser.safebrowsing.phishing.enabled': false,
219
+
220
+ # Disable updates to search engines.
221
+ 'browser.search.update': false,
222
+ # Do not restore the last open set of tabs if the browser has crashed
223
+ 'browser.sessionstore.resume_from_crash': false,
224
+ # Skip check for default browser on startup
225
+ 'browser.shell.checkDefaultBrowser': false,
226
+
227
+ # Disable newtabpage
228
+ 'browser.startup.homepage': 'about:blank',
229
+ # Do not redirect user when a milstone upgrade of Firefox is detected
230
+ 'browser.startup.homepage_override.mstone': 'ignore',
231
+ # Start with a blank page about:blank
232
+ 'browser.startup.page': 0,
233
+
234
+ # Do not allow background tabs to be zombified on Android: otherwise for
235
+ # tests that open additional tabs: the test harness tab itself might get
236
+ # unloaded
237
+ 'browser.tabs.disableBackgroundZombification': false,
238
+ # Do not warn when closing all other open tabs
239
+ 'browser.tabs.warnOnCloseOtherTabs': false,
240
+ # Do not warn when multiple tabs will be opened
241
+ 'browser.tabs.warnOnOpen': false,
242
+
243
+ # Disable the UI tour.
244
+ 'browser.uitour.enabled': false,
245
+ # Turn off search suggestions in the location bar so as not to trigger
246
+ # network connections.
247
+ 'browser.urlbar.suggest.searches': false,
248
+ # Disable first run splash page on Windows 10
249
+ 'browser.usedOnWindows10.introURL': '',
250
+ # Do not warn on quitting Firefox
251
+ 'browser.warnOnQuit': false,
252
+
253
+ # Do not show datareporting policy notifications which can
254
+ # interfere with tests
255
+ 'datareporting.healthreport.about.reportUrl': "http://#{server}/dummy/abouthealthreport/",
256
+ 'datareporting.healthreport.documentServerURI': "http://#{server}/dummy/healthreport/",
257
+ 'datareporting.healthreport.logging.consoleEnabled': false,
258
+ 'datareporting.healthreport.service.enabled': false,
259
+ 'datareporting.healthreport.service.firstRun': false,
260
+ 'datareporting.healthreport.uploadEnabled': false,
261
+ 'datareporting.policy.dataSubmissionEnabled': false,
262
+ 'datareporting.policy.dataSubmissionPolicyAccepted': false,
263
+ 'datareporting.policy.dataSubmissionPolicyBypassNotification': true,
264
+
265
+ # DevTools JSONViewer sometimes fails to load dependencies with its require.js.
266
+ # This doesn't affect Puppeteer but spams console (Bug 1424372)
267
+ 'devtools.jsonview.enabled': false,
268
+
269
+ # Disable popup-blocker
270
+ 'dom.disable_open_during_load': false,
271
+
272
+ # Enable the support for File object creation in the content process
273
+ # Required for |Page.setFileInputFiles| protocol method.
274
+ 'dom.file.createInChild': true,
275
+
276
+ # Disable the ProcessHangMonitor
277
+ 'dom.ipc.reportProcessHangs': false,
278
+
279
+ # Disable slow script dialogues
280
+ 'dom.max_chrome_script_run_time': 0,
281
+ 'dom.max_script_run_time': 0,
282
+
283
+ # Only load extensions from the application and user profile
284
+ # AddonManager.SCOPE_PROFILE + AddonManager.SCOPE_APPLICATION
285
+ 'extensions.autoDisableScopes': 0,
286
+ 'extensions.enabledScopes': 5,
287
+
288
+ # Disable metadata caching for installed add-ons by default
289
+ 'extensions.getAddons.cache.enabled': false,
290
+
291
+ # Disable installing any distribution extensions or add-ons.
292
+ 'extensions.installDistroAddons': false,
293
+
294
+ # Disabled screenshots extension
295
+ 'extensions.screenshots.disabled': true,
296
+
297
+ # Turn off extension updates so they do not bother tests
298
+ 'extensions.update.enabled': false,
299
+
300
+ # Turn off extension updates so they do not bother tests
301
+ 'extensions.update.notifyUser': false,
302
+
303
+ # Make sure opening about:addons will not hit the network
304
+ 'extensions.webservice.discoverURL': "http://#{server}/dummy/discoveryURL",
305
+
306
+ # Allow the application to have focus even it runs in the background
307
+ 'focusmanager.testmode': true,
308
+ # Disable useragent updates
309
+ 'general.useragent.updates.enabled': false,
310
+ # Always use network provider for geolocation tests so we bypass the
311
+ # macOS dialog raised by the corelocation provider
312
+ 'geo.provider.testing': true,
313
+ # Do not scan Wifi
314
+ 'geo.wifi.scan': false,
315
+ # No hang monitor
316
+ 'hangmonitor.timeout': 0,
317
+ # Show chrome errors and warnings in the error console
318
+ 'javascript.options.showInConsole': true,
319
+
320
+ # Disable download and usage of OpenH264: and Widevine plugins
321
+ 'media.gmp-manager.updateEnabled': false,
322
+ # Prevent various error message on the console
323
+ # jest-puppeteer asserts that no error message is emitted by the console
324
+ 'network.cookie.cookieBehavior': 0,
325
+
326
+ # Do not prompt for temporary redirects
327
+ 'network.http.prompt-temp-redirect': false,
328
+
329
+ # Disable speculative connections so they are not reported as leaking
330
+ # when they are hanging around
331
+ 'network.http.speculative-parallel-limit': 0,
332
+
333
+ # Do not automatically switch between offline and online
334
+ 'network.manage-offline-status': false,
335
+
336
+ # Make sure SNTP requests do not hit the network
337
+ 'network.sntp.pools': server,
338
+
339
+ # Disable Flash.
340
+ 'plugin.state.flash': 0,
341
+
342
+ 'privacy.trackingprotection.enabled': false,
343
+
344
+ # Enable Remote Agent
345
+ # https://bugzilla.mozilla.org/show_bug.cgi?id=1544393
346
+ 'remote.enabled': true,
347
+
348
+ # Don't do network connections for mitm priming
349
+ 'security.certerrors.mitm.priming.enabled': false,
350
+ # Local documents have access to all other local documents,
351
+ # including directory listings
352
+ 'security.fileuri.strict_origin_policy': false,
353
+ # Do not wait for the notification button security delay
354
+ 'security.notification_enable_delay': 0,
355
+
356
+ # Ensure blocklist updates do not hit the network
357
+ 'services.settings.server': "http://#{server}/dummy/blocklist/",
358
+
359
+ # Do not automatically fill sign-in forms with known usernames and
360
+ # passwords
361
+ 'signon.autofillForms': false,
362
+ # Disable password capture, so that tests that include forms are not
363
+ # influenced by the presence of the persistent doorhanger notification
364
+ 'signon.rememberSignons': false,
365
+
366
+ # Disable first-run welcome page
367
+ 'startup.homepage_welcome_url': 'about:blank',
368
+
369
+ # Disable first-run welcome page
370
+ 'startup.homepage_welcome_url.additional': '',
371
+
372
+ # Disable browser animations (tabs, fullscreen, sliding alerts)
373
+ 'toolkit.cosmeticAnimations.enabled': false,
374
+
375
+ # We want to collect telemetry, but we don't want to send in the results
376
+ 'toolkit.telemetry.server': "https://#{server}/dummy/telemetry/",
377
+ # Prevent starting into safe mode after application crashes
378
+ 'toolkit.startup.max_resumed_crashes': -1,
379
+ }
380
+
381
+ preferences = default_preferences.merge(extra_prefs)
382
+
383
+ File.open(File.join(profile_path, 'user.js'), 'w') do |f|
384
+ preferences.each do |key, value|
385
+ f.write("user_pref(#{JSON.generate(key)}, #{JSON.generate(value)});\n")
386
+ end
387
+ end
388
+ IO.write(File.join(profile_path, 'prefs.js'), "")
389
+ end
390
+ end
391
+ end
392
+ end
@@ -266,7 +266,13 @@ class Puppeteer::Page
266
266
  @frame_manager.main_frame
267
267
  end
268
268
 
269
- attr_reader :keyboard, :touch_screen, :coverage, :accessibility
269
+ attr_reader :touch_screen, :coverage, :accessibility
270
+
271
+ def keyboard(&block)
272
+ @keyboard.instance_eval(&block) unless block.nil?
273
+
274
+ @keyboard
275
+ end
270
276
 
271
277
  def frames
272
278
  @frame_manager.frames
@@ -80,7 +80,18 @@ class Puppeteer::RemoteObject
80
80
 
81
81
  # used in ElementHandle#_box_model
82
82
  def box_model(client)
83
- client.send_message('DOM.getBoxModel', objectId: @object_id)
83
+ result = client.send_message('DOM.getBoxModel', objectId: @object_id)
84
+
85
+ # Firefox returns width/height = 0, content/padding/border/margin = [nil, nil, nil, nil, nil, nil, nil, nil]
86
+ # while Chrome throws Error(Could not compute box model)
87
+ model = result['model']
88
+ if model['width'] == 0 && model['height'] == 0 &&
89
+ %w(content padding border margin).all? { |key| model[key].all?(&:nil?) }
90
+
91
+ debug_puts('Could not compute box model in Firefox.')
92
+ return nil
93
+ end
94
+ result
84
95
  rescue => err
85
96
  debug_puts(err)
86
97
  nil
@@ -1,3 +1,3 @@
1
1
  class Puppeteer
2
- VERSION = '0.0.18'
2
+ VERSION = '0.0.19'
3
3
  end
@@ -26,7 +26,7 @@ Gem::Specification.new do |spec|
26
26
  spec.add_development_dependency 'rake', '~> 10.0'
27
27
  spec.add_development_dependency 'rspec', '~> 3.0'
28
28
  spec.add_development_dependency 'rspec_junit_formatter' # for CircleCI.
29
- spec.add_development_dependency 'rubocop', '~> 0.89.0'
29
+ spec.add_development_dependency 'rubocop', '~> 0.90.0'
30
30
  spec.add_development_dependency 'rubocop-rspec'
31
31
  spec.add_development_dependency 'sinatra'
32
32
  spec.add_development_dependency 'yard'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puppeteer-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.18
4
+ version: 0.0.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - YusukeIwaki
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-08-23 00:00:00.000000000 Z
11
+ date: 2020-09-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -128,14 +128,14 @@ dependencies:
128
128
  requirements:
129
129
  - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: 0.89.0
131
+ version: 0.90.0
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: 0.89.0
138
+ version: 0.90.0
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: rubocop-rspec
141
141
  requirement: !ruby/object:Gem::Requirement
@@ -193,11 +193,13 @@ files:
193
193
  - ".rspec"
194
194
  - ".rubocop.yml"
195
195
  - ".travis.yml"
196
+ - Dockerfile
196
197
  - Gemfile
197
198
  - README.md
198
199
  - Rakefile
199
200
  - bin/console
200
201
  - bin/setup
202
+ - docker-compose.yml
201
203
  - lib/puppeteer.rb
202
204
  - lib/puppeteer/browser.rb
203
205
  - lib/puppeteer/browser_context.rb
@@ -234,6 +236,7 @@ files:
234
236
  - lib/puppeteer/launcher/browser_options.rb
235
237
  - lib/puppeteer/launcher/chrome.rb
236
238
  - lib/puppeteer/launcher/chrome_arg_options.rb
239
+ - lib/puppeteer/launcher/firefox.rb
237
240
  - lib/puppeteer/launcher/launch_options.rb
238
241
  - lib/puppeteer/lifecycle_watcher.rb
239
242
  - lib/puppeteer/mouse.rb