puppeteer-ruby 0.36.0 → 0.37.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 +4 -4
- data/CHANGELOG.md +54 -49
- data/README.md +69 -0
- data/docs/api_coverage.md +3 -2
- data/lib/puppeteer/browser.rb +2 -8
- data/lib/puppeteer/browser_context.rb +1 -0
- data/lib/puppeteer/coverage.rb +11 -2
- data/lib/puppeteer/devices.rb +130 -0
- data/lib/puppeteer/dom_world.rb +10 -9
- data/lib/puppeteer/element_handle/offset.rb +28 -0
- data/lib/puppeteer/element_handle/point.rb +11 -0
- data/lib/puppeteer/element_handle.rb +27 -7
- data/lib/puppeteer/frame.rb +3 -2
- data/lib/puppeteer/js_coverage.rb +28 -7
- data/lib/puppeteer/page/screenshot_options.rb +3 -1
- data/lib/puppeteer/page.rb +15 -5
- data/lib/puppeteer/timeout_helper.rb +22 -0
- data/lib/puppeteer/tracing.rb +6 -1
- data/lib/puppeteer/version.rb +1 -1
- data/lib/puppeteer/web_socket.rb +1 -0
- data/lib/puppeteer.rb +14 -11
- data/puppeteer-ruby.gemspec +1 -1
- metadata +6 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9e46056e6227e597554a407d47c132610af952d42b1cd7c2149e2046e0d8f1bb
|
|
4
|
+
data.tar.gz: 99a5c6fd6885181e32c72086a768c60583738974a3c86a05a693af2b97b51bc3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d4b1032b52bb5a0ad92e57f0bac5fe5208b785679f1d7efff0ab335cb28478f6110979102d0ec4759ef2f86654b4d231e018aa9cdb3982dc1ffa2e985fa4c55f
|
|
7
|
+
data.tar.gz: 42f81fe580fcb85b5c57397962362c3c6b0ba7462fe210c65ee017b9e73c0a3d9d091c03a7b18f6e6d78f3a3c52572a5d0bb8284f1087412344a184e8624170d
|
data/CHANGELOG.md
CHANGED
|
@@ -1,51 +1,57 @@
|
|
|
1
|
-
### master [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.
|
|
1
|
+
### master [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.37.0...master)]
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
- xxx
|
|
4
|
+
|
|
5
|
+
### 0.37.0 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.36.0...0.37.0)]
|
|
6
|
+
|
|
7
|
+
New features:
|
|
8
|
+
|
|
9
|
+
- Some features introduced in Puppeteer 10.4
|
|
4
10
|
|
|
5
11
|
### 0.36.0 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.35.1...0.36.0)]
|
|
6
12
|
|
|
7
13
|
New features:
|
|
8
14
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
15
|
+
- Drag and Drop feature introduced in Puppeteer 10.1
|
|
16
|
+
- `Page#emulateNetworkConditions`, `Page#emulateCPUThrottling`
|
|
17
|
+
- `Page#exposeFunction`
|
|
18
|
+
- Metrics
|
|
13
19
|
|
|
14
20
|
### 0.35.1 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.35.0...0.35.1)]
|
|
15
21
|
|
|
16
22
|
New features:
|
|
17
23
|
|
|
18
|
-
|
|
24
|
+
- Allow Rails users to use this library without `require 'puppeteer'`.
|
|
19
25
|
|
|
20
26
|
### 0.35.0 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.34.3...0.35.0)]
|
|
21
27
|
|
|
22
28
|
New features:
|
|
23
29
|
|
|
24
|
-
|
|
30
|
+
- Add `channel` parameter for Puppeteer.launch. Now `channel: chrome` or `channel: chrome-canary` (chrome-beta, chrome-dev is also available) automatically detects the executablePath of Google Chrome. Windows/macOS users can also use `channel: msedge`.
|
|
25
31
|
|
|
26
32
|
### 0.34.3 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.34.2...0.34.3)]
|
|
27
33
|
|
|
28
34
|
Bugfix:
|
|
29
35
|
|
|
30
|
-
|
|
36
|
+
- Fix wait_for_xxx's timeout error type.
|
|
31
37
|
|
|
32
38
|
### 0.34.2 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.34.1...0.34.2)]
|
|
33
39
|
|
|
34
40
|
New features:
|
|
35
41
|
|
|
36
|
-
|
|
42
|
+
- Add `Page#bring_to_front`.
|
|
37
43
|
|
|
38
44
|
### 0.34.1 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.34.0...0.34.1)]
|
|
39
45
|
|
|
40
46
|
Bugfix:
|
|
41
47
|
|
|
42
|
-
|
|
48
|
+
- Fix `Page#pdf` to work without `path` parameter.
|
|
43
49
|
|
|
44
50
|
### 0.34.0 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.33.0...0.34.0)]
|
|
45
51
|
|
|
46
52
|
New features:
|
|
47
53
|
|
|
48
|
-
|
|
54
|
+
- Sync API with block
|
|
49
55
|
|
|
50
56
|
### 0.33.0 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.32.4...0.33.0)]
|
|
51
57
|
|
|
@@ -53,170 +59,169 @@ NOTE: Requires Ruby version >= 2.6 explicitly since this version.
|
|
|
53
59
|
|
|
54
60
|
Bugfix:
|
|
55
61
|
|
|
56
|
-
|
|
62
|
+
- Fix PDF options to work correctly on decimal numbers specified.
|
|
57
63
|
|
|
58
64
|
### 0.32.4 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.32.3...0.32.4)]
|
|
59
65
|
|
|
60
66
|
Bugfix:
|
|
61
67
|
|
|
62
|
-
|
|
68
|
+
- Fix `#type_text` to input '<' correctly.
|
|
63
69
|
|
|
64
70
|
### 0.32.3 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.32.2...0.32.3)]
|
|
65
71
|
|
|
66
72
|
Bugfix:
|
|
67
73
|
|
|
68
|
-
|
|
69
|
-
|
|
74
|
+
- Fix puppeteer-ruby to work on Rails in development mode.
|
|
70
75
|
|
|
71
76
|
### 0.32.2 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.32.1...0.32.2)]
|
|
72
77
|
|
|
73
78
|
Bugfix:
|
|
74
79
|
|
|
75
|
-
|
|
80
|
+
- Fix full_page option in screenshot.
|
|
76
81
|
|
|
77
82
|
### 0.32.1 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.32.0...0.32.1)]
|
|
78
83
|
|
|
79
84
|
Bugfix:
|
|
80
85
|
|
|
81
|
-
|
|
86
|
+
- Fix WebSocket to work with `wss://...` endpoint (ex. browserless.io)
|
|
82
87
|
|
|
83
88
|
### 0.32.0 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.31.6...0.32.0)]
|
|
84
89
|
|
|
85
90
|
New features:
|
|
86
91
|
|
|
87
|
-
|
|
88
|
-
|
|
92
|
+
- Tracing
|
|
93
|
+
- JS/CSS coverages
|
|
89
94
|
|
|
90
95
|
Improvement:
|
|
91
96
|
|
|
92
|
-
|
|
97
|
+
- Increase stability [#92](https://github.com/YusukeIwaki/puppeteer-ruby/pull/92)
|
|
93
98
|
|
|
94
99
|
### 0.31.6 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.31.5...0.31.6)]
|
|
95
100
|
|
|
96
101
|
Improvement:
|
|
97
102
|
|
|
98
|
-
|
|
103
|
+
- Increase stability [#87](https://github.com/YusukeIwaki/puppeteer-ruby/pull/87)
|
|
99
104
|
|
|
100
105
|
### 0.31.5 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.31.4...0.31.5)]
|
|
101
106
|
|
|
102
107
|
Bugfix:
|
|
103
108
|
|
|
104
|
-
|
|
109
|
+
- Fix file uploading to work without crash.
|
|
105
110
|
|
|
106
111
|
### 0.31.4 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.31.3...0.31.4)]
|
|
107
112
|
|
|
108
113
|
Bugfix:
|
|
109
114
|
|
|
110
|
-
|
|
115
|
+
- Fix PDF options (format, margin, omit_background) to work.
|
|
111
116
|
|
|
112
117
|
### 0.31.3 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.31.1...0.31.3)]
|
|
113
118
|
|
|
114
119
|
Bugfix:
|
|
115
120
|
|
|
116
|
-
|
|
121
|
+
- Fix `wait_for_selector` to work. _It is strongly recommended to update for 0.29.0-0.31.x users._
|
|
117
122
|
|
|
118
123
|
### 0.31.1 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.31.0...0.31.1)]
|
|
119
124
|
|
|
120
125
|
Bugfix:
|
|
121
126
|
|
|
122
|
-
|
|
127
|
+
- Fix `Page#pdf` to work on Windows.
|
|
123
128
|
|
|
124
129
|
### 0.31.0 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.30.0...0.31.0)]
|
|
125
130
|
|
|
126
131
|
New features:
|
|
127
132
|
|
|
128
|
-
|
|
133
|
+
- Now puppeteer-ruby is compatible with Windows
|
|
129
134
|
|
|
130
135
|
Bugfix:
|
|
131
136
|
|
|
132
|
-
|
|
137
|
+
- Fix `Page#add_script_tag` and `Page#add_style_tag` to work
|
|
133
138
|
|
|
134
139
|
### 0.30.0 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.29.0...0.30.0)]
|
|
135
140
|
|
|
136
141
|
New features:
|
|
137
142
|
|
|
138
|
-
|
|
143
|
+
- S, SS, Seval, SSeval is renamed to query_selector, query_selector_all, eval_on_selector, eval_on_selector_all
|
|
139
144
|
|
|
140
145
|
### 0.29.0 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.28.1...0.29.0)]
|
|
141
146
|
|
|
142
147
|
New features:
|
|
143
148
|
|
|
144
|
-
|
|
149
|
+
- Add `AriaQueryHandler`. Now we can use "aria/...." for selectors.
|
|
145
150
|
|
|
146
151
|
### 0.28.1 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.0.27...0.28.1)]
|
|
147
152
|
|
|
148
153
|
New features:
|
|
149
154
|
|
|
150
|
-
|
|
151
|
-
|
|
155
|
+
- Add `Page#emulate_idle_state`
|
|
156
|
+
- Change versioning rule.
|
|
152
157
|
|
|
153
158
|
### 0.0.27 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.0.26...0.0.27)]
|
|
154
159
|
|
|
155
160
|
New features:
|
|
156
161
|
|
|
157
|
-
|
|
162
|
+
- Now puppeteer-ruby is Ruby 3.0 compatible!
|
|
158
163
|
|
|
159
164
|
### 0.0.26 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.0.25...0.0.26)]
|
|
160
165
|
|
|
161
166
|
Bugfix:
|
|
162
167
|
|
|
163
|
-
|
|
168
|
+
- Fix `Page#screenshot` working correctly with `quality` parameter.
|
|
164
169
|
|
|
165
170
|
### 0.0.25 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.0.23...0.0.25)]
|
|
166
171
|
|
|
167
172
|
New feature:
|
|
168
173
|
|
|
169
|
-
|
|
174
|
+
- **Cookie** feature: `Page#set_cookie`, `Page#cookies`
|
|
170
175
|
|
|
171
176
|
### 0.0.23 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.0.22...0.0.23)]
|
|
172
177
|
|
|
173
178
|
New feature:
|
|
174
179
|
|
|
175
|
-
|
|
176
|
-
|
|
180
|
+
- **GeoLocation** feature
|
|
181
|
+
- grant/clear permission
|
|
177
182
|
|
|
178
183
|
Bugfix/Improvement:
|
|
179
184
|
|
|
180
|
-
|
|
181
|
-
|
|
185
|
+
- Refactoring for events ([#31](https://github.com/YusukeIwaki/puppeteer-ruby/pull/31))
|
|
186
|
+
- Improve SEND/RECV handling in CDPSession ([#34](https://github.com/YusukeIwaki/puppeteer-ruby/pull/34))
|
|
182
187
|
|
|
183
188
|
### 0.0.22 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.0.21...0.0.22)]
|
|
184
189
|
|
|
185
190
|
Bugfix
|
|
186
191
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
192
|
+
- Make `Puppeteer#default_args` to work
|
|
193
|
+
- Respect Firefox launch options
|
|
194
|
+
- Respect `default_viewport: nil`
|
|
190
195
|
|
|
191
196
|
### 0.0.21 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.0.20...0.0.21)]
|
|
192
197
|
|
|
193
198
|
Bugfix/Improvement:
|
|
194
199
|
|
|
195
|
-
|
|
196
|
-
|
|
200
|
+
- Update DeviceDescriptors (list of emulatable devices)
|
|
201
|
+
- Fix bug on inputing "(" ([#25](https://github.com/YusukeIwaki/puppeteer-ruby/pull/25))
|
|
197
202
|
|
|
198
203
|
### 0.0.20 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.0.19...0.0.20)]
|
|
199
204
|
|
|
200
205
|
New feature
|
|
201
206
|
|
|
202
|
-
|
|
207
|
+
- Dialog-handling feature
|
|
203
208
|
|
|
204
209
|
### 0.0.19 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.0.18...0.0.19)]
|
|
205
210
|
|
|
206
211
|
New feature
|
|
207
212
|
|
|
208
|
-
|
|
213
|
+
- **Firefox support**
|
|
209
214
|
|
|
210
215
|
Bugfix/Improvement
|
|
211
216
|
|
|
212
|
-
|
|
217
|
+
- Allow `Page#keyboard` with block ([#18](https://github.com/YusukeIwaki/puppeteer-ruby/pull/18))
|
|
213
218
|
|
|
214
219
|
### 0.0.18 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.0.17...0.0.18)]
|
|
215
220
|
|
|
216
221
|
New feature
|
|
217
222
|
|
|
218
|
-
|
|
223
|
+
- **Firefox support**
|
|
219
224
|
|
|
220
225
|
Bugfix/Improvement
|
|
221
226
|
|
|
222
|
-
|
|
227
|
+
- Allow `Page#keyboard` with block ([#18](https://github.com/YusukeIwaki/puppeteer-ruby/pull/18))
|
data/README.md
CHANGED
|
@@ -156,6 +156,75 @@ RSpec.describe 'hotel.testplanisphere.dev', type: :feature do
|
|
|
156
156
|
|
|
157
157
|
The detailed step of configuration can be found [here](https://github.com/YusukeIwaki/puppeteer-ruby-example/tree/master/_with_capybara-rspec).
|
|
158
158
|
|
|
159
|
+
## :bulb: Use Puppeteer methods simply without Capybara::DSL
|
|
160
|
+
|
|
161
|
+
We can also use puppeteer-ruby as it is without Capybara DSL. When you want to just test a Rails application simply with Puppeteer, refer this section.
|
|
162
|
+
|
|
163
|
+
Also, if you have trouble with handling flaky/unstable testcases in existing feature/system specs, consider replacing Capybara::DSL with raw puppeteer-ruby codes like `page.wait_for_selector(...)` or `page.wait_for_navigation { ... }`.
|
|
164
|
+
|
|
165
|
+
Capybara prepares test server even when Capybara DSL is not used.
|
|
166
|
+
|
|
167
|
+
Sample configuration is shown below. You can use it by putting the file at `spec/support/puppeteer_ruby.rb` or another location where RSpec loads on initialization.
|
|
168
|
+
|
|
169
|
+
```ruby
|
|
170
|
+
RSpec.configure do |config|
|
|
171
|
+
require 'capybara'
|
|
172
|
+
|
|
173
|
+
# This driver only requests Capybara to launch test server.
|
|
174
|
+
# Remark that no Capybara::DSL is available with this driver.
|
|
175
|
+
class CapybaraNullDriver < Capybara::Driver::Base
|
|
176
|
+
def needs_server?
|
|
177
|
+
true
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
Capybara.register_driver(:null) { CapybaraNullDriver.new }
|
|
182
|
+
|
|
183
|
+
config.around(driver: :null) do |example|
|
|
184
|
+
Capybara.current_driver = :null
|
|
185
|
+
|
|
186
|
+
# Rails server is launched here,
|
|
187
|
+
# (at the first time of accessing Capybara.current_session.server)
|
|
188
|
+
@base_url = Capybara.current_session.server.base_url
|
|
189
|
+
|
|
190
|
+
require 'puppeteer'
|
|
191
|
+
launch_options = {
|
|
192
|
+
# Use launch options as you like.
|
|
193
|
+
channel: :chrome,
|
|
194
|
+
headless: false,
|
|
195
|
+
}
|
|
196
|
+
Puppeteer.launch(**launch_options) do |browser|
|
|
197
|
+
@puppeteer_page = browser.new_page
|
|
198
|
+
example.run
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
Capybara.reset_sessions!
|
|
202
|
+
Capybara.use_default_driver
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Now, we can work with integration test using `Puppeteer::Page` in puppeteer-ruby.
|
|
208
|
+
|
|
209
|
+
```ruby
|
|
210
|
+
RSpec.describe 'Sample integration tests', driver: :null do
|
|
211
|
+
let(:page) { @puppeteer_page }
|
|
212
|
+
let(:base_url) { @base_url }
|
|
213
|
+
|
|
214
|
+
it 'should work with Puppeteer' do
|
|
215
|
+
# null driver only launches server, and Capybara::DSL is unavailable.
|
|
216
|
+
expect { visit '/' }.to raise_error(/NotImplementedError/)
|
|
217
|
+
|
|
218
|
+
page.goto("#{base_url}/")
|
|
219
|
+
|
|
220
|
+
# Automation with Puppeteer
|
|
221
|
+
h1_text = page.eval_on_selector('h1', '(el) => el.textContent')
|
|
222
|
+
expect(h1_text).to eq('It works!')
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
|
|
159
228
|
## API
|
|
160
229
|
|
|
161
230
|
https://yusukeiwaki.github.io/puppeteer-ruby-docs/
|
data/docs/api_coverage.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# API coverages
|
|
2
|
-
- Puppeteer version: v10.
|
|
3
|
-
- puppeteer-ruby version: 0.
|
|
2
|
+
- Puppeteer version: v10.4.0
|
|
3
|
+
- puppeteer-ruby version: 0.37.0
|
|
4
4
|
|
|
5
5
|
## Puppeteer
|
|
6
6
|
|
|
@@ -136,6 +136,7 @@
|
|
|
136
136
|
* waitForFileChooser => `#wait_for_file_chooser`
|
|
137
137
|
* waitForFunction => `#wait_for_function`
|
|
138
138
|
* waitForNavigation => `#wait_for_navigation`
|
|
139
|
+
* ~~waitForNetworkIdle~~
|
|
139
140
|
* waitForRequest => `#wait_for_request`
|
|
140
141
|
* waitForResponse => `#wait_for_response`
|
|
141
142
|
* waitForSelector => `#wait_for_selector`
|
data/lib/puppeteer/browser.rb
CHANGED
|
@@ -223,7 +223,7 @@ class Puppeteer::Browser
|
|
|
223
223
|
# @param predicate [Proc(Puppeteer::Target -> Boolean)]
|
|
224
224
|
# @return [Puppeteer::Target]
|
|
225
225
|
def wait_for_target(predicate:, timeout: nil)
|
|
226
|
-
|
|
226
|
+
timeout_helper = Puppeteer::TimeoutHelper.new('target', timeout_ms: timeout, default_timeout_ms: 30000)
|
|
227
227
|
existing_target = targets.find { |target| predicate.call(target) }
|
|
228
228
|
return existing_target if existing_target
|
|
229
229
|
|
|
@@ -241,15 +241,9 @@ class Puppeteer::Browser
|
|
|
241
241
|
end
|
|
242
242
|
|
|
243
243
|
begin
|
|
244
|
-
|
|
245
|
-
Timeout.timeout(timeout_in_sec) do
|
|
246
|
-
target_promise.value!
|
|
247
|
-
end
|
|
248
|
-
else
|
|
244
|
+
timeout_helper.with_timeout do
|
|
249
245
|
target_promise.value!
|
|
250
246
|
end
|
|
251
|
-
rescue Timeout::Error
|
|
252
|
-
raise Puppeteer::TimeoutError.new("waiting for target failed: timeout #{timeout}ms exceeded")
|
|
253
247
|
ensure
|
|
254
248
|
remove_event_listener(*event_listening_ids)
|
|
255
249
|
end
|
|
@@ -74,6 +74,7 @@ class Puppeteer::BrowserContext
|
|
|
74
74
|
'clipboard-read' => 'clipboardReadWrite',
|
|
75
75
|
'clipboard-write' => 'clipboardReadWrite',
|
|
76
76
|
'payment-handler' => 'paymentHandler',
|
|
77
|
+
'persistent-storage' => 'durableStorage',
|
|
77
78
|
'idle-detection' => 'idleDetection',
|
|
78
79
|
# chrome-specific permissions we have.
|
|
79
80
|
'midi-sysex' => 'midiSysex',
|
data/lib/puppeteer/coverage.rb
CHANGED
|
@@ -5,10 +5,14 @@ class Puppeteer::Coverage
|
|
|
5
5
|
@css = Puppeteer::CSSCoverage.new(client)
|
|
6
6
|
end
|
|
7
7
|
|
|
8
|
-
def start_js_coverage(
|
|
8
|
+
def start_js_coverage(
|
|
9
|
+
reset_on_navigation: nil,
|
|
10
|
+
report_anonymous_scripts: nil,
|
|
11
|
+
include_raw_script_coverage: nil)
|
|
9
12
|
@js.start(
|
|
10
13
|
reset_on_navigation: reset_on_navigation,
|
|
11
14
|
report_anonymous_scripts: report_anonymous_scripts,
|
|
15
|
+
include_raw_script_coverage: include_raw_script_coverage,
|
|
12
16
|
)
|
|
13
17
|
end
|
|
14
18
|
|
|
@@ -16,7 +20,11 @@ class Puppeteer::Coverage
|
|
|
16
20
|
@js.stop
|
|
17
21
|
end
|
|
18
22
|
|
|
19
|
-
def js_coverage(
|
|
23
|
+
def js_coverage(
|
|
24
|
+
reset_on_navigation: nil,
|
|
25
|
+
report_anonymous_scripts: nil,
|
|
26
|
+
include_raw_script_coverage: nil,
|
|
27
|
+
&block)
|
|
20
28
|
unless block
|
|
21
29
|
raise ArgumentError.new('Block must be given')
|
|
22
30
|
end
|
|
@@ -24,6 +32,7 @@ class Puppeteer::Coverage
|
|
|
24
32
|
start_js_coverage(
|
|
25
33
|
reset_on_navigation: reset_on_navigation,
|
|
26
34
|
report_anonymous_scripts: report_anonymous_scripts,
|
|
35
|
+
include_raw_script_coverage: include_raw_script_coverage,
|
|
27
36
|
)
|
|
28
37
|
block.call
|
|
29
38
|
stop_js_coverage
|
data/lib/puppeteer/devices.rb
CHANGED
|
@@ -158,6 +158,84 @@ Puppeteer::DEVICES = Hash[
|
|
|
158
158
|
isLandscape: true,
|
|
159
159
|
},
|
|
160
160
|
},
|
|
161
|
+
{
|
|
162
|
+
name: 'Galaxy S8',
|
|
163
|
+
userAgent:
|
|
164
|
+
'Mozilla/5.0 (Linux; Android 7.0; SM-G950U Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36',
|
|
165
|
+
viewport: {
|
|
166
|
+
width: 360,
|
|
167
|
+
height: 740,
|
|
168
|
+
deviceScaleFactor: 3,
|
|
169
|
+
isMobile: true,
|
|
170
|
+
hasTouch: true,
|
|
171
|
+
isLandscape: false,
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
name: 'Galaxy S8 landscape',
|
|
176
|
+
userAgent:
|
|
177
|
+
'Mozilla/5.0 (Linux; Android 7.0; SM-G950U Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36',
|
|
178
|
+
viewport: {
|
|
179
|
+
width: 740,
|
|
180
|
+
height: 360,
|
|
181
|
+
deviceScaleFactor: 3,
|
|
182
|
+
isMobile: true,
|
|
183
|
+
hasTouch: true,
|
|
184
|
+
isLandscape: true,
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
name: 'Galaxy S9+',
|
|
189
|
+
userAgent:
|
|
190
|
+
'Mozilla/5.0 (Linux; Android 8.0.0; SM-G965U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Mobile Safari/537.36',
|
|
191
|
+
viewport: {
|
|
192
|
+
width: 320,
|
|
193
|
+
height: 658,
|
|
194
|
+
deviceScaleFactor: 4.5,
|
|
195
|
+
isMobile: true,
|
|
196
|
+
hasTouch: true,
|
|
197
|
+
isLandscape: false,
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
name: 'Galaxy S9+ landscape',
|
|
202
|
+
userAgent:
|
|
203
|
+
'Mozilla/5.0 (Linux; Android 8.0.0; SM-G965U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Mobile Safari/537.36',
|
|
204
|
+
viewport: {
|
|
205
|
+
width: 658,
|
|
206
|
+
height: 320,
|
|
207
|
+
deviceScaleFactor: 4.5,
|
|
208
|
+
isMobile: true,
|
|
209
|
+
hasTouch: true,
|
|
210
|
+
isLandscape: true,
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
name: 'Galaxy Tab S4',
|
|
215
|
+
userAgent:
|
|
216
|
+
'Mozilla/5.0 (Linux; Android 8.1.0; SM-T837A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.80 Safari/537.36',
|
|
217
|
+
viewport: {
|
|
218
|
+
width: 712,
|
|
219
|
+
height: 1138,
|
|
220
|
+
deviceScaleFactor: 2.25,
|
|
221
|
+
isMobile: true,
|
|
222
|
+
hasTouch: true,
|
|
223
|
+
isLandscape: false,
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
name: 'Galaxy Tab S4 landscape',
|
|
228
|
+
userAgent:
|
|
229
|
+
'Mozilla/5.0 (Linux; Android 8.1.0; SM-T837A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.80 Safari/537.36',
|
|
230
|
+
viewport: {
|
|
231
|
+
width: 1138,
|
|
232
|
+
height: 712,
|
|
233
|
+
deviceScaleFactor: 2.25,
|
|
234
|
+
isMobile: true,
|
|
235
|
+
hasTouch: true,
|
|
236
|
+
isLandscape: true,
|
|
237
|
+
},
|
|
238
|
+
},
|
|
161
239
|
{
|
|
162
240
|
name: 'iPad',
|
|
163
241
|
userAgent:
|
|
@@ -1003,6 +1081,58 @@ Puppeteer::DEVICES = Hash[
|
|
|
1003
1081
|
isLandscape: true,
|
|
1004
1082
|
},
|
|
1005
1083
|
},
|
|
1084
|
+
{
|
|
1085
|
+
name: 'Pixel 3',
|
|
1086
|
+
userAgent:
|
|
1087
|
+
'Mozilla/5.0 (Linux; Android 9; Pixel 3 Build/PQ1A.181105.017.A1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.158 Mobile Safari/537.36',
|
|
1088
|
+
viewport: {
|
|
1089
|
+
width: 393,
|
|
1090
|
+
height: 786,
|
|
1091
|
+
deviceScaleFactor: 2.75,
|
|
1092
|
+
isMobile: true,
|
|
1093
|
+
hasTouch: true,
|
|
1094
|
+
isLandscape: false,
|
|
1095
|
+
},
|
|
1096
|
+
},
|
|
1097
|
+
{
|
|
1098
|
+
name: 'Pixel 3 landscape',
|
|
1099
|
+
userAgent:
|
|
1100
|
+
'Mozilla/5.0 (Linux; Android 9; Pixel 3 Build/PQ1A.181105.017.A1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.158 Mobile Safari/537.36',
|
|
1101
|
+
viewport: {
|
|
1102
|
+
width: 786,
|
|
1103
|
+
height: 393,
|
|
1104
|
+
deviceScaleFactor: 2.75,
|
|
1105
|
+
isMobile: true,
|
|
1106
|
+
hasTouch: true,
|
|
1107
|
+
isLandscape: true,
|
|
1108
|
+
},
|
|
1109
|
+
},
|
|
1110
|
+
{
|
|
1111
|
+
name: 'Pixel 4',
|
|
1112
|
+
userAgent:
|
|
1113
|
+
'Mozilla/5.0 (Linux; Android 10; Pixel 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Mobile Safari/537.36',
|
|
1114
|
+
viewport: {
|
|
1115
|
+
width: 353,
|
|
1116
|
+
height: 745,
|
|
1117
|
+
deviceScaleFactor: 3,
|
|
1118
|
+
isMobile: true,
|
|
1119
|
+
hasTouch: true,
|
|
1120
|
+
isLandscape: false,
|
|
1121
|
+
},
|
|
1122
|
+
},
|
|
1123
|
+
{
|
|
1124
|
+
name: 'Pixel 4 landscape',
|
|
1125
|
+
userAgent:
|
|
1126
|
+
'Mozilla/5.0 (Linux; Android 10; Pixel 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Mobile Safari/537.36',
|
|
1127
|
+
viewport: {
|
|
1128
|
+
width: 745,
|
|
1129
|
+
height: 353,
|
|
1130
|
+
deviceScaleFactor: 3,
|
|
1131
|
+
isMobile: true,
|
|
1132
|
+
hasTouch: true,
|
|
1133
|
+
isLandscape: true,
|
|
1134
|
+
},
|
|
1135
|
+
},
|
|
1006
1136
|
].map do |json|
|
|
1007
1137
|
[
|
|
1008
1138
|
json[:name],
|
data/lib/puppeteer/dom_world.rb
CHANGED
|
@@ -233,12 +233,13 @@ class Puppeteer::DOMWorld
|
|
|
233
233
|
# @param url [String?]
|
|
234
234
|
# @param path [String?]
|
|
235
235
|
# @param content [String?]
|
|
236
|
+
# @param id [String?]
|
|
236
237
|
# @param type [String?]
|
|
237
|
-
def add_script_tag(url: nil, path: nil, content: nil, type: nil)
|
|
238
|
+
def add_script_tag(url: nil, path: nil, content: nil, id: nil, type: nil)
|
|
238
239
|
if url
|
|
239
240
|
begin
|
|
240
241
|
return execution_context.
|
|
241
|
-
evaluate_handle(ADD_SCRIPT_URL, url, type || '').
|
|
242
|
+
evaluate_handle(ADD_SCRIPT_URL, url, id, type || '').
|
|
242
243
|
as_element
|
|
243
244
|
rescue Puppeteer::ExecutionContext::EvaluationError # for Chrome
|
|
244
245
|
raise "Loading script from #{url} failed"
|
|
@@ -251,13 +252,13 @@ class Puppeteer::DOMWorld
|
|
|
251
252
|
contents = File.read(path)
|
|
252
253
|
contents += "//# sourceURL=#{path.gsub(/\n/, '')}"
|
|
253
254
|
return execution_context.
|
|
254
|
-
evaluate_handle(ADD_SCRIPT_CONTENT, contents, type || '').
|
|
255
|
+
evaluate_handle(ADD_SCRIPT_CONTENT, contents, id, type || 'text/javascript').
|
|
255
256
|
as_element
|
|
256
257
|
end
|
|
257
258
|
|
|
258
259
|
if content
|
|
259
260
|
return execution_context.
|
|
260
|
-
evaluate_handle(ADD_SCRIPT_CONTENT, content, type || '').
|
|
261
|
+
evaluate_handle(ADD_SCRIPT_CONTENT, content, id, type || 'text/javascript').
|
|
261
262
|
as_element
|
|
262
263
|
end
|
|
263
264
|
|
|
@@ -265,11 +266,11 @@ class Puppeteer::DOMWorld
|
|
|
265
266
|
end
|
|
266
267
|
|
|
267
268
|
ADD_SCRIPT_URL = <<~JAVASCRIPT
|
|
268
|
-
async (url, type) => {
|
|
269
|
+
async (url, id, type) => {
|
|
269
270
|
const script = document.createElement('script');
|
|
270
271
|
script.src = url;
|
|
271
|
-
if (
|
|
272
|
-
|
|
272
|
+
if (id) script.id = id;
|
|
273
|
+
if (type) script.type = type;
|
|
273
274
|
const promise = new Promise((res, rej) => {
|
|
274
275
|
script.onload = res;
|
|
275
276
|
script.onerror = rej;
|
|
@@ -281,11 +282,11 @@ class Puppeteer::DOMWorld
|
|
|
281
282
|
JAVASCRIPT
|
|
282
283
|
|
|
283
284
|
ADD_SCRIPT_CONTENT = <<~JAVASCRIPT
|
|
284
|
-
(content, type) => {
|
|
285
|
-
if (type === undefined) type = 'text/javascript';
|
|
285
|
+
(content, id, type) => {
|
|
286
286
|
const script = document.createElement('script');
|
|
287
287
|
script.type = type;
|
|
288
288
|
script.text = content;
|
|
289
|
+
if (id) script.id = id;
|
|
289
290
|
let error = null;
|
|
290
291
|
script.onerror = e => error = e;
|
|
291
292
|
document.head.appendChild(script);
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
class Puppeteer::ElementHandle < Puppeteer::JSHandle
|
|
2
|
+
# A class to represent (x, y)-offset coordinates
|
|
3
|
+
class Offset
|
|
4
|
+
def initialize(x:, y:)
|
|
5
|
+
@x = x
|
|
6
|
+
@y = y
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def self.from(offset)
|
|
10
|
+
case offset
|
|
11
|
+
when nil
|
|
12
|
+
nil
|
|
13
|
+
when Hash
|
|
14
|
+
if offset[:x] && offset[:y]
|
|
15
|
+
Offset.new(x: offset[:x], y: offset[:y])
|
|
16
|
+
else
|
|
17
|
+
raise ArgumentError.new('offset parameter must have x, y coordinates')
|
|
18
|
+
end
|
|
19
|
+
when Offset
|
|
20
|
+
offset
|
|
21
|
+
else
|
|
22
|
+
raise ArgumentError.new('Offset.from(Hash|Offset)')
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
attr_reader :x, :y
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -21,6 +21,17 @@ class Puppeteer::ElementHandle < Puppeteer::JSHandle
|
|
|
21
21
|
)
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
+
def ==(other)
|
|
25
|
+
case other
|
|
26
|
+
when Hash
|
|
27
|
+
@x == other[:x] && @y == other[:y]
|
|
28
|
+
when Point
|
|
29
|
+
@x == other.x && @y == other.y
|
|
30
|
+
else
|
|
31
|
+
super
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
24
35
|
attr_reader :x, :y
|
|
25
36
|
end
|
|
26
37
|
end
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require_relative './element_handle/bounding_box'
|
|
2
2
|
require_relative './element_handle/box_model'
|
|
3
|
+
require_relative './element_handle/offset'
|
|
3
4
|
require_relative './element_handle/point'
|
|
4
5
|
|
|
5
6
|
class Puppeteer::ElementHandle < Puppeteer::JSHandle
|
|
@@ -79,7 +80,9 @@ class Puppeteer::ElementHandle < Puppeteer::JSHandle
|
|
|
79
80
|
end
|
|
80
81
|
end
|
|
81
82
|
|
|
82
|
-
def clickable_point
|
|
83
|
+
def clickable_point(offset = nil)
|
|
84
|
+
offset_param = Offset.from(offset)
|
|
85
|
+
|
|
83
86
|
result =
|
|
84
87
|
begin
|
|
85
88
|
@remote_object.content_quads(@client)
|
|
@@ -105,6 +108,19 @@ class Puppeteer::ElementHandle < Puppeteer::JSHandle
|
|
|
105
108
|
raise ElementNotVisibleError.new
|
|
106
109
|
end
|
|
107
110
|
|
|
111
|
+
if offset_param
|
|
112
|
+
# Return the point of the first quad identified by offset.
|
|
113
|
+
quad = quads.first
|
|
114
|
+
min_x = quad.map(&:x).min
|
|
115
|
+
min_y = quad.map(&:y).min
|
|
116
|
+
if min_x && min_y
|
|
117
|
+
return Point.new(
|
|
118
|
+
x: min_x + offset_param.x,
|
|
119
|
+
y: min_y + offset_param.y,
|
|
120
|
+
)
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
108
124
|
# Return the middle point of the first quad.
|
|
109
125
|
quads.first.reduce(:+) / 4
|
|
110
126
|
end
|
|
@@ -139,9 +155,10 @@ class Puppeteer::ElementHandle < Puppeteer::JSHandle
|
|
|
139
155
|
# @param delay [Number]
|
|
140
156
|
# @param button [String] "left"|"right"|"middle"
|
|
141
157
|
# @param click_count [Number]
|
|
142
|
-
|
|
158
|
+
# @param offset [Hash]
|
|
159
|
+
def click(delay: nil, button: nil, click_count: nil, offset: nil)
|
|
143
160
|
scroll_into_view_if_needed
|
|
144
|
-
point = clickable_point
|
|
161
|
+
point = clickable_point(offset)
|
|
145
162
|
@page.mouse.click(point.x, point.y, delay: delay, button: button, click_count: click_count)
|
|
146
163
|
end
|
|
147
164
|
|
|
@@ -436,10 +453,12 @@ class Puppeteer::ElementHandle < Puppeteer::JSHandle
|
|
|
436
453
|
define_async_method :async_Sx
|
|
437
454
|
|
|
438
455
|
# in JS, #isIntersectingViewport.
|
|
456
|
+
# @param threshold [Float|nil]
|
|
439
457
|
# @return [Boolean]
|
|
440
|
-
def intersecting_viewport?
|
|
458
|
+
def intersecting_viewport?(threshold: nil)
|
|
459
|
+
option_threshold = threshold || 0
|
|
441
460
|
js = <<~JAVASCRIPT
|
|
442
|
-
async element => {
|
|
461
|
+
async (element, threshold) => {
|
|
443
462
|
const visibleRatio = await new Promise(resolve => {
|
|
444
463
|
const observer = new IntersectionObserver(entries => {
|
|
445
464
|
resolve(entries[0].intersectionRatio);
|
|
@@ -447,11 +466,12 @@ class Puppeteer::ElementHandle < Puppeteer::JSHandle
|
|
|
447
466
|
});
|
|
448
467
|
observer.observe(element);
|
|
449
468
|
});
|
|
450
|
-
return visibleRatio
|
|
469
|
+
if (threshold === 1) return visibleRatio === 1;
|
|
470
|
+
else return visibleRatio > threshold;
|
|
451
471
|
}
|
|
452
472
|
JAVASCRIPT
|
|
453
473
|
|
|
454
|
-
evaluate(js)
|
|
474
|
+
evaluate(js, option_threshold)
|
|
455
475
|
end
|
|
456
476
|
|
|
457
477
|
# @param quad [Array<Point>]
|
data/lib/puppeteer/frame.rb
CHANGED
|
@@ -157,8 +157,9 @@ class Puppeteer::Frame
|
|
|
157
157
|
# @param path [String?]
|
|
158
158
|
# @param content [String?]
|
|
159
159
|
# @param type [String?]
|
|
160
|
-
|
|
161
|
-
|
|
160
|
+
# @param id [String?]
|
|
161
|
+
def add_script_tag(url: nil, path: nil, content: nil, type: nil, id: nil)
|
|
162
|
+
@main_world.add_script_tag(url: url, path: path, content: content, type: type, id: id)
|
|
162
163
|
end
|
|
163
164
|
|
|
164
165
|
# @param url [String?]
|
|
@@ -12,6 +12,14 @@ class Puppeteer::JSCoverage
|
|
|
12
12
|
attr_reader :url, :ranges, :text
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
+
class ItemWithRawScriptCoverage < Item
|
|
16
|
+
def initialize(url:, ranges:, text:, raw_script_coverage:)
|
|
17
|
+
super(url: url, ranges: ranges, text: text)
|
|
18
|
+
@raw_script_coverage = raw_script_coverage
|
|
19
|
+
end
|
|
20
|
+
attr_reader :raw_script_coverage
|
|
21
|
+
end
|
|
22
|
+
|
|
15
23
|
# @param client [Puppeteer::CDPSession]
|
|
16
24
|
def initialize(client)
|
|
17
25
|
@client = client
|
|
@@ -20,7 +28,10 @@ class Puppeteer::JSCoverage
|
|
|
20
28
|
@script_sources = {}
|
|
21
29
|
end
|
|
22
30
|
|
|
23
|
-
def start(
|
|
31
|
+
def start(
|
|
32
|
+
reset_on_navigation: nil,
|
|
33
|
+
report_anonymous_scripts: nil,
|
|
34
|
+
include_raw_script_coverage: nil)
|
|
24
35
|
raise 'JSCoverage is already enabled' if @enabled
|
|
25
36
|
|
|
26
37
|
@reset_on_navigation =
|
|
@@ -30,6 +41,7 @@ class Puppeteer::JSCoverage
|
|
|
30
41
|
true
|
|
31
42
|
end
|
|
32
43
|
@report_anonymous_scripts = report_anonymous_scripts || false
|
|
44
|
+
@include_raw_script_coverage = include_raw_script_coverage || false
|
|
33
45
|
@enabled = true
|
|
34
46
|
@script_urls.clear
|
|
35
47
|
@script_sources.clear
|
|
@@ -43,7 +55,7 @@ class Puppeteer::JSCoverage
|
|
|
43
55
|
await_all(
|
|
44
56
|
@client.async_send_message('Profiler.enable'),
|
|
45
57
|
@client.async_send_message('Profiler.startPreciseCoverage',
|
|
46
|
-
callCount:
|
|
58
|
+
callCount: @include_raw_script_coverage,
|
|
47
59
|
detailed: true,
|
|
48
60
|
),
|
|
49
61
|
@client.async_send_message('Debugger.enable'),
|
|
@@ -107,11 +119,20 @@ class Puppeteer::JSCoverage
|
|
|
107
119
|
end
|
|
108
120
|
end
|
|
109
121
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
122
|
+
if @include_raw_script_coverage
|
|
123
|
+
coverage << ItemWithRawScriptCoverage.new(
|
|
124
|
+
url: url,
|
|
125
|
+
ranges: convert_to_disjoint_ranges(flatten_ranges),
|
|
126
|
+
text: text,
|
|
127
|
+
raw_script_coverage: entry,
|
|
128
|
+
)
|
|
129
|
+
else
|
|
130
|
+
coverage << Item.new(
|
|
131
|
+
url: url,
|
|
132
|
+
ranges: convert_to_disjoint_ranges(flatten_ranges),
|
|
133
|
+
text: text,
|
|
134
|
+
)
|
|
135
|
+
end
|
|
115
136
|
end
|
|
116
137
|
|
|
117
138
|
coverage
|
|
@@ -15,7 +15,7 @@ class Puppeteer::Page
|
|
|
15
15
|
# @params options [Hash]
|
|
16
16
|
def initialize(options)
|
|
17
17
|
if options[:type]
|
|
18
|
-
unless [:png, :jpeg].include?(options[:type].to_sym)
|
|
18
|
+
unless [:png, :jpeg, :webp].include?(options[:type].to_sym)
|
|
19
19
|
raise ArgumentError.new("Unknown options.type value: #{options[:type]}")
|
|
20
20
|
end
|
|
21
21
|
@type = options[:type]
|
|
@@ -25,6 +25,8 @@ class Puppeteer::Page
|
|
|
25
25
|
@type = 'png'
|
|
26
26
|
elsif mime_types.include?('image/jpeg')
|
|
27
27
|
@type = 'jpeg'
|
|
28
|
+
elsif mime_types.include?('image/webp')
|
|
29
|
+
@type = 'webp'
|
|
28
30
|
else
|
|
29
31
|
raise ArgumentError.new("Unsupported screenshot mime type resolved: #{mime_types}, path: #{options[:path]}")
|
|
30
32
|
end
|
data/lib/puppeteer/page.rb
CHANGED
|
@@ -404,8 +404,9 @@ class Puppeteer::Page
|
|
|
404
404
|
# @param path [String?]
|
|
405
405
|
# @param content [String?]
|
|
406
406
|
# @param type [String?]
|
|
407
|
-
|
|
408
|
-
|
|
407
|
+
# @param id [String?]
|
|
408
|
+
def add_script_tag(url: nil, path: nil, content: nil, type: nil, id: nil)
|
|
409
|
+
main_frame.add_script_tag(url: url, path: path, content: content, type: type, id: id)
|
|
409
410
|
end
|
|
410
411
|
|
|
411
412
|
# @param url [String?]
|
|
@@ -965,7 +966,7 @@ class Puppeteer::Page
|
|
|
965
966
|
main_frame.title
|
|
966
967
|
end
|
|
967
968
|
|
|
968
|
-
# @param type [String] "png"|"jpeg"
|
|
969
|
+
# @param type [String] "png"|"jpeg"|"webp"
|
|
969
970
|
# @param path [String]
|
|
970
971
|
# @param full_page [Boolean]
|
|
971
972
|
# @param clip [Hash]
|
|
@@ -1059,11 +1060,20 @@ class Puppeteer::Page
|
|
|
1059
1060
|
|
|
1060
1061
|
# @return [Enumerable<String>]
|
|
1061
1062
|
def create_pdf_stream(options = {})
|
|
1063
|
+
timeout_helper = Puppeteer::TimeoutHelper.new('Page.printToPDF',
|
|
1064
|
+
timeout_ms: options[:timeout],
|
|
1065
|
+
default_timeout_ms: 30000)
|
|
1062
1066
|
pdf_options = PDFOptions.new(options)
|
|
1063
1067
|
omit_background = options[:omit_background]
|
|
1064
1068
|
set_transparent_background_color if omit_background
|
|
1065
|
-
result =
|
|
1066
|
-
|
|
1069
|
+
result =
|
|
1070
|
+
begin
|
|
1071
|
+
timeout_helper.with_timeout do
|
|
1072
|
+
@client.send_message('Page.printToPDF', pdf_options.page_print_args)
|
|
1073
|
+
end
|
|
1074
|
+
ensure
|
|
1075
|
+
reset_default_background_color if omit_background
|
|
1076
|
+
end
|
|
1067
1077
|
|
|
1068
1078
|
Puppeteer::ProtocolStreamReader.new(
|
|
1069
1079
|
client: @client,
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require 'timeout'
|
|
2
|
+
|
|
3
|
+
class Puppeteer::TimeoutHelper
|
|
4
|
+
# @param timeout_ms [String|Integer|nil]
|
|
5
|
+
# @param default_timeout_ms [Integer]
|
|
6
|
+
def initialize(task_name, timeout_ms:, default_timeout_ms:)
|
|
7
|
+
@task_name = task_name
|
|
8
|
+
@timeout_ms = (timeout_ms || default_timeout_ms).to_i
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def with_timeout(&block)
|
|
12
|
+
if @timeout_ms > 0
|
|
13
|
+
begin
|
|
14
|
+
Timeout.timeout(@timeout_ms / 1000.0, &block)
|
|
15
|
+
rescue Timeout::Error
|
|
16
|
+
raise Puppeteer::TimeoutError.new("waiting for #{@task_name} failed: timeout #{@timeout_ms}ms exceeded")
|
|
17
|
+
end
|
|
18
|
+
else
|
|
19
|
+
block.call
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
data/lib/puppeteer/tracing.rb
CHANGED
|
@@ -27,11 +27,16 @@ class Puppeteer::Tracing
|
|
|
27
27
|
option_categories << 'disabled-by-default-devtools.screenshot'
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
+
ex_cat = option_categories.select { |cat| cat.start_with?('-') }.map { |cat| cat[1..-1] }
|
|
31
|
+
in_cat = option_categories.reject { |cat| cat.start_with?('-') }
|
|
30
32
|
@path = path
|
|
31
33
|
@recording = true
|
|
32
34
|
@client.send_message('Tracing.start',
|
|
33
35
|
transferMode: 'ReturnAsStream',
|
|
34
|
-
|
|
36
|
+
traceConfig: {
|
|
37
|
+
excludedCategories: ex_cat,
|
|
38
|
+
includedCategories: in_cat,
|
|
39
|
+
},
|
|
35
40
|
)
|
|
36
41
|
end
|
|
37
42
|
|
data/lib/puppeteer/version.rb
CHANGED
data/lib/puppeteer/web_socket.rb
CHANGED
|
@@ -55,6 +55,7 @@ class Puppeteer::WebSocket
|
|
|
55
55
|
def initialize(url:, max_payload_size:)
|
|
56
56
|
@impl = DriverImpl.new(url)
|
|
57
57
|
@driver = ::WebSocket::Driver.client(@impl, max_length: max_payload_size)
|
|
58
|
+
@driver.set_header('User-Agent', "Puppeteer #{Puppeteer::VERSION}")
|
|
58
59
|
|
|
59
60
|
setup
|
|
60
61
|
@driver.start
|
data/lib/puppeteer.rb
CHANGED
|
@@ -54,6 +54,7 @@ require 'puppeteer/request'
|
|
|
54
54
|
require 'puppeteer/response'
|
|
55
55
|
require 'puppeteer/target'
|
|
56
56
|
require 'puppeteer/tracing'
|
|
57
|
+
require 'puppeteer/timeout_helper'
|
|
57
58
|
require 'puppeteer/timeout_settings'
|
|
58
59
|
require 'puppeteer/touch_screen'
|
|
59
60
|
require 'puppeteer/version'
|
|
@@ -66,17 +67,19 @@ require 'puppeteer/element_handle'
|
|
|
66
67
|
|
|
67
68
|
# ref: https://github.com/puppeteer/puppeteer/blob/master/lib/Puppeteer.js
|
|
68
69
|
module Puppeteer
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
)
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
70
|
+
@puppeteer ||= ::Puppeteer::Puppeteer.new(
|
|
71
|
+
project_root: __dir__,
|
|
72
|
+
preferred_revision: '706915',
|
|
73
|
+
is_puppeteer_core: true,
|
|
74
|
+
).tap do |instance|
|
|
75
|
+
instance.public_methods(false).each do |method_name|
|
|
76
|
+
define_singleton_method(method_name) do |*args, **kwargs, &block|
|
|
77
|
+
if kwargs.empty? # for Ruby < 2.7
|
|
78
|
+
@puppeteer.public_send(method_name, *args, &block)
|
|
79
|
+
else
|
|
80
|
+
@puppeteer.public_send(method_name, *args, **kwargs, &block)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
80
83
|
end
|
|
81
84
|
end
|
|
82
85
|
end
|
data/puppeteer-ruby.gemspec
CHANGED
|
@@ -32,7 +32,7 @@ Gem::Specification.new do |spec|
|
|
|
32
32
|
spec.add_development_dependency 'rollbar'
|
|
33
33
|
spec.add_development_dependency 'rspec', '~> 3.10.0 '
|
|
34
34
|
spec.add_development_dependency 'rspec_junit_formatter' # for CircleCI.
|
|
35
|
-
spec.add_development_dependency 'rubocop', '~> 1.
|
|
35
|
+
spec.add_development_dependency 'rubocop', '~> 1.21.0'
|
|
36
36
|
spec.add_development_dependency 'rubocop-rspec'
|
|
37
37
|
spec.add_development_dependency 'sinatra'
|
|
38
38
|
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.
|
|
4
|
+
version: 0.37.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- YusukeIwaki
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2021-
|
|
11
|
+
date: 2021-09-29 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: concurrent-ruby
|
|
@@ -170,14 +170,14 @@ dependencies:
|
|
|
170
170
|
requirements:
|
|
171
171
|
- - "~>"
|
|
172
172
|
- !ruby/object:Gem::Version
|
|
173
|
-
version: 1.
|
|
173
|
+
version: 1.21.0
|
|
174
174
|
type: :development
|
|
175
175
|
prerelease: false
|
|
176
176
|
version_requirements: !ruby/object:Gem::Requirement
|
|
177
177
|
requirements:
|
|
178
178
|
- - "~>"
|
|
179
179
|
- !ruby/object:Gem::Version
|
|
180
|
-
version: 1.
|
|
180
|
+
version: 1.21.0
|
|
181
181
|
- !ruby/object:Gem::Dependency
|
|
182
182
|
name: rubocop-rspec
|
|
183
183
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -274,6 +274,7 @@ files:
|
|
|
274
274
|
- lib/puppeteer/element_handle.rb
|
|
275
275
|
- lib/puppeteer/element_handle/bounding_box.rb
|
|
276
276
|
- lib/puppeteer/element_handle/box_model.rb
|
|
277
|
+
- lib/puppeteer/element_handle/offset.rb
|
|
277
278
|
- lib/puppeteer/element_handle/point.rb
|
|
278
279
|
- lib/puppeteer/emulation_manager.rb
|
|
279
280
|
- lib/puppeteer/env.rb
|
|
@@ -315,6 +316,7 @@ files:
|
|
|
315
316
|
- lib/puppeteer/request.rb
|
|
316
317
|
- lib/puppeteer/response.rb
|
|
317
318
|
- lib/puppeteer/target.rb
|
|
319
|
+
- lib/puppeteer/timeout_helper.rb
|
|
318
320
|
- lib/puppeteer/timeout_settings.rb
|
|
319
321
|
- lib/puppeteer/touch_screen.rb
|
|
320
322
|
- lib/puppeteer/tracing.rb
|