puppeteer-ruby 0.31.0 → 0.31.6

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.
data/lib/puppeteer.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  require 'concurrent'
2
2
 
3
- class Puppeteer; end
3
+ module Puppeteer; end
4
4
 
5
5
  require 'puppeteer/env'
6
6
 
@@ -43,6 +43,7 @@ require 'puppeteer/lifecycle_watcher'
43
43
  require 'puppeteer/mouse'
44
44
  require 'puppeteer/network_manager'
45
45
  require 'puppeteer/page'
46
+ require 'puppeteer/puppeteer'
46
47
  require 'puppeteer/query_handler_manager'
47
48
  require 'puppeteer/remote_object'
48
49
  require 'puppeteer/request'
@@ -59,9 +60,9 @@ require 'puppeteer/web_socket_transport'
59
60
  require 'puppeteer/element_handle'
60
61
 
61
62
  # ref: https://github.com/puppeteer/puppeteer/blob/master/lib/Puppeteer.js
62
- class Puppeteer
63
- def self.method_missing(method, *args, **kwargs, &block)
64
- @puppeteer ||= Puppeteer.new(
63
+ module Puppeteer
64
+ module_function def method_missing(method, *args, **kwargs, &block)
65
+ @puppeteer ||= ::Puppeteer::Puppeteer.new(
65
66
  project_root: __dir__,
66
67
  preferred_revision: '706915',
67
68
  is_puppeteer_core: true,
@@ -73,167 +74,4 @@ class Puppeteer
73
74
  @puppeteer.public_send(method, *args, **kwargs, &block)
74
75
  end
75
76
  end
76
-
77
- # @param project_root [String]
78
- # @param prefereed_revision [String]
79
- # @param is_puppeteer_core [String]
80
- def initialize(project_root:, preferred_revision:, is_puppeteer_core:)
81
- @project_root = project_root
82
- @preferred_revision = preferred_revision
83
- @is_puppeteer_core = is_puppeteer_core
84
- end
85
-
86
- # @param product [String]
87
- # @param executable_path [String]
88
- # @param ignore_default_args [Array<String>|nil]
89
- # @param handle_SIGINT [Boolean]
90
- # @param handle_SIGTERM [Boolean]
91
- # @param handle_SIGHUP [Boolean]
92
- # @param timeout [Integer]
93
- # @param dumpio [Boolean]
94
- # @param env [Hash]
95
- # @param pipe [Boolean]
96
- # @param args [Array<String>]
97
- # @param user_data_dir [String]
98
- # @param devtools [Boolean]
99
- # @param headless [Boolean]
100
- # @param ignore_https_errors [Boolean]
101
- # @param default_viewport [Puppeteer::Viewport|nil]
102
- # @param slow_mo [Integer]
103
- # @return [Puppeteer::Browser]
104
- def launch(
105
- product: nil,
106
- executable_path: nil,
107
- ignore_default_args: nil,
108
- handle_SIGINT: nil,
109
- handle_SIGTERM: nil,
110
- handle_SIGHUP: nil,
111
- timeout: nil,
112
- dumpio: nil,
113
- env: nil,
114
- pipe: nil,
115
- args: nil,
116
- user_data_dir: nil,
117
- devtools: nil,
118
- headless: nil,
119
- ignore_https_errors: nil,
120
- default_viewport: nil,
121
- slow_mo: nil
122
- )
123
- options = {
124
- executable_path: executable_path,
125
- ignore_default_args: ignore_default_args,
126
- handle_SIGINT: handle_SIGINT,
127
- handle_SIGTERM: handle_SIGTERM,
128
- handle_SIGHUP: handle_SIGHUP,
129
- timeout: timeout,
130
- dumpio: dumpio,
131
- env: env,
132
- pipe: pipe,
133
- args: args,
134
- user_data_dir: user_data_dir,
135
- devtools: devtools,
136
- headless: headless,
137
- ignore_https_errors: ignore_https_errors,
138
- default_viewport: default_viewport,
139
- slow_mo: slow_mo,
140
- }
141
-
142
- @product_name ||= product
143
- browser = launcher.launch(options)
144
- if block_given?
145
- begin
146
- yield(browser)
147
- ensure
148
- browser.close
149
- end
150
- else
151
- browser
152
- end
153
- end
154
-
155
- # @param browser_ws_endpoint [String]
156
- # @param browser_url [String]
157
- # @param transport [Puppeteer::WebSocketTransport]
158
- # @param ignore_https_errors [Boolean]
159
- # @param default_viewport [Puppeteer::Viewport|nil]
160
- # @param slow_mo [Integer]
161
- # @return [Puppeteer::Browser]
162
- def connect(
163
- browser_ws_endpoint: nil,
164
- browser_url: nil,
165
- transport: nil,
166
- ignore_https_errors: nil,
167
- default_viewport: nil,
168
- slow_mo: nil
169
- )
170
- options = {
171
- browser_ws_endpoint: browser_ws_endpoint,
172
- browser_url: browser_url,
173
- transport: transport,
174
- ignore_https_errors: ignore_https_errors,
175
- default_viewport: default_viewport,
176
- slow_mo: slow_mo,
177
- }.compact
178
- browser = launcher.connect(options)
179
- if block_given?
180
- begin
181
- yield(browser)
182
- ensure
183
- browser.disconnect
184
- end
185
- else
186
- browser
187
- end
188
- end
189
-
190
- # @return [String]
191
- def executable_path
192
- launcher.executable_path
193
- end
194
-
195
- private def launcher
196
- @launcher ||= Puppeteer::Launcher.new(
197
- project_root: @project_root,
198
- preferred_revision: @preferred_revision,
199
- is_puppeteer_core: @is_puppeteer_core,
200
- product: @product_name,
201
- )
202
- end
203
-
204
- # @return [String]
205
- def product
206
- launcher.product
207
- end
208
-
209
- # @return [Puppeteer::Devices]
210
- def devices
211
- Puppeteer::Devices
212
- end
213
-
214
- # # @return {Object}
215
- # def errors
216
- # # ???
217
- # end
218
-
219
- # @param args [Array<String>]
220
- # @param user_data_dir [String]
221
- # @param devtools [Boolean]
222
- # @param headless [Boolean]
223
- # @return [Array<String>]
224
- def default_args(args: nil, user_data_dir: nil, devtools: nil, headless: nil)
225
- options = {
226
- args: args,
227
- user_data_dir: user_data_dir,
228
- devtools: devtools,
229
- headless: headless,
230
- }.compact
231
- launcher.default_args(options)
232
- end
233
-
234
- # @param {!BrowserFetcher.Options=} options
235
- # @return {!BrowserFetcher}
236
- def createBrowserFetcher(options = {})
237
- BrowserFetcher.new(@project_root, options)
238
- end
239
77
  end
@@ -46,7 +46,11 @@ class Puppeteer::Connection
46
46
  @transport.on_message do |data|
47
47
  message = JSON.parse(data)
48
48
  sleep_before_handling_message(message)
49
- async_handle_message(message)
49
+ if should_handle_synchronously?(message)
50
+ handle_message(message)
51
+ else
52
+ async_handle_message(message)
53
+ end
50
54
  end
51
55
  @transport.on_close do |reason, code|
52
56
  handle_close
@@ -71,6 +75,40 @@ class Puppeteer::Connection
71
75
  sleep 0.004
72
76
  end
73
77
 
78
+ private def should_handle_synchronously?(message)
79
+ return true if message['id']
80
+
81
+ case message['method']
82
+ when nil
83
+ false
84
+ when /^Network\./
85
+ # Puppeteer doesn't handle any Network monitoring responses.
86
+ # So we don't care their handling order.
87
+ false
88
+ when /^Page\.frame/
89
+ # Page.frameAttached
90
+ # Page.frameNavigated
91
+ # Page.frameDetached
92
+ # Page.frameStoppedLoading
93
+ true
94
+ when 'Page.lifecycleEvent'
95
+ true
96
+ when /^Runtime\.executionContext/
97
+ # - Runtime.executionContextCreated
98
+ # - Runtime.executionContextDestroyed
99
+ # - Runtime.executionContextsCleared
100
+ # These events should be strictly ordered.
101
+ true
102
+ when 'Target.attachedToTarget', 'Target.detachedFromTarget'
103
+ true
104
+ when 'Target.targetCreated'
105
+ # type=page must be handled asynchronously for avoiding wait timeout...
106
+ message.dig('params', 'targetInfo', 'type') == 'browser'
107
+ else
108
+ false
109
+ end
110
+ end
111
+
74
112
  def self.from_session(session)
75
113
  session.connection
76
114
  end
@@ -183,7 +183,7 @@ class Puppeteer::ElementHandle < Puppeteer::JSHandle
183
183
  end
184
184
 
185
185
  if error_path = file_paths.find { |file_path| !File.exist?(file_path) }
186
- raise ArgmentError.new("#{error_path} does not exist or is not readable")
186
+ raise ArgumentError.new("#{error_path} does not exist or is not readable")
187
187
  end
188
188
 
189
189
  backend_node_id = @remote_object.node_info(@client)["node"]["backendNodeId"]
@@ -201,9 +201,9 @@ class Puppeteer::ElementHandle < Puppeteer::JSHandle
201
201
  element.dispatchEvent(new Event('change', { bubbles: true }));
202
202
  }
203
203
  JAVASCRIPT
204
- await this.evaluate(fn)
204
+ await evaluate(fn)
205
205
  else
206
- @remote_object.set_file_input_files(@client, file_paths, backend_node_id)
206
+ @remote_object.set_file_input_files(@client, file_paths.map { |path| File.expand_path(path) }, backend_node_id)
207
207
  end
208
208
  end
209
209
 
data/lib/puppeteer/env.rb CHANGED
@@ -20,8 +20,8 @@ class Puppeteer::Env
20
20
  end
21
21
  end
22
22
 
23
- class Puppeteer
24
- def self.env
25
- Puppeteer::Env.new
23
+ module Puppeteer
24
+ module_function def env
25
+ ::Puppeteer::Env.new
26
26
  end
27
27
  end
@@ -202,6 +202,7 @@ class Puppeteer::Page
202
202
  end
203
203
 
204
204
  attr_reader :javascript_enabled, :target
205
+ alias_method :javascript_enabled?, :javascript_enabled
205
206
 
206
207
  def browser
207
208
  @target.browser
@@ -586,6 +587,16 @@ class Puppeteer::Page
586
587
  emit_event(PageEmittedEvents::Dialog, dialog)
587
588
  end
588
589
 
590
+ private def set_transparent_background_color(&block)
591
+ @client.send_message(
592
+ 'Emulation.setDefaultBackgroundColorOverride',
593
+ color: { r: 0, g: 0, b: 0, a: 0 })
594
+ end
595
+
596
+ private def reset_default_background_color(&block)
597
+ @client.send_message('Emulation.setDefaultBackgroundColorOverride')
598
+ end
599
+
589
600
  # @return [String]
590
601
  def url
591
602
  main_frame.url
@@ -948,18 +959,14 @@ class Puppeteer::Page
948
959
  end
949
960
 
950
961
  should_set_default_background = screenshot_options.omit_background? && format == 'png'
951
- if should_set_default_background
952
- @client.send_message('Emulation.setDefaultBackgroundColorOverride', color: { r: 0, g: 0, b: 0, a: 0 })
953
- end
962
+ set_transparent_background_color if should_set_default_background
954
963
  screenshot_params = {
955
964
  format: format,
956
965
  quality: screenshot_options.quality,
957
966
  clip: clip,
958
967
  }.compact
959
968
  result = @client.send_message('Page.captureScreenshot', screenshot_params)
960
- if should_set_default_background
961
- @client.send_message('Emulation.setDefaultBackgroundColorOverride')
962
- end
969
+ reset_default_background_color if should_set_default_background
963
970
 
964
971
  if screenshot_options.full_page? && @viewport
965
972
  self.viewport = @viewport
@@ -988,7 +995,7 @@ class Puppeteer::Page
988
995
 
989
996
  def read
990
997
  out = StringIO.new
991
- File.open(@path, 'w') do |file|
998
+ File.open(@path, 'wb') do |file|
992
999
  eof = false
993
1000
  until eof
994
1001
  response = @client.send_message('IO.read', handle: @handle)
@@ -1017,7 +1024,10 @@ class Puppeteer::Page
1017
1024
  # @return [String]
1018
1025
  def pdf(options = {})
1019
1026
  pdf_options = PDFOptions.new(options)
1027
+ omit_background = options[:omit_background]
1028
+ set_transparent_background_color if omit_background
1020
1029
  result = @client.send_message('Page.printToPDF', pdf_options.page_print_args)
1030
+ reset_default_background_color if omit_background
1021
1031
  ProtocolStreamReader.new(client: @client, handle: result['stream'], path: pdf_options.path).read
1022
1032
  rescue => err
1023
1033
  if err.message.include?('PrintToPDF is not implemented')
@@ -52,24 +52,24 @@ class Puppeteer::Page
52
52
  end
53
53
 
54
54
  PAPER_FORMATS = {
55
- letter: PaperSize.new(width: 8.5, height: 11),
56
- legal: PaperSize.new(width: 8.5, height: 14),
57
- tabloid: PaperSize.new(width: 11, height: 17),
58
- ledger: PaperSize.new(width: 17, height: 11),
59
- a0: PaperSize.new(width: 33.1, height: 46.8),
60
- a1: PaperSize.new(width: 23.4, height: 33.1),
61
- a2: PaperSize.new(width: 16.54, height: 23.4),
62
- a3: PaperSize.new(width: 11.7, height: 16.54),
63
- a4: PaperSize.new(width: 8.27, height: 11.7),
64
- a5: PaperSize.new(width: 5.83, height: 8.27),
65
- a6: PaperSize.new(width: 4.13, height: 5.83),
55
+ 'letter' => PaperSize.new(width: 8.5, height: 11),
56
+ 'legal' => PaperSize.new(width: 8.5, height: 14),
57
+ 'tabloid' => PaperSize.new(width: 11, height: 17),
58
+ 'ledger' => PaperSize.new(width: 17, height: 11),
59
+ 'a0' => PaperSize.new(width: 33.1, height: 46.8),
60
+ 'a1' => PaperSize.new(width: 23.4, height: 33.1),
61
+ 'a2' => PaperSize.new(width: 16.54, height: 23.4),
62
+ 'a3' => PaperSize.new(width: 11.7, height: 16.54),
63
+ 'a4' => PaperSize.new(width: 8.27, height: 11.7),
64
+ 'a5' => PaperSize.new(width: 5.83, height: 8.27),
65
+ 'a6' => PaperSize.new(width: 4.13, height: 5.83),
66
66
  }
67
67
 
68
68
  UNIT_TO_PIXELS = {
69
- px: 1,
70
- in: 96,
71
- cm: 37.8,
72
- mm: 3.78,
69
+ 'px' => 1,
70
+ 'in' => 96,
71
+ 'cm' => 37.8,
72
+ 'mm' => 3.78,
73
73
  }
74
74
 
75
75
  # @param parameter [String|Integer|nil]
@@ -0,0 +1,164 @@
1
+ class Puppeteer::Puppeteer
2
+ # @param project_root [String]
3
+ # @param prefereed_revision [String]
4
+ # @param is_puppeteer_core [String]
5
+ def initialize(project_root:, preferred_revision:, is_puppeteer_core:)
6
+ @project_root = project_root
7
+ @preferred_revision = preferred_revision
8
+ @is_puppeteer_core = is_puppeteer_core
9
+ end
10
+
11
+ # @param product [String]
12
+ # @param executable_path [String]
13
+ # @param ignore_default_args [Array<String>|nil]
14
+ # @param handle_SIGINT [Boolean]
15
+ # @param handle_SIGTERM [Boolean]
16
+ # @param handle_SIGHUP [Boolean]
17
+ # @param timeout [Integer]
18
+ # @param dumpio [Boolean]
19
+ # @param env [Hash]
20
+ # @param pipe [Boolean]
21
+ # @param args [Array<String>]
22
+ # @param user_data_dir [String]
23
+ # @param devtools [Boolean]
24
+ # @param headless [Boolean]
25
+ # @param ignore_https_errors [Boolean]
26
+ # @param default_viewport [Puppeteer::Viewport|nil]
27
+ # @param slow_mo [Integer]
28
+ # @return [Puppeteer::Browser]
29
+ def launch(
30
+ product: nil,
31
+ executable_path: nil,
32
+ ignore_default_args: nil,
33
+ handle_SIGINT: nil,
34
+ handle_SIGTERM: nil,
35
+ handle_SIGHUP: nil,
36
+ timeout: nil,
37
+ dumpio: nil,
38
+ env: nil,
39
+ pipe: nil,
40
+ args: nil,
41
+ user_data_dir: nil,
42
+ devtools: nil,
43
+ headless: nil,
44
+ ignore_https_errors: nil,
45
+ default_viewport: nil,
46
+ slow_mo: nil
47
+ )
48
+ options = {
49
+ executable_path: executable_path,
50
+ ignore_default_args: ignore_default_args,
51
+ handle_SIGINT: handle_SIGINT,
52
+ handle_SIGTERM: handle_SIGTERM,
53
+ handle_SIGHUP: handle_SIGHUP,
54
+ timeout: timeout,
55
+ dumpio: dumpio,
56
+ env: env,
57
+ pipe: pipe,
58
+ args: args,
59
+ user_data_dir: user_data_dir,
60
+ devtools: devtools,
61
+ headless: headless,
62
+ ignore_https_errors: ignore_https_errors,
63
+ default_viewport: default_viewport,
64
+ slow_mo: slow_mo,
65
+ }
66
+
67
+ @product_name ||= product
68
+ browser = launcher.launch(options)
69
+ if block_given?
70
+ begin
71
+ yield(browser)
72
+ ensure
73
+ browser.close
74
+ end
75
+ else
76
+ browser
77
+ end
78
+ end
79
+
80
+ # @param browser_ws_endpoint [String]
81
+ # @param browser_url [String]
82
+ # @param transport [Puppeteer::WebSocketTransport]
83
+ # @param ignore_https_errors [Boolean]
84
+ # @param default_viewport [Puppeteer::Viewport|nil]
85
+ # @param slow_mo [Integer]
86
+ # @return [Puppeteer::Browser]
87
+ def connect(
88
+ browser_ws_endpoint: nil,
89
+ browser_url: nil,
90
+ transport: nil,
91
+ ignore_https_errors: nil,
92
+ default_viewport: nil,
93
+ slow_mo: nil
94
+ )
95
+ options = {
96
+ browser_ws_endpoint: browser_ws_endpoint,
97
+ browser_url: browser_url,
98
+ transport: transport,
99
+ ignore_https_errors: ignore_https_errors,
100
+ default_viewport: default_viewport,
101
+ slow_mo: slow_mo,
102
+ }.compact
103
+ browser = launcher.connect(options)
104
+ if block_given?
105
+ begin
106
+ yield(browser)
107
+ ensure
108
+ browser.disconnect
109
+ end
110
+ else
111
+ browser
112
+ end
113
+ end
114
+
115
+ # @return [String]
116
+ def executable_path
117
+ launcher.executable_path
118
+ end
119
+
120
+ private def launcher
121
+ @launcher ||= Puppeteer::Launcher.new(
122
+ project_root: @project_root,
123
+ preferred_revision: @preferred_revision,
124
+ is_puppeteer_core: @is_puppeteer_core,
125
+ product: @product_name,
126
+ )
127
+ end
128
+
129
+ # @return [String]
130
+ def product
131
+ launcher.product
132
+ end
133
+
134
+ # @return [Puppeteer::Devices]
135
+ def devices
136
+ Puppeteer::Devices
137
+ end
138
+
139
+ # # @return {Object}
140
+ # def errors
141
+ # # ???
142
+ # end
143
+
144
+ # @param args [Array<String>]
145
+ # @param user_data_dir [String]
146
+ # @param devtools [Boolean]
147
+ # @param headless [Boolean]
148
+ # @return [Array<String>]
149
+ def default_args(args: nil, user_data_dir: nil, devtools: nil, headless: nil)
150
+ options = {
151
+ args: args,
152
+ user_data_dir: user_data_dir,
153
+ devtools: devtools,
154
+ headless: headless,
155
+ }.compact
156
+ launcher.default_args(options)
157
+ end
158
+
159
+ # @param {!BrowserFetcher.Options=} options
160
+ # @return {!BrowserFetcher}
161
+ def createBrowserFetcher(options = {})
162
+ BrowserFetcher.new(@project_root, options)
163
+ end
164
+ end