puppeteer-ruby 0.0.23 → 0.29.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 133c14dccb0da46cc01bff747bb2e36c1de1f7619ee4a8a898e798b3eb3947af
4
- data.tar.gz: a7cc95948ddef2b45cc3b4a8faa82497334daeb1e47d92c97a7cbcbf9dccd887
3
+ metadata.gz: 2b852a48cd11f269c3b4eec0a85583b120a5cd1b0bc204e27a6ec0e365aa33dd
4
+ data.tar.gz: 8864c21fe02f6e3fcbb07c6c009516e91273ecfe0636437bc41015187e9985ad
5
5
  SHA512:
6
- metadata.gz: de40a672ecbf7089e43463497bd877ed671e366ae022d6224bef0068c9ecbc5a949d4649454348af8d9823abf0e0effe84255ce3e73f8bd6f13c2d4ce2dd514e
7
- data.tar.gz: 96821b3ec521338f6c2a08c31a65113acb1aa808e1f50b9fece78bcdcc19cb6f4072b2dd6d778a5a413f47733b1efa7d3f9ded85fdd0e0dce6c1729f53be47ab
6
+ metadata.gz: dd3cdb6d7b64b0b6f6e2568eb83cad62f36ea45943f0df9cd434c6e30221ccd47b161a0368cbe02cacf4a6a3c6c6ecf293bd1313829d7f02daed5d1d2c5c9f73
7
+ data.tar.gz: 541c2dffa4c6359dff6c2d9d03e70a039057d554c1ee6509d0574d194f17a6407a968c30153bae850f8c4c0e9fa7ade7beaea2dcc8d136a896e80b22831a436f
data/.circleci/config.yml CHANGED
@@ -1,30 +1,41 @@
1
1
  version: 2.1
2
- orbs:
3
- ruby: circleci/ruby@0.1.2
2
+
3
+ rspec_chrome_job: &rspec_chrome_job
4
+ steps:
5
+ - checkout
6
+ - run:
7
+ command: gem install bundler:2.2.3 && bundle install
8
+ - run:
9
+ name: rspec
10
+ command: |
11
+ DEBUG=1 bundle exec rspec --profile 10 \
12
+ --format RspecJunitFormatter \
13
+ --out test_results/rspec.xml \
14
+ --format documentation
4
15
 
5
16
  jobs:
6
- rspec:
17
+ rspec_chrome_ruby2_6:
7
18
  docker:
8
19
  - image: circleci/ruby:2.6.6-buster-node-browsers
9
- executor: ruby/default
10
- steps:
11
- - checkout
12
- - ruby/bundle-install
13
- - run:
14
- name: rspec
15
- command: |
16
- DEBUG=1 bundle exec rspec --profile 10 \
17
- --format RspecJunitFormatter \
18
- --out test_results/rspec.xml \
19
- --format documentation
20
+ <<: *rspec_chrome_job
21
+
22
+ rspec_chrome_ruby2_7:
23
+ docker:
24
+ - image: circleci/ruby:2.7.2-buster-node-browsers
25
+ <<: *rspec_chrome_job
26
+
27
+ rspec_chrome_ruby3_0:
28
+ docker:
29
+ - image: circleci/ruby:3.0.0-buster-node-browsers
30
+ <<: *rspec_chrome_job
20
31
 
21
32
  rspec_firefox:
22
33
  docker:
23
- - image: circleci/ruby:2.6.6-buster-node-browsers
24
- executor: ruby/default
34
+ - image: circleci/ruby:2.7.2-buster-node-browsers
25
35
  steps:
26
36
  - checkout
27
- - ruby/bundle-install
37
+ - run:
38
+ command: gem install bundler:2.2.3 && bundle install
28
39
  - run:
29
40
  name: install firefox-nightly
30
41
  command: |
@@ -43,13 +54,10 @@ jobs:
43
54
  deploy:
44
55
  docker:
45
56
  - image: circleci/ruby:2.6.3-stretch-node
46
- executor: ruby/default
47
57
  steps:
48
58
  - checkout
49
59
  - run:
50
- name: Which bundler?
51
- command: bundle -v
52
- - ruby/bundle-install
60
+ command: gem install bundler:2.2.3 && bundle install
53
61
  - run:
54
62
  name: rake build
55
63
  command: rake build
@@ -70,7 +78,9 @@ jobs:
70
78
  workflows:
71
79
  ci:
72
80
  jobs:
