puppeteer-ruby 0.0.27 → 0.31.1

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.
@@ -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
@@ -0,0 +1,65 @@
1
+ require 'singleton'
2
+
3
+ class Puppeteer::QueryHandlerManager
4
+ include Singleton
5
+
6
+ def query_handlers
7
+ @query_handlers ||= {
8
+ aria: Puppeteer::AriaQueryHandler.new,
9
+ }
10
+ end
11
+
12
+ private def default_handler
13
+ @default_handler ||= Puppeteer::CustomQueryHandler.new(
14
+ query_one: '(element, selector) => element.querySelector(selector)',
15
+ query_all: '(element, selector) => element.querySelectorAll(selector)',
16
+ )
17
+ end
18
+
19
+ class Result
20
+ def initialize(query_handler:, selector:)
21
+ @query_handler = query_handler
22
+ @selector = selector
23
+ end
24
+
25
+ def query_one(element_handle)
26
+ @query_handler.query_one(element_handle, @selector)
27
+ end
28
+
29
+ def wait_for(dom_world, visible:, hidden:, timeout:)
30
+ @query_handler.wait_for(dom_world, @selector, visible: visible, hidden: hidden, timeout: timeout)
31
+ end
32
+
33
+ def query_all(element_handle)
34
+ @query_handler.query_all(element_handle, @selector)
35
+ end
36
+
37
+ def query_all_array(element_handle)
38
+ @query_handler.query_all_array(element_handle, @selector)
39
+ end
40
+ end
41
+
42
+ def detect_query_handler(selector)
43
+ unless /^[a-zA-Z]+\// =~ selector
44
+ return Result.new(
45
+ query_handler: default_handler,
46
+ selector: selector,
47
+ )
48
+ end
49
+
50
+ chunk = selector.split("/")
51
+ name = chunk.shift
52
+ updated_selector = chunk.join("/")
53
+
54
+ query_handler = query_handlers[name.to_sym]
55
+
56
+ unless query_handler
57
+ raise ArgumentError.new("Query set to use \"#{name}\", but no query handler of that name was found")
58
+ end
59
+
60
+ Result.new(
61
+ query_handler: query_handler,
62
+ selector: updated_selector,
63
+ )
64
+ end
65
+ end
@@ -97,6 +97,18 @@ class Puppeteer::RemoteObject
97
97
  nil
98
98
  end
99
99
 
100
+ # used in ElementHandle#query_ax_tree
101
+ def query_ax_tree(client, accessible_name: nil, role: nil)
102
+ result = client.send_message('Accessibility.queryAXTree', {
103
+ objectId: @object_id,
104
+ accessibleName: accessible_name,
105
+ role: role,
106
+ }.compact)
107
+
108
+ result['nodes'].reject do |node|
109
+ node['role']['value'] == 'text'
110
+ end
111
+ end
100
112
 
101
113
  # helper#valueFromRemoteObject
102
114
  def value
@@ -1,3 +1,3 @@
1
- class Puppeteer
2
- VERSION = '0.0.27'
1
+ module Puppeteer
2
+ VERSION = '0.31.1'
3
3
  end
@@ -9,7 +9,7 @@ class Puppeteer::WaitTask
9
9
  end
10
10
  end
11
11
 
12
- def initialize(dom_world:, predicate_body:, title:, polling:, timeout:, args: [])
12
+ def initialize(dom_world:, predicate_body:, title:, polling:, timeout:, args: [], binding_function: nil)
13
13
  if polling.is_a?(String)
14
14
  if polling != 'raf' && polling != 'mutation'
15
15
  raise ArgumentError.new("Unknown polling option: #{polling}")
@@ -27,8 +27,12 @@ class Puppeteer::WaitTask
27
27
  @timeout = timeout
28
28
  @predicate_body = "return (#{predicate_body})(...args);"
29
29
  @args = args
30
+ @binding_function = binding_function
30
31
  @run_count = 0
31
- @dom_world._wait_tasks.add(self)
32
+ @dom_world.send(:_wait_tasks).add(self)
33
+ if binding_function
34
+ @dom_world.send(:_bound_functions)[binding_function.name] = binding_function
35
+ end
32
36
  @promise = resolvable_future
33
37
 
34
38
  # Since page navigation requires us to re-install the pageScript, we should track
@@ -53,8 +57,16 @@ class Puppeteer::WaitTask
53
57
 
54
58
  def rerun
55
59
  run_count = (@run_count += 1)
60
+ context = @dom_world.execution_context
61
+
62
+ return if @terminated || run_count != @run_count
63
+ if @binding_function
64
+ @dom_world.add_binding_to_context(context, @binding_function)
65
+ end
66
+ return if @terminated || run_count != @run_count
67
+
56
68
  begin
