puppeteer-ruby 0.0.14 → 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: 0a500508a5a1d88ed4694c5614c7c70bdae06d4d5cb10f81c1237ebd25a6623f
4
- data.tar.gz: 338b902e3c64d9f96e7b7822353a7b664ab112cd3993e7a7ec06cda41752521e
3
+ metadata.gz: 6e6a29713aa4dd143bdd6c4fd1cc84df1bd7037aa920b0d660a62267f6321515
4
+ data.tar.gz: 46a433d484dfabd019cc0874b8dd6c17182e374fb53d6f6905fde7c1d120d5e6
5
5
  SHA512:
6
- metadata.gz: 51ea52a62c04917d5ec62c4224ffe91cacf3ccd3cfc796d94d975c309971dc0e789fdec7f4fabcc37f51619d833f070e7d6136f18cdb7113721382392456dd88
7
- data.tar.gz: ef643098e96d3d1794470f38befb55039916c13b35d7d133596acf42d7217c302d1de4865c62c178e758aa619063ee9469bbbfcda1665c3e19fcca26aaee12ce
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
@@ -13,10 +13,32 @@ jobs:
13
13
  - run:
14
14
  name: rspec
15
15
  command: |
16
+ DEBUG=1 bundle exec rspec --profile 10 \
17
+ --format RspecJunitFormatter \
18
+ --out test_results/rspec.xml \
19
+ --format documentation
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 \
16
38
  bundle exec rspec --profile 10 \
17
39
  --format RspecJunitFormatter \
18
40
  --out test_results/rspec.xml \
19
- --format progress
41
+ --format documentation spec/integration/
20
42
 
21
43
  deploy:
22
44
  docker:
@@ -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
@@ -146,17 +159,44 @@ Lint/AmbiguousOperator:
146
159
  Lint/AmbiguousRegexpLiteral:
147
160
  Enabled: true
148
161
 
162
+ Lint/BinaryOperatorWithIdenticalOperands:
163
+ Enabled: true
164
+
165
+ Lint/DeprecatedClassMethods:
166
+ Enabled: true
167
+
168
+ Lint/DuplicateRescueException:
169
+ Enabled: true
170
+
149
171
  Lint/ErbNewArguments:
150
172
  Enabled: true
151
173
 
174
+ Lint/EmptyConditionalBody:
175
+ Enabled: true
176
+
177
+ Lint/FloatComparison:
178
+ Enabled: true
179
+
180
+ Lint/OutOfRangeRegexpRef:
181
+ Enabled: true
182
+
183
+ Lint/RedundantStringCoercion:
184
+ Enabled: true
185
+
152
186
  # Use my_method(my_arg) not my_method( my_arg ) or my_method my_arg.
153
187
  Lint/RequireParentheses:
154
188
  Enabled: true
155
189
 
190
+ Lint/SelfAssignment:
191
+ Enabled: true
192
+
156
193
  Lint/ShadowingOuterLocalVariable:
157
194
  Enabled: true
158
195
 
159
- Lint/RedundantStringCoercion:
196
+ Lint/TopLevelReturnWithArgument:
197
+ Enabled: true
198
+
199
+ Lint/UnreachableLoop:
160
200
  Enabled: true
161
201
 
162
202
  Lint/UriEscapeUnescape:
@@ -165,15 +205,18 @@ Lint/UriEscapeUnescape:
165
205
  Lint/UselessAssignment:
166
206
  Enabled: true
167
207
 
168
- Lint/DeprecatedClassMethods:
208
+ Style/ParenthesesAroundCondition:
169
209
  Enabled: true
170
210
 
171
- Style/ParenthesesAroundCondition:
211
+ Style/ExplicitBlockArgument:
172
212
  Enabled: true
173
213
 
174
214
  Style/FrozenStringLiteralComment:
175
215
  Enabled: false
176
216
 
217
+ Style/GlobalStdStream:
218
+ Enabled: true
219
+
177
220
  Style/HashEachMethods:
178
221
  Enabled: true
179
222
 
@@ -198,6 +241,9 @@ Style/Semicolon:
198
241
  Enabled: true
199
242
  AllowAsExpressionSeparator: true
200
243
 
244
+ Style/StringConcatenation:
245
+ Enabled: true
246
+
201
247
  # Prefer Foo.method over Foo::method
202
248
  Style/ColonMethodCall:
203
249
  Enabled: true