73
- - rspec
81
+ - rspec_chrome_ruby2_6
82
+ - rspec_chrome_ruby2_7
83
+ - rspec_chrome_ruby3_0
74
84
  - rspec_firefox
75
85
  rubygems-deploy:
76
86
  jobs:
@@ -0,0 +1,17 @@
1
+ ---
2
+ name: Bug report
3
+ about: Create a report to help us improve
4
+ title: ''
5
+ labels: ''
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ ### Step To Reproduce / Observed behavior
11
+
12
+
13
+ ### Expected behavior
14
+
15
+ ### Environment
16
+
17
+ Paste the output of `ruby --version`
@@ -0,0 +1,15 @@
1
+ ---
2
+ name: Feature request
3
+ about: Request a new feature for playwright-ruby-client
4
+ title: ''
5
+ labels: ''
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ ### Simple description about the feature
11
+
12
+
13
+ ### Usecase / Motivation
14
+
15
+ <!-- Describe why the feature helps. -->
@@ -16,12 +16,12 @@ jobs:
16
16
  - name: Set up Ruby
17
17
  uses: ruby/setup-ruby@v1
18
18
  with:
19
- ruby-version: 2.6
19
+ ruby-version: 2.7
20
20
 
21
21
  - name: Install dependencies
22
22
  run: |
23
23
  gem uninstall bundler
24
- gem install bundler -v 1.17
24
+ gem install bundler -v 2.2.3
25
25
  bundle install
26
26
 
27
27
  - name: Deploy Configuration