57
- success = @dom_world.execution_context.evaluate_handle(
69
+ success = context.evaluate_handle(
58
70
  WAIT_FOR_PREDICATE_PAGE_FUNCTION,
59
71
  @predicate_body,
60
72
  @polling,
@@ -103,7 +115,7 @@ class Puppeteer::WaitTask
103
115
 
104
116
  private def cleanup
105
117
  @timeout_cleared = true
106
- @dom_world._wait_tasks.delete(self)
118
+ @dom_world.send(:_wait_tasks).delete(self)
107
119
  end
108
120
 
109
121
  private define_async_method :async_rerun
@@ -18,6 +18,8 @@ class Puppeteer::WebSocket
18
18
  @socket.write(data)
19
19
  rescue Errno::EPIPE
20
20
  raise EOFError.new('already closed')
21
+ rescue Errno::ECONNRESET
22
+ raise EOFError.new('closed by remote')
21
23
  end
22
24
 
23
25
  def readpartial(maxlen = 1024)
@@ -37,6 +37,8 @@ class Puppeteer::WebSocketTransport
37
37
 
38
38
  def close
39
39
  @ws.close
40
+ rescue EOFError
41
+ # ignore EOLError. The connection is already closed.
40
42
  end
41
43
 
42
44
  def on_close(&block)
@@ -12,7 +12,9 @@ Gem::Specification.new do |spec|
12
12
  spec.homepage = 'https://github.com/YusukeIwaki/puppeteer-ruby'
13
13
 
14
14
  spec.files = Dir.chdir(File.expand_path(__dir__)) do
15
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
15
+ `git ls-files -z`.split("\x0").reject do |f|
16
+ f.match(%r{^(test|spec|features)/}) || f.include?(".git") || f.include?(".circleci") || f.start_with?("development/")
17
+ end
16
18
  end
17
19
  spec.bindir = 'exe'
18
20
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
@@ -23,11 +25,12 @@ Gem::Specification.new do |spec|
23
25
  spec.add_dependency 'mime-types', '>= 3.0'
24
26
  spec.add_development_dependency 'bundler', '~> 2.2.3'
25
27
  spec.add_development_dependency 'chunky_png'
28
+ spec.add_development_dependency 'dry-inflector'
26
29
  spec.add_development_dependency 'pry-byebug'
27
30
  spec.add_development_dependency 'rake', '~> 13.0.3'
28
31
  spec.add_development_dependency 'rspec', '~> 3.10.0 '
29
32
  spec.add_development_dependency 'rspec_junit_formatter' # for CircleCI.
30
- spec.add_development_dependency 'rubocop', '~> 1.6.1'
33
+ spec.add_development_dependency 'rubocop', '~> 1.11.0'
31
34
  spec.add_development_dependency 'rubocop-rspec'
32
35
  spec.add_development_dependency 'sinatra'
33
36
  spec.add_development_dependency 'webrick'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puppeteer-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.27
4
+ version: 0.31.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - YusukeIwaki
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-12-25 00:00:00.000000000 Z
11
+ date: 2021-03-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: dry-inflector
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: pry-byebug
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -142,14 +156,14 @@ dependencies:
142
156
  requirements:
143
157
  - - "~>"
144
158
  - !ruby/object:Gem::Version
145
- version: 1.6.1
159
+ version: 1.11.0
146
160
  type: :development
147
161
  prerelease: false
148
162
  version_requirements: !ruby/object:Gem::Requirement
149
163
  requirements:
150
164
  - - "~>"
151
165
  - !ruby/object:Gem::Version
152
- version: 1.6.1
166
+ version: 1.11.0
153
167
  - !ruby/object:Gem::Dependency
154
168
  name: rubocop-rspec
155
169
  requirement: !ruby/object:Gem::Requirement
@@ -213,14 +227,8 @@ executables: []
213
227
  extensions: []
214
228
  extra_rdoc_files: []
215
229
  files:
216
- - ".circleci/config.yml"
217
- - ".github/stale.yml"
218
- - ".github/workflows/docs.yml"
219
- - ".github/workflows/reviewdog.yml"
220
- - ".gitignore"
221
230
  - ".rspec"
222
231
  - ".rubocop.yml"
223
- - ".travis.yml"
224
232
  - CHANGELOG.md
225
233
  - Dockerfile
226
234
  - Gemfile
@@ -229,7 +237,9 @@ files:
229
237
  - bin/console
230
238
  - bin/setup
231
239
  - docker-compose.yml
240
+ - docs/api_coverage.md
232
241
  - lib/puppeteer.rb
242
+ - lib/puppeteer/aria_query_handler.rb
233
243
  - lib/puppeteer/browser.rb
234
244
  - lib/puppeteer/browser_context.rb
235
245
  - lib/puppeteer/browser_fetcher.rb
@@ -238,6 +248,7 @@ files:
238
248
  - lib/puppeteer/concurrent_ruby_utils.rb
239
249
  - lib/puppeteer/connection.rb
240
250
  - lib/puppeteer/console_message.rb
251
+ - lib/puppeteer/custom_query_handler.rb
241
252
  - lib/puppeteer/debug_print.rb
242
253
  - lib/puppeteer/define_async_method.rb
243
254
  - lib/puppeteer/device.rb
@@ -278,6 +289,8 @@ files:
278
289
  - lib/puppeteer/page/pdf_options.rb
279
290
  - lib/puppeteer/page/screenshot_options.rb
280
291
  - lib/puppeteer/page/screenshot_task_queue.rb
292
+ - lib/puppeteer/puppeteer.rb
293
+ - lib/puppeteer/query_handler_manager.rb
281
294
  - lib/puppeteer/remote_object.rb
282
295
  - lib/puppeteer/request.rb
283
296
  - lib/puppeteer/response.rb