@@ -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
data/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ [![Gem Version](https://badge.fury.io/rb/puppeteer-ruby.svg)](https://badge.fury.io/rb/puppeteer-ruby)
2
+
1
3
  # Puppeteer in Ruby [UNDER HEAVY DEVELOPMENT]
2
4
 
3
5
  A Ruby port of [puppeteer](https://pptr.dev/).
@@ -47,7 +49,7 @@ end
47
49
 
48
50
  More usage examples can be found [here](https://github.com/YusukeIwaki/puppeteer-ruby-example)
49
51
 
50
- ## Collaboration with Selenium or Capybara
52
+ ## :bulb: Collaboration with Selenium or Capybara
51
53
 
52
54
  It is really remarkable that we can use puppeteer functions in existing Selenium or Capybara codes, with a few configuration in advance.
53
55
 
@@ -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
@@ -2,6 +2,8 @@ require 'concurrent'
2
2
 
3
3
  class Puppeteer; end
4
4
 
5
+ require 'puppeteer/env'
6
+
5
7
  # Custom data types.
6
8
  require 'puppeteer/device'
7
9
  require 'puppeteer/errors'
@@ -36,6 +38,8 @@ require 'puppeteer/mouse'
36
38
  require 'puppeteer/network_manager'
37
39
  require 'puppeteer/page'
38
40
  require 'puppeteer/remote_object'
41
+ require 'puppeteer/request'
42
+ require 'puppeteer/response'
39
43
  require 'puppeteer/target'
40
44
  require 'puppeteer/timeout_settings'
41
45
  require 'puppeteer/touch_screen'
@@ -49,18 +53,14 @@ require 'puppeteer/element_handle'
49
53
 
50
54
  # ref: https://github.com/puppeteer/puppeteer/blob/master/lib/Puppeteer.js
51
55
  class Puppeteer
52
- class << self
53
- def method_missing(method, *args, **kwargs, &block)
54
- instance.send(method, *args, **kwargs, &block)
55
- 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
+ )
56
62
 
57
- def instance
58
- @instance ||= Puppeteer.new(
59
- project_root: __dir__,
60
- preferred_revision: '706915',
61
- is_puppeteer_core: true,
62
- )
63
- end
63
+ @puppeteer.send(method, *args, **kwargs, &block)
64
64
  end
65
65
 
66
66
  # @param project_root [String]
@@ -166,7 +166,11 @@ class Puppeteer
166
166
  }.compact
167
167
  browser = launcher.connect(options)
168
168
  if block_given?
169
- yield(browser)
169
+ begin
170
+ yield(browser)
171
+ ensure
172
+ browser.disconnect
173
+ end
170
174
  else
171
175
  browser
172
176
  end
@@ -43,7 +43,7 @@ class Puppeteer::Browser
43
43
  @default_context = Puppeteer::BrowserContext.new(@connection, self, nil)
44
44
  @contexts = {}
45
45
  context_ids.each do |context_id|
46
- @contexts[context_id] = Puppeteer::BrowserContext.new(@connection, self. context_id)
46
+ @contexts[context_id] = Puppeteer::BrowserContext.new(@connection, self, context_id)
47
47
  end
48
48
  @targets = {}
49
49
  @connection.on_event 'Events.Connection.Disconnected' do
@@ -70,6 +70,15 @@ class Puppeteer::Browser
70
70
  add_event_listener(EVENT_MAPPINGS[event_name.to_sym], &block)
71
71
  end
72
72
 
73
+ # @param event_name [Symbol]
74
+ def once(event_name, &block)
75
+ unless EVENT_MAPPINGS.has_key?(event_name.to_sym)
76
+ raise ArgumentError.new("Unknown event name: #{event_name}. Known events are #{EVENT_MAPPINGS.keys.join(", ")}")
77
+ end
78
+
79
+ observe_first(EVENT_MAPPINGS[event_name.to_sym], &block)
80
+ end
81
+
73
82
  # @return [Puppeteer::BrowserRunner::BrowserProcess]
74
83
  def process
75
84
  @process
@@ -94,7 +103,7 @@ class Puppeteer::Browser
94
103
  # @param context_id [String]
95
104
  def dispose_context(context_id)
96
105
  @connection.send_message('Target.disposeBrowserContext', browserContextId: context_id)
97
- @contexts.remove(context_id)
106
+ @contexts.delete(context_id)
98
107
  end
99
108
 
100
109
  class TargetAlreadyExistError < StandardError
@@ -166,7 +175,7 @@ class Puppeteer::Browser
166
175
  end
167
176
 
168
177
  # @return [String]
169
- def websocket_endpoint
178
+ def ws_endpoint
170
179
  @connection.url
171
180
  end
172
181
 
@@ -196,7 +205,7 @@ class Puppeteer::Browser
196
205
 
197
206
  # @return {!Target}
198
207
  def target
199
- targets.first { |target| target.type == 'browser' }
208
+ targets.find { |target| target.type == 'browser' }
200
209
  end
201
210
 
202
211
  # used only in Target#opener
@@ -204,12 +213,11 @@ class Puppeteer::Browser
204
213
  @targets[target_id]
205
214
  end
206
215
 
207
- # @param {function(!Target):boolean} predicate
208
- # @param {{timeout?: number}=} options
209
- # @return {!Promise<!Target>}
216
+ # @param predicate [Proc(Puppeteer::Target -> Boolean)]
217
+ # @return [Puppeteer::Target]
210
218
  def wait_for_target(predicate:, timeout: nil)
211
219
  timeout_in_sec = (timeout || 30000).to_i / 1000.0
212
- existing_target = targets.first { |target| predicate.call(target) }
220
+ existing_target = targets.find { |target| predicate.call(target) }
213
221
  return existing_target if existing_target
214
222
 
215
223
  event_listening_ids = []
@@ -233,11 +241,18 @@ class Puppeteer::Browser
233
241
  else
234
242
  target_promise.value!
235
243
  end
244
+ rescue Timeout::Error
245
+ raise Puppeteer::TimeoutError.new("waiting for target failed: timeout #{timeout}ms exceeded")
236
246
  ensure
237
247
  remove_event_listener(*event_listening_ids)
238
248
  end
239
249
  end
240
250
 
251
+ # @!method async_wait_for_target(predicate:, timeout: nil)
252
+ #
253
+ # @param predicate [Proc(Puppeteer::Target -> Boolean)]
254
+ define_async_method :async_wait_for_target
255
+
241
256
  # @return {!Promise<!Array<!Puppeteer.Page>>}
242
257
  def pages
243
258
  browser_contexts.flat_map(&:pages)
@@ -266,7 +281,19 @@ class Puppeteer::Browser
266
281
  !@connection.closed?
267
282
  end
268
283
 
284
+ class Version
285
+ def initialize(hash)
286
+ @protocol_version = hash['protocolVersion']
287
+ @product = hash['product']
288
+ @revision = hash['revision']
289
+ @user_agent = hash['userAgent']
290
+ @js_version = hash['jsVersion']
291
+ end
292
+
293
+ attr_reader :protocol_version, :product, :revision, :user_agent, :js_version
294
+ end
295
+
269
296
  private def get_version
270
- @connection.send_message('Browser.getVersion')
297
+ Version.new(@connection.send_message('Browser.getVersion'))
271
298
  end
272
299
  end
@@ -1,5 +1,6 @@
1
1
  class Puppeteer::BrowserContext
2
2
  include Puppeteer::EventCallbackable
3
+ using Puppeteer::DefineAsyncMethod
3
4
 
4
5
  # @param {!Puppeteer.Connection} connection
5
6
  # @param {!Browser} browser
@@ -10,14 +11,38 @@ class Puppeteer::BrowserContext
10
11
  @id = context_id
11
12
  end
12
13
 
14
+ EVENT_MAPPINGS = {
15
+ disconnected: 'Events.BrowserContext.Disconnected',
16
+ targetcreated: 'Events.BrowserContext.TargetCreated',
17
+ targetchanged: 'Events.BrowserContext.TargetChanged',
18
+ targetdestroyed: 'Events.BrowserContext.TargetDestroyed',
19
+ }
20
+
21
+ # @param event_name [Symbol] either of :disconnected, :targetcreated, :targetchanged, :targetdestroyed
22
+ def on(event_name, &block)
23
+ unless EVENT_MAPPINGS.has_key?(event_name.to_sym)
24
+ raise ArgumentError.new("Unknown event name: #{event_name}. Known events are #{EVENT_MAPPINGS.keys.join(", ")}")
25
+ end
26
+
27
+ add_event_listener(EVENT_MAPPINGS[event_name.to_sym], &block)
28
+ end
29
+
30
+ # @param event_name [Symbol]
31
+ def once(event_name, &block)
32
+ unless EVENT_MAPPINGS.has_key?(event_name.to_sym)
33
+ raise ArgumentError.new("Unknown event name: #{event_name}. Known events are #{EVENT_MAPPINGS.keys.join(", ")}")
34
+ end
35
+
36
+ observe_first(EVENT_MAPPINGS[event_name.to_sym], &block)
37
+ end
38
+
13
39
  # @return {!Array<!Target>} target
14
40
  def targets
15
41
  @browser.targets.select { |target| target.browser_context == self }
16
42
  end
17
43
 
18
- # @param {function(!Target):boolean} predicate
19
- # @param {{timeout?: number}=} options
20
- # @return {!Promise<!Target>}
44
+ # @param predicate [Proc(Puppeteer::Target -> Boolean)]
45
+ # @return [Puppeteer::Target]
21
46
  def wait_for_target(predicate:, timeout: nil)
22
47
  @browser.wait_for_target(
23
48
  predicate: ->(target) { target.browser_context == self && predicate.call(target) },
@@ -25,13 +50,18 @@ class Puppeteer::BrowserContext
25
50
  )
26
51
  end
27
52
 
53
+ # @!method async_wait_for_target(predicate:, timeout: nil)
54
+ #
55
+ # @param predicate [Proc(Puppeteer::Target -> Boolean)]
56
+ define_async_method :async_wait_for_target
57
+
28
58
  # @return {!Promise<!Array<!Puppeteer.Page>>}
29
59
  def pages
30
60
  targets.select { |target| target.type == 'page' }.map(&:page).reject { |page| !page }
31
61
  end
32
62
 
33
63
  def incognito?
34
- !@id
64
+ !!@id
35
65
  end
36
66
 
37
67
  # /**
@@ -82,7 +112,7 @@ class Puppeteer::BrowserContext
82
112
  end
83
113
 
84
114
  def close
85
- if !@id
115
+ unless @id
86
116
  raise 'Non-incognito profiles cannot be closed!'
87
117
  end
88
118
  @browser.dispose_context(@id)