@@ -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.90.0
15
+ rubocop_version: 1.10.0
data/CHANGELOG.md ADDED
@@ -0,0 +1,88 @@
1
+ ### master [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.29.0...master)]
2
+
3
+ * xxx
4
+
5
+ ### 0.29.0 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.28.1...0.29.0)]
6
+
7
+ New features:
8
+
9
+ * Add `AriaQueryHandler`. Now we can use "aria/...." for selectors.
10
+
11
+
12
+ ### 0.28.1 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.0.27...0.28.1)]
13
+
14
+ New features:
15
+
16
+ * Add `Page#emulate_idle_state`
17
+ * Change versioning rule.
18
+
19
+ ### 0.0.27 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.0.26...0.0.27)]
20
+
21
+ New features:
22
+
23
+ * Now puppeteer-ruby is Ruby 3.0 compatible!
24
+
25
+ ### 0.0.26 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.0.25...0.0.26)]
26
+
27
+ Bugfix:
28
+
29
+ * Fix `Page#screenshot` working correctly with `quality` parameter.
30
+
31
+ ### 0.0.25 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.0.23...0.0.25)]
32
+
33
+ New feature:
34
+
35
+ * **Cookie** feature: `Page#set_cookie`, `Page#cookies`
36
+
37
+ ### 0.0.23 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.0.22...0.0.23)]
38
+
39
+ New feature:
40
+
41
+ * **GeoLocation** feature
42
+ * grant/clear permission
43
+
44
+ Bugfix/Improvement:
45
+
46
+ * Refactoring for events ([#31](https://github.com/YusukeIwaki/puppeteer-ruby/pull/31))
47
+ * Improve SEND/RECV handling in CDPSession ([#34](https://github.com/YusukeIwaki/puppeteer-ruby/pull/34))
48
+
49
+ ### 0.0.22 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.0.21...0.0.22)]
50
+
51
+ Bugfix
52
+
53
+ * Make `Puppeteer#default_args` to work
54
+ * Respect Firefox launch options
55
+ * Respect `default_viewport: nil`
56
+
57
+ ### 0.0.21 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.0.20...0.0.21)]
58
+
59
+ Bugfix/Improvement:
60
+
61
+ * Update DeviceDescriptors (list of emulatable devices)
62
+ * Fix bug on inputing "(" ([#25](https://github.com/YusukeIwaki/puppeteer-ruby/pull/25))
63
+
64
+ ### 0.0.20 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.0.19...0.0.20)]
65
+
66
+ New feature
67
+
68
+ * Dialog-handling feature
69
+
70
+ ### 0.0.19 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.0.18...0.0.19)]
71
+
72
+ New feature
73
+
74
+ * **Firefox support**
75
+
76
+ Bugfix/Improvement
77
+
78
+ * Allow `Page#keyboard` with block ([#18](https://github.com/YusukeIwaki/puppeteer-ruby/pull/18))
79
+
80
+ ### 0.0.18 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.0.17...0.0.18)]
81
+
82
+ New feature
83
+
84
+ * **Firefox support**
85
+
86
+ Bugfix/Improvement
87
+
88
+ * Allow `Page#keyboard` with block ([#18](https://github.com/YusukeIwaki/puppeteer-ruby/pull/18))
data/Dockerfile CHANGED
@@ -1,4 +1,4 @@
1
- FROM circleci/ruby:2.6.6-buster-node-browsers
1
+ FROM circleci/ruby:3.0.0-rc1-buster-node-browsers
2
2
 
3
3
  USER root
4
4
 
data/README.md CHANGED
@@ -1,15 +1,31 @@
1
1
  [![Gem Version](https://badge.fury.io/rb/puppeteer-ruby.svg)](https://badge.fury.io/rb/puppeteer-ruby)
2
2
 
3
- # Puppeteer in Ruby [UNDER HEAVY DEVELOPMENT]
3
+ # Puppeteer in Ruby
4
4
 
5
5
  A Ruby port of [puppeteer](https://pptr.dev/).
6
6
 
7
7
  ![logo](puppeteer-ruby.png)
8
8
 
9
- REMARK: This Gem is NOT production-ready!!
9
+ REMARK: This Gem covers just a part of Puppeteer APIs. Feedbacks and feature requests are welcome :)
10
10
 
11
11
  ## Getting Started
12
12
 
13
+ ### Installation
14
+
15
+ Add this line to your application's Gemfile:
16
+
17
+ ```ruby
18
+ gem 'puppeteer-ruby'
19
+ ```
20
+
21
+ And then execute:
22
+
23
+ $ bundle
24
+
25
+ Or install it yourself as:
26
+
27
+ $ gem install puppeteer-ruby
28
+
13
29
  ### Capture a site
14
30
 
15
31
  ```ruby
data/lib/puppeteer.rb CHANGED
@@ -19,12 +19,14 @@ require 'puppeteer/event_callbackable'
19
19
  require 'puppeteer/if_present'
20
20
 
21
21
  # Classes & values.
22
+ require 'puppeteer/aria_query_handler'
22
23
  require 'puppeteer/browser'
23
24
  require 'puppeteer/browser_context'
24
25
  require 'puppeteer/browser_runner'
25
26
  require 'puppeteer/cdp_session'
26
27
  require 'puppeteer/connection'
27
28
  require 'puppeteer/console_message'
29
+ require 'puppeteer/custom_query_handler'
28
30
  require 'puppeteer/devices'
29
31
  require 'puppeteer/dialog'
30
32
  require 'puppeteer/dom_world'
@@ -41,6 +43,7 @@ require 'puppeteer/lifecycle_watcher'
41
43
  require 'puppeteer/mouse'
42
44
  require 'puppeteer/network_manager'
43
45
  require 'puppeteer/page'
46
+ require 'puppeteer/query_handler_manager'
44
47
  require 'puppeteer/remote_object'
45
48
  require 'puppeteer/request'
46
49
  require 'puppeteer/response'
@@ -0,0 +1,71 @@
1
+ class Puppeteer::AriaQueryHandler
2
+ private def normalize(value)
3
+ value.gsub(/ +/, ' ').strip
4
+ end
5
+
6
+ # @param selector [String]
7
+ private def parse_aria_selector(selector)
8
+ known_attributes = %w(name role)
9
+ query_options = {}
10
+ attribute_regexp = /\[\s*(?<attribute>\w+)\s*=\s*"(?<value>\\.|[^"\\]*)"\s*\]/
11
+ default_name = selector.gsub(attribute_regexp) do
12
+ attribute = $1.strip
13
+ value = $2
14
+ unless known_attributes.include?(attribute)
15
+ raise ArgumentError.new("Unkown aria attribute \"#{attribute}\" in selector")
16
+ end
17
+ query_options[attribute.to_sym] = normalize(value)
18
+ ''
19
+ end
20
+
21
+ if default_name.length > 0
22
+ query_options[:name] ||= normalize(default_name)
23
+ end
24
+
25
+ query_options
26
+ end
27
+
28
+ def query_one(element, selector)
29
+ context = element.execution_context
30
+ parse_result = parse_aria_selector(selector)
31
+ res = element.query_ax_tree(accessible_name: parse_result[:name], role: parse_result[:role])
32
+ if res.empty?
33
+ nil
34
+ else
35
+ context.adopt_backend_node_id(res.first['backendDOMNodeId'])
36
+ end
37
+ end
38
+
39
+ def wait_for(dom_world, selector, visible: nil, hidden: nil, timeout: nil)
40
+ binding_function = Puppeteer::DOMWorld::BindingFunction.new(
41
+ name: 'ariaQuerySelector',
42
+ proc: -> (selector) { query_one(dom_world.send(:document), selector) },
43
+ )
44
+ dom_world.send(:wait_for_selector_in_page,
45
+ '(_, selector) => globalThis.ariaQuerySelector(selector)',
46
+ selector,
47
+ visible: visible,
48
+ hidden: hidden,
49
+ timeout: timeout,
50
+ binding_function: binding_function)
51
+ end
52
+
53
+ def query_all(element, selector)
54
+ context = element.execution_context
55
+ parse_result = parse_aria_selector(selector)
56
+ res = element.query_ax_tree(accessible_name: parse_result[:name], role: parse_result[:role])
57
+ if res.empty?
58
+ nil
59
+ else
60
+ promises = res.map do |ax_node|
61
+ context.send(:async_adopt_backend_node_id, ax_node['backendDOMNodeId'])
62
+ end
63
+ await_all(*promises)
64
+ end
65
+ end
66
+
67
+ def query_all_array(element, selector)
68
+ element_handles = query_all(element, selector)
69
+ element.execution_context.evaluate_handle('(...elements) => elements', *element_handles)
70
+ end
71
+ end
@@ -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
 
@@ -125,7 +124,6 @@ class Puppeteer::Browser
125
124
  session_factory: -> { @connection.create_session(target_info) },
126
125
  ignore_https_errors: @ignore_https_errors,
127
126
  default_viewport: @default_viewport,
128
- screenshot_task_queue: @screenshot_task_queue,
129
127
  )
130
128
  # assert(!this._targets.has(event.targetInfo.targetId), 'Target should not exist before targetCreated');
131
129
  @targets[target_info.target_id] = target
@@ -39,9 +39,12 @@ module Puppeteer::ConcurrentRubyUtils
39
39
  end
40
40
  end
41
41
 
42
- def future(&block)
43
- Concurrent::Promises.future do
44
- block.call
42
+ def future(*args, &block)
43
+ Concurrent::Promises.future(*args) do |*block_args|
44
+ block.call(*block_args)
45
+ rescue Puppeteer::TimeoutError
46
+ # suppress error logging
47
+ raise
45
48
  rescue => err
46
49
  Logger.new($stderr).warn(err)
47
50
  raise err
@@ -0,0 +1,51 @@
1
+ class Puppeteer::CustomQueryHandler
2
+ # @param query_one [String] JS function (element: Element | Document, selector: string) => Element | null;
3
+ # @param query_all [String] JS function (element: Element | Document, selector: string) => Element[] | NodeListOf<Element>;
4
+ def initialize(query_one: nil, query_all: nil)
5
+ @query_one = query_one
6
+ @query_all = query_all
7
+ end
8
+
9
+ def query_one(element, selector)
10
+ unless @query_one
11
+ raise NotImplementedError.new("#{self.class}##{__method__} is not implemented.")
12
+ end
13
+
14
+ handle = element.evaluate_handle(@query_one, selector)
15
+ element = handle.as_element
16
+
17
+ if element
18
+ return element
19
+ end
20
+ handle.dispose
21
+ nil
22
+ end
23
+
24
+ def wait_for(dom_world, selector, visible: nil, hidden: nil, timeout: nil)
25
+ unless @query_one
26
+ raise NotImplementedError.new("#{self.class}##{__method__} is not implemented.")
27
+ end
28
+
29
+ dom_world.send(:wait_for_selector_in_page, @query_one, selector, visible: visible, hidden: hidden, timeout: timeout)
30
+ end
31
+
32
+ def query_all(element, selector)
33
+ unless @query_all
34
+ raise NotImplementedError.new("#{self.class}##{__method__} is not implemented.")
35
+ end
36
+
37
+ handles = element.evaluate_handle(@query_all, selector)
38
+ properties = handles.properties
39
+ handles.dispose
40
+ properties.values.map(&:as_element).compact
41
+ end
42
+
43
+ def query_all_array(element, selector)
44
+ unless @query_all
45
+ raise NotImplementedError.new("#{self.class}##{__method__} is not implemented.")
46
+ end
47
+
48
+ handles = element.evaluate_handle(@query_all, selector)
49
+ handles.evaluate_handle('(res) => Array.from(res)')
50
+ end
51
+ end