puppeteer-ruby 0.0.20 → 0.0.26

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: 8a0821b740ece89c3194c7b9fc7778b18528d38becf524e7a1c50ceffd37ab3c
4
- data.tar.gz: 86a3e592c61b4f0095ca3fad2ab0ecb1b031c4dbe4f9607caa52b2b82cf225bd
3
+ metadata.gz: f76be710be28b32694ef8d21bcaa305f00b8ac0ada333d2992137f166614bd94
4
+ data.tar.gz: 29d4c83aaa00705db67dd1a33b62b304b125fc59bd5f826099a9f864202f3e00
5
5
  SHA512:
6
- metadata.gz: e73f8a9f380aadb2e4dd4164be571ee22b688b48b1999720d0ecefb39b62f79a071a709134b00f701b04a1d179bba3efe742d3307fca9bc2d2f56cb305b7bb53
7
- data.tar.gz: f03efa136e60899f4eb0e0bd671e60c86b52efb13a59d62754b88961188d1495e7e85e012bb93a11d118e2f5a93375de07c453ef5a5eff7375325c2ec9b2b5ae
6
+ metadata.gz: f5dbf6ee744fdb70d7645bdfaf3840088d756b31a0dfcf05109058299d07ea338967c019ee4a55f834bc388b39cfc19b147ac7f08d80762d5eb44ed8517d0f1a
7
+ data.tar.gz: 05a88198b74788638619bbdef3faaede3503c61a5b6574a562180265f5f927a236a564b3f0d73dfefcaa442b492227b934f7233ad72183924b98d66e242e4850
@@ -116,6 +116,43 @@ Style/DefWithParentheses:
116
116
  Style/MethodDefParentheses:
117
117
  Enabled: true
118
118
 
119
+ Style/MethodCallWithArgsParentheses:
120
+ Enabled: true
121
+ IgnoredMethods:
122
+ # Gemfile, gemspec
123
+ - source
124
+ - add_dependency
125
+ - add_development_dependency
126
+
127
+ # include/require
128
+ - require
129
+ - require_relative
130
+ - include
131
+
132
+ # fundamental methods
133
+ - raise
134
+ - sleep
135
+
136
+ # RSpec
137
+ - describe
138
+ - it
139
+ - to
140
+ - not_to
141
+ - be
142
+ - eq
143
+
144
+ # async/await
145
+ - define_async_method
146
+ - await
147
+ - future
148
+
149
+ # utils
150
+ - debug_print
151
+ - debug_puts
152
+
153
+ Style/MethodCallWithoutArgsParentheses:
154
+ Enabled: true
155
+
119
156
  Style/RedundantFreeze:
120
157
  Enabled: true
121
158
 
