puppeteer-ruby 0.0.14 → 0.0.19

Sign up to get free protection for your applications and to get access to all the features.
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)