puppeteer-ruby 0.31.0 → 0.31.6

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