@@ -0,0 +1,62 @@
1
+ ### master [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.0.25...master)]
2
+
3
+ * xxx
4
+
5
+ ### 0.0.25 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.0.23...0.0.25)]
6
+
7
+ New feature:
8
+
9
+ * **Cookie** feature: `Page#set_cookie`, `Page#cookies`
10
+
11
+ ### 0.0.23 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.0.22...0.0.23)]
12
+
13
+ New feature:
14
+
15
+ * **GeoLocation** feature
16
+ * grant/clear permission
17
+
18
+ Bugfix/Improvement:
19
+
20
+ * Refactoring for events ([#31](https://github.com/YusukeIwaki/puppeteer-ruby/pull/31))
21
+ * Improve SEND/RECV handling in CDPSession ([#34](https://github.com/YusukeIwaki/puppeteer-ruby/pull/34))
22
+
23
+ ### 0.0.22 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.0.21...0.0.22)]
24
+
25
+ Bugfix
26
+
27
+ * Make `Puppeteer#default_args` to work
28
+ * Respect Firefox launch options
29
+ * Respect `default_viewport: nil`
30
+
31
+ ### 0.0.21 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.0.20...0.0.21)]
32
+
33
+ Bugfix/Improvement:
34
+
35
+ * Update DeviceDescriptors (list of emulatable devices)
36
+ * Fix bug on inputing "(" ([#25](https://github.com/YusukeIwaki/puppeteer-ruby/pull/25))
37
+
38
+ ### 0.0.20 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.0.19...0.0.20)]
39
+
40
+ New feature
41
+
42
+ * Dialog-handling feature
43
+
44
+ ### 0.0.19 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.0.18...0.0.19)]
45
+
46
+ New feature
47
+
48
+ * **Firefox support**
49
+
50
+ Bugfix/Improvement
51
+
52
+ * Allow `Page#keyboard` with block ([#18](https://github.com/YusukeIwaki/puppeteer-ruby/pull/18))
53
+
54
+ ### 0.0.18 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.0.17...0.0.18)]
55
+
56
+ New feature
57
+
58
+ * **Firefox support**
59
+
60
+ Bugfix/Improvement
61
+
62
+ * Allow `Page#keyboard` with block ([#18](https://github.com/YusukeIwaki/puppeteer-ruby/pull/18))
data/README.md CHANGED
@@ -72,6 +72,21 @@ end
72
72
 
73
73
  More usage examples can be found [here](https://github.com/YusukeIwaki/puppeteer-ruby-example)
74
74
 
75
+ ## :whale: Running in Docker
76
+
77
+ Following packages are required.
78
+
79
+ * Google Chrome or Chromium
80
+ * In Debian-based images, `google-chrome-stable`
81
+ * In Alpine-based images, `chromium`
82
+
83
+ Also, CJK font will be required for Chinese, Japanese, Korean sites.
84
+
85
+ ### References
86
+
87
+ * Puppeteer official README: https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md#running-puppeteer-in-docker
88
+ * puppeteer-ruby example: https://github.com/YusukeIwaki/puppeteer-ruby-example/tree/master/docker_chromium
89
+
75
90
  ## :bulb: Collaboration with Selenium or Capybara
76
91
 
77
92
  It is really remarkable that we can use puppeteer functions in existing Selenium or Capybara codes, with a few configuration in advance.
@@ -6,7 +6,9 @@ require 'puppeteer/env'
6
6
 
7
7
  # Custom data types.
8
8
  require 'puppeteer/device'
9
+ require 'puppeteer/events'
9
10
  require 'puppeteer/errors'
11
+ require 'puppeteer/geolocation'
10
12
  require 'puppeteer/viewport'
11
13
 
12
14
  # Modules
@@ -27,6 +29,7 @@ require 'puppeteer/devices'
27
29
  require 'puppeteer/dialog'
28
30
  require 'puppeteer/dom_world'
29
31
  require 'puppeteer/emulation_manager'
32
+ require 'puppeteer/exception_details'
30
33
  require 'puppeteer/execution_context'
31
34
  require 'puppeteer/file_chooser'
32
35
  require 'puppeteer/frame'
@@ -61,7 +64,11 @@ class Puppeteer
61
64
  is_puppeteer_core: true,
62
65
  )
63
66
 
64
- @puppeteer.send(method, *args, **kwargs, &block)
67
+ if kwargs.empty? # for Ruby < 2.7
68
+ @puppeteer.public_send(method, *args, &block)
69
+ else
70
+ @puppeteer.public_send(method, *args, **kwargs, &block)
71
+ end
65
72
  end
66
73
 
67
74
  # @param project_root [String]
@@ -127,7 +134,7 @@ class Puppeteer
127
134
  ignore_https_errors: ignore_https_errors,
128
135
  default_viewport: default_viewport,
129
136
  slow_mo: slow_mo,
130
- }.compact
137
+ }
131
138
 
132
139
  @product_name ||= product
133
140
  browser = launcher.launch(options)
@@ -36,7 +36,6 @@ class Puppeteer::Browser
36
36
  @ignore_https_errors = ignore_https_errors
37
37
  @default_viewport = default_viewport
38
38
  @process = process
39
- # @screenshot_task_queue = TaskQueue.new
40
39
  @connection = connection
41
40
  @close_callback = close_callback
42
41
 
@@ -46,37 +45,30 @@ class Puppeteer::Browser
46
45
  @contexts[context_id] = Puppeteer::BrowserContext.new(@connection, self, context_id)
47
46
  end
48
47
  @targets = {}
49
- @connection.on_event 'Events.Connection.Disconnected' do
50
- emit_event 'Events.Browser.Disconnected'
48
+ @connection.on_event(ConnectionEmittedEvents::Disconnected) do
49
+ emit_event(BrowserEmittedEvents::Disconnected)
51
50
  end
52
- @connection.on_event 'Target.targetCreated', &method(:handle_target_created)
53
- @connection.on_event 'Target.targetDestroyed', &method(:handle_target_destroyed)
54
- @connection.on_event 'Target.targetInfoChanged', &method(:handle_target_info_changed)
51
+ @connection.on_event('Target.targetCreated', &method(:handle_target_created))
52
+ @connection.on_event('Target.targetDestroyed', &method(:handle_target_destroyed))
53
+ @connection.on_event('Target.targetInfoChanged', &method(:handle_target_info_changed))
55
54
  end
56
55
 
57
- EVENT_MAPPINGS = {
58
- disconnected: 'Events.Browser.Disconnected',
59
- targetcreated: 'Events.Browser.TargetCreated',
60
- targetchanged: 'Events.Browser.TargetChanged',
61
- targetdestroyed: 'Events.Browser.TargetDestroyed',
62
- }
63
-
64
56
  # @param event_name [Symbol] either of :disconnected, :targetcreated, :targetchanged, :targetdestroyed
65
57
  def on(event_name, &block)
66
- unless EVENT_MAPPINGS.has_key?(event_name.to_sym)
67
- raise ArgumentError.new("Unknown event name: #{event_name}. Known events are #{EVENT_MAPPINGS.keys.join(", ")}")
58
+ unless BrowserEmittedEvents.values.include?(event_name.to_s)
59
+ raise ArgumentError.new("Unknown event name: #{event_name}. Known events are #{BrowserEmittedEvents.values.to_a.join(", ")}")
68
60
  end
69
61
 
70
- add_event_listener(EVENT_MAPPINGS[event_name.to_sym], &block)
62
+ super(event_name.to_s, &block)
71
63
  end
72
64
 
73
65
  # @param event_name [Symbol]
74
66
  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(", ")}")
67
+ unless BrowserEmittedEvents.values.include?(event_name.to_s)
68
+ raise ArgumentError.new("Unknown event name: #{event_name}. Known events are #{BrowserEmittedEvents.values.to_a.join(", ")}")
77
69
  end
78
70
 
79
- observe_first(EVENT_MAPPINGS[event_name.to_sym], &block)
71
+ super(event_name.to_s, &block)
80
72
  end
81
73
 
82
74
  # @return [Puppeteer::BrowserRunner::BrowserProcess]
@@ -132,13 +124,12 @@ class Puppeteer::Browser
132
124
  session_factory: -> { @connection.create_session(target_info) },
133
125
  ignore_https_errors: @ignore_https_errors,
134
126
  default_viewport: @default_viewport,
135
- screenshot_task_queue: @screenshot_task_queue,
136
127
  )
137
128
  # assert(!this._targets.has(event.targetInfo.targetId), 'Target should not exist before targetCreated');
138
129
  @targets[target_info.target_id] = target
139
130
  if await target.initialized_promise
140
- emit_event 'Events.Browser.TargetCreated', target
141
- context.emit_event 'Events.BrowserContext.TargetCreated', target
131
+ emit_event(BrowserEmittedEvents::TargetCreated, target)
132
+ context.emit_event(BrowserContextEmittedEvents::TargetCreated, target)
142
133
  end
143
134
  end
144
135
 
@@ -150,8 +141,8 @@ class Puppeteer::Browser
150
141
  @targets.delete(target_id)
151
142
  target.closed_callback
152
143
  if await target.initialized_promise
153
- emit_event 'Events.Browser.TargetDestroyed', target
154
- target.browser_context.emit_event 'Events.BrowserContext.TargetDestroyed', target
144
+ emit_event(BrowserEmittedEvents::TargetDestroyed, target)
145
+ target.browser_context.emit_event(BrowserContextEmittedEvents::TargetDestroyed, target)
155
146
  end
156
147
  end
157
148
 
@@ -169,8 +160,8 @@ class Puppeteer::Browser
169
160
  was_initialized = target.initialized?
170
161
  target.handle_target_info_changed(target_info)
171
162
  if was_initialized && previous_url != target.url
172
- emit_event 'Events.Browser.TargetChanged', target
173
- target.browser_context.emit_event 'Events.BrowserContext.TargetChanged', target
163
+ emit_event(BrowserEmittedEvents::TargetChanged, target)
164
+ target.browser_context.emit_event(BrowserContextEmittedEvents::TargetChanged, target)
174
165
  end
175
166
  end
176
167
 
@@ -222,12 +213,12 @@ class Puppeteer::Browser
222
213
 
223
214
  event_listening_ids = []
224
215
  target_promise = resolvable_future
225
- event_listening_ids << add_event_listener('Events.Browser.TargetCreated') do |target|
216
+ event_listening_ids << add_event_listener(BrowserEmittedEvents::TargetCreated) do |target|
226
217
  if predicate.call(target)
227
218
  target_promise.fulfill(target)
228
219
  end
229
220
  end
230
- event_listening_ids << add_event_listener('Events.Browser.TargetChanged') do |target|
221
+ event_listening_ids << add_event_listener(BrowserEmittedEvents::TargetChanged) do |target|
231
222
  if predicate.call(target)
232
223
  target_promise.fulfill(target)
233
224
  end
@@ -11,29 +11,22 @@ class Puppeteer::BrowserContext
11
11
  @id = context_id
12
12
  end
13
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
14
  # @param event_name [Symbol] either of :disconnected, :targetcreated, :targetchanged, :targetdestroyed
22
15
  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(", ")}")
16
+ unless BrowserContextEmittedEvents.values.include?(event_name.to_s)
17
+ raise ArgumentError.new("Unknown event name: #{event_name}. Known events are #{BrowserContextEmittedEvents.values.to_a.join(", ")}")
25
18
  end
26
19
 
27
- add_event_listener(EVENT_MAPPINGS[event_name.to_sym], &block)
20
+ super(event_name.to_s, &block)
28
21
  end
29
22
 
30
23
  # @param event_name [Symbol]
31
24
  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(", ")}")
25
+ unless BrowserContextEmittedEvents.values.include?(event_name.to_s)
26
+ raise ArgumentError.new("Unknown event name: #{event_name}. Known events are #{BrowserContextEmittedEvents.values.to_a.join(", ")}")
34
27
  end
35
28
 
36
- observe_first(EVENT_MAPPINGS[event_name.to_sym], &block)
29
+ super(event_name.to_s, &block)
37
30
  end
38
31
 
39
32
  # @return {!Array<!Target>} target
@@ -64,42 +57,48 @@ class Puppeteer::BrowserContext
64
57
  !!@id
65
58
  end
66
59
 
67
- # /**
68
- # * @param {string} origin
69
- # * @param {!Array<string>} permissions
70
- # */
71
- # async overridePermissions(origin, permissions) {
72
- # const webPermissionToProtocol = new Map([
73
- # ['geolocation', 'geolocation'],
74
- # ['midi', 'midi'],
75
- # ['notifications', 'notifications'],
76
- # ['push', 'push'],
77
- # ['camera', 'videoCapture'],
78
- # ['microphone', 'audioCapture'],
79
- # ['background-sync', 'backgroundSync'],
80
- # ['ambient-light-sensor', 'sensors'],
81
- # ['accelerometer', 'sensors'],
82
- # ['gyroscope', 'sensors'],
83
- # ['magnetometer', 'sensors'],
84
- # ['accessibility-events', 'accessibilityEvents'],
85
- # ['clipboard-read', 'clipboardRead'],
86
- # ['clipboard-write', 'clipboardWrite'],
87
- # ['payment-handler', 'paymentHandler'],
88
- # // chrome-specific permissions we have.
89
- # ['midi-sysex', 'midiSysex'],
90
- # ]);
91
- # permissions = permissions.map(permission => {
92
- # const protocolPermission = webPermissionToProtocol.get(permission);
93
- # if (!protocolPermission)
94
- # throw new Error('Unknown permission: ' + permission);
95
- # return protocolPermission;
96
- # });
97
- # await this._connection.send('Browser.grantPermissions', {origin, browserContextId: this._id || undefined, permissions});
98
- # }
99
-
100
- # async clearPermissionOverrides() {
101
- # await this._connection.send('Browser.resetPermissions', {browserContextId: this._id || undefined});
102
- # }
60
+ WEB_PERMISSION_TO_PROTOCOL = {
61
+ 'geolocation' => 'geolocation',
62
+ 'midi' => 'midi',
63
+ 'notifications' => 'notifications',
64
+ # TODO: push isn't a valid type?
65
+ # 'push' => 'push',
66
+ 'camera' => 'videoCapture',
67
+ 'microphone' => 'audioCapture',
68
+ 'background-sync' => 'backgroundSync',
69
+ 'ambient-light-sensor' => 'sensors',
70
+ 'accelerometer' => 'sensors',
71
+ 'gyroscope' => 'sensors',
72
+ 'magnetometer' => 'sensors',
73
+ 'accessibility-events' => 'accessibilityEvents',
74
+ 'clipboard-read' => 'clipboardReadWrite',
75
+ 'clipboard-write' => 'clipboardReadWrite',
76
+ 'payment-handler' => 'paymentHandler',
77
+ 'idle-detection' => 'idleDetection',
78
+ # chrome-specific permissions we have.
79
+ 'midi-sysex' => 'midiSysex',
80
+ }.freeze
81
+
82
+ # @param origin [String]
83
+ # @param permissions [Array<String>]
84
+ def override_permissions(origin, permissions)
85
+ protocol_permissions = permissions.map do |permission|
86
+ WEB_PERMISSION_TO_PROTOCOL[permission] or raise ArgumentError.new("Unknown permission: #{permission}")
87
+ end
88
+ @connection.send_message('Browser.grantPermissions', {
89
+ origin: origin,
90
+ browserContextId: @id,
91
+ permissions: protocol_permissions,
92
+ }.compact)
93
+ end
94
+
95
+ def clear_permission_overrides
96
+ if @id
97
+ @connection.send_message('Browser.resetPermissions', browserContextId: @id)
98
+ else
99
+ @connection.send_message('Browser.resetPermissions')
100
+ end
101
+ end
103
102
 
104
103
  # @return [Future<Puppeteer::Page>]
105
104
  def new_page
@@ -14,16 +14,24 @@ class Puppeteer::BrowserRunner
14
14
  @proc = nil
15
15
  @connection = nil
16
16
  @closed = true
17
- @listeners = []
18
17
  end
19
18
 
20
19
  attr_reader :proc, :connection
21
20
 
22
21
  class BrowserProcess
23
22
  def initialize(env, executable_path, args)
23
+ @spawnargs =
24
+ if args && !args.empty?
25
+ [executable_path] + args
26
+ else
27
+ [executable_path]
28
+ end
29
+
24
30
  stdin, @stdout, @stderr, @thread = Open3.popen3(env, executable_path, *args)
25
31
  stdin.close
26
32
  @pid = @thread.pid
33
+ rescue Errno::ENOENT => err
34
+ raise LaunchError.new(err.message)
27
35
  end
28
36
 
29
37
  def kill
@@ -37,7 +45,13 @@ class Puppeteer::BrowserRunner
37
45
  @thread.join
38
46
  end
39
47
 
40
- attr_reader :stdout, :stderr
48
+ attr_reader :stdout, :stderr, :spawnargs
49
+ end
50
+
51
+ class LaunchError < StandardError
52
+ def initialize(reason)
53
+ super("Failed to launch browser! #{reason}")
54
+ end
41
55
  end
42
56
 
43
57
  # @param {!(Launcher.LaunchOptions)=} options
@@ -123,12 +137,12 @@ class Puppeteer::BrowserRunner
123
137
 
124
138
  # @return {Promise}
125
139
  def kill
126
- unless @closed
127
- @proc.kill
128
- end
129
140
  if @temp_directory
130
141
  FileUtils.rm_rf(@temp_directory)
131
142
  end
143
+ unless @closed
144
+ @proc.kill
145
+ end
132
146
  end
133
147
 
134
148