ferrum 0.8 → 0.11
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/LICENSE +1 -1
- data/README.md +200 -75
- data/lib/ferrum.rb +36 -8
- data/lib/ferrum/browser.rb +12 -5
- data/lib/ferrum/browser/client.rb +6 -0
- data/lib/ferrum/browser/command.rb +26 -25
- data/lib/ferrum/browser/options/base.rb +46 -0
- data/lib/ferrum/browser/options/chrome.rb +74 -0
- data/lib/ferrum/browser/options/firefox.rb +34 -0
- data/lib/ferrum/browser/process.rb +23 -11
- data/lib/ferrum/browser/subscriber.rb +5 -1
- data/lib/ferrum/browser/web_socket.rb +17 -1
- data/lib/ferrum/browser/xvfb.rb +37 -0
- data/lib/ferrum/context.rb +10 -6
- data/lib/ferrum/contexts.rb +4 -2
- data/lib/ferrum/frame.rb +1 -0
- data/lib/ferrum/frame/dom.rb +30 -30
- data/lib/ferrum/frame/runtime.rb +62 -63
- data/lib/ferrum/network.rb +23 -6
- data/lib/ferrum/network/error.rb +8 -15
- data/lib/ferrum/network/intercepted_request.rb +1 -1
- data/lib/ferrum/node.rb +61 -17
- data/lib/ferrum/page.rb +40 -13
- data/lib/ferrum/page/animation.rb +16 -0
- data/lib/ferrum/page/frames.rb +10 -2
- data/lib/ferrum/page/screenshot.rb +64 -12
- data/lib/ferrum/rbga.rb +38 -0
- data/lib/ferrum/version.rb +1 -1
- metadata +19 -10
- data/lib/ferrum/browser/chrome.rb +0 -76
- data/lib/ferrum/browser/firefox.rb +0 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c953c12b582e6d81031c8daa598f25d4f8b2dba8e6d736f227b2e8c461a83d41
|
4
|
+
data.tar.gz: 229fe35bc81a133eff2628e1b3e0e0d31d733da2b277e0dbe70c9699e80e2a15
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f48e9fac5bfbcf9959d855b1b7c7259f97d845e812f3fce6fa59dc6a3e6b5147cced16167c2a3603e964978a9d3b1e4e5b4f2c7b5b686454acaa47d1aadf6d3
|
7
|
+
data.tar.gz: aa9f267ea80365e636e8b047bc87e6d5fe6761814cbd1b59b3d14bc3350ccdd9e2199718ba57c774abdf5bc089ef000cdbd55d03d7dbd6158cee4c975ee9d9e0
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
# Ferrum - high-level API to control Chrome in Ruby
|
2
2
|
|
3
|
-
[](https://travis-ci.org/rubycdp/ferrum)
|
4
|
-
|
5
3
|
<img align="right"
|
6
4
|
width="320" height="241"
|
7
5
|
alt="Ferrum logo"
|
@@ -32,9 +30,6 @@ Web design by [Evrone](https://evrone.com/), what else
|
|
32
30
|
[we build with Ruby on Rails](https://evrone.com/ruby), what else
|
33
31
|
[we do at Evrone](https://evrone.com/cases#case-studies).
|
34
32
|
|
35
|
-
If you like this project, please consider to
|
36
|
-
_[become a backer](https://www.patreon.com/rubycdp_ferrum)_ on Patreon.
|
37
|
-
|
38
33
|
|
39
34
|
## Index
|
40
35
|
|
@@ -54,7 +49,11 @@ _[become a backer](https://www.patreon.com/rubycdp_ferrum)_ on Patreon.
|
|
54
49
|
* [Frames](https://github.com/rubycdp/ferrum#frames)
|
55
50
|
* [Frame](https://github.com/rubycdp/ferrum#frame)
|
56
51
|
* [Dialog](https://github.com/rubycdp/ferrum#dialog)
|
52
|
+
* [Animation](https://github.com/rubycdp/ferrum#animation)
|
53
|
+
* [Node](https://github.com/rubycdp/ferrum#node)
|
57
54
|
* [Thread safety](https://github.com/rubycdp/ferrum#thread-safety)
|
55
|
+
* [Development](https://github.com/rubycdp/ferrum#development)
|
56
|
+
* [Contributing](https://github.com/rubycdp/ferrum#contributing)
|
58
57
|
* [License](https://github.com/rubycdp/ferrum#license)
|
59
58
|
|
60
59
|
|
@@ -80,7 +79,7 @@ Navigate to a website and save a screenshot:
|
|
80
79
|
|
81
80
|
```ruby
|
82
81
|
browser = Ferrum::Browser.new
|
83
|
-
browser.
|
82
|
+
browser.go_to("https://google.com")
|
84
83
|
browser.screenshot(path: "google.png")
|
85
84
|
browser.quit
|
86
85
|
```
|
@@ -89,8 +88,8 @@ Interact with a page:
|
|
89
88
|
|
90
89
|
```ruby
|
91
90
|
browser = Ferrum::Browser.new
|
92
|
-
browser.
|
93
|
-
input = browser.at_xpath("//
|
91
|
+
browser.go_to("https://google.com")
|
92
|
+
input = browser.at_xpath("//input[@name='q']")
|
94
93
|
input.focus.type("Ruby headless driver for Chrome", :Enter)
|
95
94
|
browser.at_css("a > h3").text # => "rubycdp/ferrum: Ruby Chrome/Chromium driver - GitHub"
|
96
95
|
browser.quit
|
@@ -100,7 +99,7 @@ Evaluate some JavaScript and get full width/height:
|
|
100
99
|
|
101
100
|
```ruby
|
102
101
|
browser = Ferrum::Browser.new
|
103
|
-
browser.
|
102
|
+
browser.go_to("https://www.google.com/search?q=Ruby+headless+driver+for+Capybara")
|
104
103
|
width, height = browser.evaluate <<~JS
|
105
104
|
[document.documentElement.offsetWidth,
|
106
105
|
document.documentElement.offsetHeight]
|
@@ -114,7 +113,7 @@ Do any mouse movements you like:
|
|
114
113
|
```ruby
|
115
114
|
# Trace a 100x100 square
|
116
115
|
browser = Ferrum::Browser.new
|
117
|
-
browser.
|
116
|
+
browser.go_to("https://google.com")
|
118
117
|
browser.mouse
|
119
118
|
.move(x: 0, y: 0)
|
120
119
|
.down
|
@@ -147,6 +146,7 @@ Ferrum::Browser.new(options)
|
|
147
146
|
|
148
147
|
* options `Hash`
|
149
148
|
* `:headless` (Boolean) - Set browser as headless or not, `true` by default.
|
149
|
+
* `:xvfb` (Boolean) - Run browser in a virtual framebuffer, `false` by default.
|
150
150
|
* `:window_size` (Array) - The dimensions of the browser window in which to
|
151
151
|
test, expressed as a 2-element array, e.g. [1024, 768]. Default: [1024, 768]
|
152
152
|
* `:extensions` (Array[String | Hash]) - An array of paths to files or JS
|
@@ -154,11 +154,14 @@ Ferrum::Browser.new(options)
|
|
154
154
|
`["/path/to/script.js", { source: "window.secret = 'top'" }]`
|
155
155
|
* `:logger` (Object responding to `puts`) - When present, debug output is
|
156
156
|
written to this object.
|
157
|
-
* `:slowmo` (Integer | Float) - Set a delay to wait before sending command.
|
157
|
+
* `:slowmo` (Integer | Float) - Set a delay in seconds to wait before sending command.
|
158
158
|
Usefull companion of headless option, so that you have time to see changes.
|
159
159
|
* `:timeout` (Numeric) - The number of seconds we'll wait for a response when
|
160
160
|
communicating with browser. Default is 5.
|
161
161
|
* `:js_errors` (Boolean) - When true, JavaScript errors get re-raised in Ruby.
|
162
|
+
* `:pending_connection_errors` (Boolean) - When main frame is still waiting for slow responses while timeout is
|
163
|
+
reached `PendingConnectionsError` is raised. It's better to figure out why you have slow responses and fix or
|
164
|
+
block them rather than turn this setting off. Default is true.
|
162
165
|
* `:browser_name` (Symbol) - `:chrome` by default, only experimental support
|
163
166
|
for `:firefox` for now.
|
164
167
|
* `:browser_path` (String) - Path to Chrome binary, you can also set ENV
|
@@ -166,6 +169,10 @@ Ferrum::Browser.new(options)
|
|
166
169
|
* `:browser_options` (Hash) - Additional command line options,
|
167
170
|
[see them all](https://peter.sh/experiments/chromium-command-line-switches/)
|
168
171
|
e.g. `{ "ignore-certificate-errors" => nil }`
|
172
|
+
* `:ignore_default_browser_options` (Boolean) - Ferrum has a number of default
|
173
|
+
options it passes to the browser, if you set this to `true` then only
|
174
|
+
options you put in `:browser_options` will be passed to the browser,
|
175
|
+
except required ones of course.
|
169
176
|
* `:port` (Integer) - Remote debugging port for headless Chrome
|
170
177
|
* `:host` (String) - Remote debugging address for headless Chrome
|
171
178
|
* `:url` (String) - URL for a running instance of Chrome. If this is set, a
|
@@ -179,7 +186,7 @@ Ferrum::Browser.new(options)
|
|
179
186
|
|
180
187
|
## Navigation
|
181
188
|
|
182
|
-
####
|
189
|
+
#### go_to(url) : `String`
|
183
190
|
|
184
191
|
Navigate page to.
|
185
192
|
|
@@ -187,7 +194,7 @@ Navigate page to.
|
|
187
194
|
configuring driver.
|
188
195
|
|
189
196
|
```ruby
|
190
|
-
browser.
|
197
|
+
browser.go_to("https://github.com/")
|
191
198
|
```
|
192
199
|
|
193
200
|
#### back
|
@@ -195,7 +202,7 @@ browser.goto("https://github.com/")
|
|
195
202
|
Navigate to the previous page in history.
|
196
203
|
|
197
204
|
```ruby
|
198
|
-
browser.
|
205
|
+
browser.go_to("https://github.com/")
|
199
206
|
browser.at_xpath("//a").click
|
200
207
|
browser.back
|
201
208
|
```
|
@@ -205,7 +212,7 @@ browser.back
|
|
205
212
|
Navigate to the next page in history.
|
206
213
|
|
207
214
|
```ruby
|
208
|
-
browser.
|
215
|
+
browser.go_to("https://github.com/")
|
209
216
|
browser.at_xpath("//a").click
|
210
217
|
browser.back
|
211
218
|
browser.forward
|
@@ -216,7 +223,7 @@ browser.forward
|
|
216
223
|
Reload current page.
|
217
224
|
|
218
225
|
```ruby
|
219
|
-
browser.
|
226
|
+
browser.go_to("https://github.com/")
|
220
227
|
browser.refresh
|
221
228
|
```
|
222
229
|
|
@@ -225,10 +232,29 @@ browser.refresh
|
|
225
232
|
Stop all navigations and loading pending resources on the page
|
226
233
|
|
227
234
|
```ruby
|
228
|
-
browser.
|
235
|
+
browser.go_to("https://github.com/")
|
229
236
|
browser.stop
|
230
237
|
```
|
231
238
|
|
239
|
+
#### position = \*\*options
|
240
|
+
|
241
|
+
Set the position for the browser window
|
242
|
+
|
243
|
+
* options `Hash`
|
244
|
+
* :left `Integer`
|
245
|
+
* :top `Integer`
|
246
|
+
|
247
|
+
```ruby
|
248
|
+
browser.position = { left: 10, top: 20 }
|
249
|
+
```
|
250
|
+
|
251
|
+
#### position : `Array<Integer>`
|
252
|
+
|
253
|
+
Get the position for the browser window
|
254
|
+
|
255
|
+
```ruby
|
256
|
+
browser.position # => [10, 20]
|
257
|
+
```
|
232
258
|
|
233
259
|
## Finders
|
234
260
|
|
@@ -242,7 +268,7 @@ provided node.
|
|
242
268
|
* :within `Node` | `nil`
|
243
269
|
|
244
270
|
```ruby
|
245
|
-
browser.
|
271
|
+
browser.go_to("https://github.com/")
|
246
272
|
browser.at_css("a[aria-label='Issues you created']") # => Node
|
247
273
|
```
|
248
274
|
|
@@ -257,7 +283,7 @@ document or provided node.
|
|
257
283
|
* :within `Node` | `nil`
|
258
284
|
|
259
285
|
```ruby
|
260
|
-
browser.
|
286
|
+
browser.go_to("https://github.com/")
|
261
287
|
browser.css("a[aria-label='Issues you created']") # => [Node]
|
262
288
|
```
|
263
289
|
|
@@ -270,7 +296,7 @@ Find node by xpath.
|
|
270
296
|
* :within `Node` | `nil`
|
271
297
|
|
272
298
|
```ruby
|
273
|
-
browser.
|
299
|
+
browser.go_to("https://github.com/")
|
274
300
|
browser.at_xpath("//a[@aria-label='Issues you created']") # => Node
|
275
301
|
```
|
276
302
|
|
@@ -283,7 +309,7 @@ Find nodes by xpath.
|
|
283
309
|
* :within `Node` | `nil`
|
284
310
|
|
285
311
|
```ruby
|
286
|
-
browser.
|
312
|
+
browser.go_to("https://github.com/")
|
287
313
|
browser.xpath("//a[@aria-label='Issues you created']") # => [Node]
|
288
314
|
```
|
289
315
|
|
@@ -292,7 +318,7 @@ browser.xpath("//a[@aria-label='Issues you created']") # => [Node]
|
|
292
318
|
Returns current top window location href.
|
293
319
|
|
294
320
|
```ruby
|
295
|
-
browser.
|
321
|
+
browser.go_to("https://google.com/")
|
296
322
|
browser.current_url # => "https://www.google.com/"
|
297
323
|
```
|
298
324
|
|
@@ -301,7 +327,7 @@ browser.current_url # => "https://www.google.com/"
|
|
301
327
|
Returns current top window title
|
302
328
|
|
303
329
|
```ruby
|
304
|
-
browser.
|
330
|
+
browser.go_to("https://google.com/")
|
305
331
|
browser.current_title # => "Google"
|
306
332
|
```
|
307
333
|
|
@@ -310,7 +336,7 @@ browser.current_title # => "Google"
|
|
310
336
|
Returns current page's html.
|
311
337
|
|
312
338
|
```ruby
|
313
|
-
browser.
|
339
|
+
browser.go_to("https://google.com/")
|
314
340
|
browser.body # => '<html itemscope="" itemtype="http://schema.org/WebPage" lang="ru"><head>...
|
315
341
|
```
|
316
342
|
|
@@ -331,18 +357,21 @@ Saves screenshot on a disk or returns it as base64.
|
|
331
357
|
* :full `Boolean` whether you need full page screenshot or a viewport
|
332
358
|
* :selector `String` css selector for given element
|
333
359
|
* :scale `Float` zoom in/out
|
360
|
+
* :background_color `Ferrum::RGBA.new(0, 0, 0, 0.0)` to have specific background color
|
334
361
|
|
335
362
|
```ruby
|
336
|
-
browser.
|
363
|
+
browser.go_to("https://google.com/")
|
337
364
|
# Save on the disk in PNG
|
338
365
|
browser.screenshot(path: "google.png") # => 134660
|
339
366
|
# Save on the disk in JPG
|
340
367
|
browser.screenshot(path: "google.jpg") # => 30902
|
341
368
|
# Save to Base64 the whole page not only viewport and reduce quality
|
342
369
|
browser.screenshot(full: true, quality: 60) # "iVBORw0KGgoAAAANSUhEUgAABAAAAAMACAYAAAC6uhUNAAAAAXNSR0IArs4c6Q...
|
370
|
+
# Save with specific background color
|
371
|
+
browser.screenshot(background_color: Ferrum::RGBA.new(0, 0, 0, 0.0))
|
343
372
|
```
|
344
373
|
|
345
|
-
#### pdf(\*\*options) : `String` | `
|
374
|
+
#### pdf(\*\*options) : `String` | `Boolean`
|
346
375
|
|
347
376
|
Saves PDF on a disk or returns it as base64.
|
348
377
|
|
@@ -360,9 +389,21 @@ Saves PDF on a disk or returns it as base64.
|
|
360
389
|
* See other [native options](https://chromedevtools.github.io/devtools-protocol/tot/Page#method-printToPDF) you can pass
|
361
390
|
|
362
391
|
```ruby
|
363
|
-
browser.
|
392
|
+
browser.go_to("https://google.com/")
|
364
393
|
# Save to disk as a PDF
|
365
|
-
browser.pdf(path: "google.pdf", paper_width: 1.0, paper_height: 1.0) # =>
|
394
|
+
browser.pdf(path: "google.pdf", paper_width: 1.0, paper_height: 1.0) # => true
|
395
|
+
```
|
396
|
+
|
397
|
+
#### mhtml(\*\*options) : `String` | `Integer`
|
398
|
+
|
399
|
+
Saves MHTML on a disk or returns it as a string.
|
400
|
+
|
401
|
+
* options `Hash`
|
402
|
+
* :path `String` to save a file on the disk.
|
403
|
+
|
404
|
+
```ruby
|
405
|
+
browser.go_to("https://google.com/")
|
406
|
+
browser.mhtml(path: "google.mhtml") # => 87742
|
366
407
|
```
|
367
408
|
|
368
409
|
|
@@ -376,7 +417,7 @@ Returns all information about network traffic as `Network::Exchange` instance
|
|
376
417
|
which in general is a wrapper around `request`, `response` and `error`.
|
377
418
|
|
378
419
|
```ruby
|
379
|
-
browser.
|
420
|
+
browser.go_to("https://github.com/")
|
380
421
|
browser.network.traffic # => [#<Ferrum::Network::Exchange, ...]
|
381
422
|
```
|
382
423
|
|
@@ -385,7 +426,7 @@ browser.network.traffic # => [#<Ferrum::Network::Exchange, ...]
|
|
385
426
|
Page request of the main frame.
|
386
427
|
|
387
428
|
```ruby
|
388
|
-
browser.
|
429
|
+
browser.go_to("https://github.com/")
|
389
430
|
browser.network.request # => #<Ferrum::Network::Request...
|
390
431
|
```
|
391
432
|
|
@@ -394,7 +435,7 @@ browser.network.request # => #<Ferrum::Network::Request...
|
|
394
435
|
Page response of the main frame.
|
395
436
|
|
396
437
|
```ruby
|
397
|
-
browser.
|
438
|
+
browser.go_to("https://github.com/")
|
398
439
|
browser.network.response # => #<Ferrum::Network::Response...
|
399
440
|
```
|
400
441
|
|
@@ -404,7 +445,7 @@ Contains the status code of the main page response (e.g., 200 for a
|
|
404
445
|
success). This is just a shortcut for `response.status`.
|
405
446
|
|
406
447
|
```ruby
|
407
|
-
browser.
|
448
|
+
browser.go_to("https://github.com/")
|
408
449
|
browser.network.status # => 200
|
409
450
|
```
|
410
451
|
|
@@ -421,7 +462,7 @@ Waits for network idle or raises `Ferrum::TimeoutError` error
|
|
421
462
|
by default
|
422
463
|
|
423
464
|
```ruby
|
424
|
-
browser.
|
465
|
+
browser.go_to("https://example.com/")
|
425
466
|
browser.at_xpath("//a[text() = 'No UI changes button']").click
|
426
467
|
browser.network.wait_for_idle
|
427
468
|
```
|
@@ -434,7 +475,7 @@ Clear browser's cache or collected traffic.
|
|
434
475
|
|
435
476
|
```ruby
|
436
477
|
traffic = browser.network.traffic # => []
|
437
|
-
browser.
|
478
|
+
browser.go_to("https://github.com/")
|
438
479
|
traffic.size # => 51
|
439
480
|
browser.network.clear(:traffic)
|
440
481
|
traffic.size # => 0
|
@@ -462,25 +503,52 @@ browser.on(:request) do |request|
|
|
462
503
|
request.continue
|
463
504
|
end
|
464
505
|
end
|
465
|
-
browser.
|
506
|
+
browser.go_to("https://google.com")
|
466
507
|
```
|
467
508
|
|
468
|
-
#### authorize(\*\*options)
|
509
|
+
#### authorize(\*\*options, &block)
|
469
510
|
|
470
|
-
If site uses authorization you can provide credentials using this method.
|
511
|
+
If site or proxy uses authorization you can provide credentials using this method.
|
471
512
|
|
472
513
|
* options `Hash`
|
473
514
|
* :type `Symbol` `:server` | `:proxy` site or proxy authorization
|
474
515
|
* :user `String`
|
475
516
|
* :password `String`
|
517
|
+
* &block accepts authenticated request, which you must subsequently allow or deny, if you don't
|
518
|
+
care about unwanted requests just call `request.continue`.
|
476
519
|
|
477
520
|
```ruby
|
478
|
-
browser.network.authorize(user: "login", password: "pass")
|
479
|
-
browser.
|
521
|
+
browser.network.authorize(user: "login", password: "pass") { |req| req.continue }
|
522
|
+
browser.go_to("http://example.com/authenticated")
|
480
523
|
puts browser.network.status # => 200
|
481
524
|
puts browser.body # => Welcome, authenticated client
|
482
525
|
```
|
483
526
|
|
527
|
+
Since Chrome implements authorize using request interception you must continue or abort authorized requests. If you
|
528
|
+
already have code that uses interception you can use `authorize` without block, but if not you are obliged to pass
|
529
|
+
block, so this is version doesn't pass block and can work just fine:
|
530
|
+
|
531
|
+
```ruby
|
532
|
+
browser = Ferrum::Browser.new
|
533
|
+
browser.network.intercept
|
534
|
+
browser.on(:request) do |request|
|
535
|
+
if request.resource_type == "Image"
|
536
|
+
request.abort
|
537
|
+
else
|
538
|
+
request.continue
|
539
|
+
end
|
540
|
+
end
|
541
|
+
|
542
|
+
browser.network.authorize(user: "login", password: "pass", type: :proxy)
|
543
|
+
|
544
|
+
browser.go_to("https://google.com")
|
545
|
+
|
546
|
+
```
|
547
|
+
|
548
|
+
You used to call `authorize` method without block, but since it's implemented using request interception there could be
|
549
|
+
a collision with another part of your code that also uses request interception, so that authorize allows the request
|
550
|
+
while your code denies but it's too late. The block is mandatory now.
|
551
|
+
|
484
552
|
|
485
553
|
### Mouse
|
486
554
|
|
@@ -496,7 +564,7 @@ Scroll page to a given x, y
|
|
496
564
|
displayed in the upper left
|
497
565
|
|
498
566
|
```ruby
|
499
|
-
browser.
|
567
|
+
browser.go_to("https://www.google.com/search?q=Ruby+headless+driver+for+Capybara")
|
500
568
|
browser.mouse.scroll_to(0, 400)
|
501
569
|
```
|
502
570
|
|
@@ -693,6 +761,20 @@ simple value.
|
|
693
761
|
browser.execute(%(1 + 1)) # => true
|
694
762
|
```
|
695
763
|
|
764
|
+
#### evaluate_on_new_document(expression)
|
765
|
+
|
766
|
+
Evaluate JavaScript to modify things before a page load
|
767
|
+
|
768
|
+
* expression `String` should be valid JavaScript
|
769
|
+
|
770
|
+
```ruby
|
771
|
+
browser.evaluate_on_new_document <<~JS
|
772
|
+
Object.defineProperty(navigator, "languages", {
|
773
|
+
get: function() { return ["tlh"]; }
|
774
|
+
});
|
775
|
+
JS
|
776
|
+
```
|
777
|
+
|
696
778
|
#### add_script_tag(\*\*options) : `Boolean`
|
697
779
|
|
698
780
|
* options `Hash`
|
@@ -722,7 +804,7 @@ browser.add_style_tag(content: "h1 { font-size: 40px; }") # => true
|
|
722
804
|
|
723
805
|
```ruby
|
724
806
|
browser.bypass_csp # => true
|
725
|
-
browser.
|
807
|
+
browser.go_to("https://github.com/ruby-concurrency/concurrent-ruby/blob/master/docs-source/promises.in.md")
|
726
808
|
browser.refresh
|
727
809
|
browser.add_script_tag(content: "window.__injected = 42")
|
728
810
|
browser.evaluate("window.__injected") # => 42
|
@@ -736,7 +818,7 @@ browser.evaluate("window.__injected") # => 42
|
|
736
818
|
Returns all the frames current page have.
|
737
819
|
|
738
820
|
```ruby
|
739
|
-
browser.
|
821
|
+
browser.go_to("https://www.w3schools.com/tags/tag_frame.asp")
|
740
822
|
browser.frames # =>
|
741
823
|
# [
|
742
824
|
# #<Ferrum::Frame @id="C6D104CE454A025FBCF22B98DE612B12" @parent_id=nil @name=nil @state=:stopped_loading @execution_id=1>,
|
@@ -795,7 +877,7 @@ One of the states frame's in:
|
|
795
877
|
Returns current frame's location href.
|
796
878
|
|
797
879
|
```ruby
|
798
|
-
browser.
|
880
|
+
browser.go_to("https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe")
|
799
881
|
frame = browser.frames[1]
|
800
882
|
frame.url # => https://interactive-examples.mdn.mozilla.net/pages/tabbed/iframe.html
|
801
883
|
```
|
@@ -805,7 +887,7 @@ frame.url # => https://interactive-examples.mdn.mozilla.net/pages/tabbed/iframe.
|
|
805
887
|
Returns current frame's title.
|
806
888
|
|
807
889
|
```ruby
|
808
|
-
browser.
|
890
|
+
browser.go_to("https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe")
|
809
891
|
frame = browser.frames[1]
|
810
892
|
frame.title # => HTML Demo: <iframe>
|
811
893
|
```
|
@@ -815,7 +897,7 @@ frame.title # => HTML Demo: <iframe>
|
|
815
897
|
If current frame is the main frame of the page (top of the tree).
|
816
898
|
|
817
899
|
```ruby
|
818
|
-
browser.
|
900
|
+
browser.go_to("https://www.w3schools.com/tags/tag_frame.asp")
|
819
901
|
frame = browser.frame_by(id: "C09C4E4404314AAEAE85928EAC109A93")
|
820
902
|
frame.main? # => false
|
821
903
|
```
|
@@ -825,7 +907,7 @@ frame.main? # => false
|
|
825
907
|
Returns current frame's top window location href.
|
826
908
|
|
827
909
|
```ruby
|
828
|
-
browser.
|
910
|
+
browser.go_to("https://www.w3schools.com/tags/tag_frame.asp")
|
829
911
|
frame = browser.frame_by(id: "C09C4E4404314AAEAE85928EAC109A93")
|
830
912
|
frame.current_url # => "https://www.w3schools.com/tags/tag_frame.asp"
|
831
913
|
```
|
@@ -835,7 +917,7 @@ frame.current_url # => "https://www.w3schools.com/tags/tag_frame.asp"
|
|
835
917
|
Returns current frame's top window title.
|
836
918
|
|
837
919
|
```ruby
|
838
|
-
browser.
|
920
|
+
browser.go_to("https://www.w3schools.com/tags/tag_frame.asp")
|
839
921
|
frame = browser.frame_by(id: "C09C4E4404314AAEAE85928EAC109A93")
|
840
922
|
frame.current_title # => "HTML frame tag"
|
841
923
|
```
|
@@ -845,7 +927,7 @@ frame.current_title # => "HTML frame tag"
|
|
845
927
|
Returns current frame's html.
|
846
928
|
|
847
929
|
```ruby
|
848
|
-
browser.
|
930
|
+
browser.go_to("https://www.w3schools.com/tags/tag_frame.asp")
|
849
931
|
frame = browser.frame_by(id: "C09C4E4404314AAEAE85928EAC109A93")
|
850
932
|
frame.body # => "<html><head></head><body></body></html>"
|
851
933
|
```
|
@@ -855,7 +937,7 @@ frame.body # => "<html><head></head><body></body></html>"
|
|
855
937
|
Returns current frame's doctype.
|
856
938
|
|
857
939
|
```ruby
|
858
|
-
browser.
|
940
|
+
browser.go_to("https://www.w3schools.com/tags/tag_frame.asp")
|
859
941
|
browser.main_frame.doctype # => "<!DOCTYPE html>"
|
860
942
|
```
|
861
943
|
|
@@ -866,7 +948,7 @@ Sets a content of a given frame.
|
|
866
948
|
* html `String`
|
867
949
|
|
868
950
|
```ruby
|
869
|
-
browser.
|
951
|
+
browser.go_to("https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe")
|
870
952
|
frame = browser.frames[1]
|
871
953
|
frame.body # <html lang="en"><head><style>body {transition: opacity ease-in 0.2s; }...
|
872
954
|
frame.set_content("<html><head></head><body><p>lol</p></body></html>")
|
@@ -895,10 +977,59 @@ browser.on(:dialog) do |dialog|
|
|
895
977
|
dialog.dismiss
|
896
978
|
end
|
897
979
|
end
|
898
|
-
browser.
|
980
|
+
browser.go_to("https://google.com")
|
981
|
+
```
|
982
|
+
|
983
|
+
|
984
|
+
## Animation
|
985
|
+
|
986
|
+
You can slow down or speed up CSS animations.
|
987
|
+
|
988
|
+
#### playback_rate : `Integer`
|
989
|
+
|
990
|
+
Returns playback rate for CSS animations, defaults to `1`.
|
991
|
+
|
992
|
+
|
993
|
+
#### playback_rate = value
|
994
|
+
|
995
|
+
Sets playback rate of CSS animations
|
996
|
+
|
997
|
+
* value `Integer`
|
998
|
+
|
999
|
+
```ruby
|
1000
|
+
browser = Ferrum::Browser.new
|
1001
|
+
browser.playback_rate = 2000
|
1002
|
+
browser.go_to("https://google.com")
|
1003
|
+
browser.playback_rate # => 2000
|
899
1004
|
```
|
900
1005
|
|
901
1006
|
|
1007
|
+
## Node
|
1008
|
+
|
1009
|
+
#### node? : `Boolean`
|
1010
|
+
#### frame_id
|
1011
|
+
#### frame
|
1012
|
+
#### focus
|
1013
|
+
#### focusable?
|
1014
|
+
#### moving? : `Boolean`
|
1015
|
+
#### wait_for_stop_moving
|
1016
|
+
#### blur
|
1017
|
+
#### type
|
1018
|
+
#### click
|
1019
|
+
#### hover
|
1020
|
+
#### select_file
|
1021
|
+
#### at_xpath
|
1022
|
+
#### at_css
|
1023
|
+
#### xpath
|
1024
|
+
#### css
|
1025
|
+
#### text
|
1026
|
+
#### inner_text
|
1027
|
+
#### value
|
1028
|
+
#### property
|
1029
|
+
#### attribute
|
1030
|
+
#### evaluate
|
1031
|
+
|
1032
|
+
|
902
1033
|
## Thread safety ##
|
903
1034
|
|
904
1035
|
Ferrum is fully thread-safe. You can create one browser or a few as you wish and
|
@@ -912,13 +1043,13 @@ context = browser.contexts.create
|
|
912
1043
|
|
913
1044
|
t1 = Thread.new(context) do |c|
|
914
1045
|
page = c.create_page
|
915
|
-
page.
|
1046
|
+
page.go_to("https://www.google.com/search?q=Ruby+headless+driver+for+Capybara")
|
916
1047
|
page.screenshot(path: "t1.png")
|
917
1048
|
end
|
918
1049
|
|
919
1050
|
t2 = Thread.new(context) do |c|
|
920
1051
|
page = c.create_page
|
921
|
-
page.
|
1052
|
+
page.go_to("https://www.google.com/search?q=Ruby+static+typing")
|
922
1053
|
page.screenshot(path: "t2.png")
|
923
1054
|
end
|
924
1055
|
|
@@ -937,7 +1068,7 @@ browser = Ferrum::Browser.new
|
|
937
1068
|
t1 = Thread.new(browser) do |b|
|
938
1069
|
context = b.contexts.create
|
939
1070
|
page = context.create_page
|
940
|
-
page.
|
1071
|
+
page.go_to("https://www.google.com/search?q=Ruby+headless+driver+for+Capybara")
|
941
1072
|
page.screenshot(path: "t1.png")
|
942
1073
|
context.dispose
|
943
1074
|
end
|
@@ -945,7 +1076,7 @@ end
|
|
945
1076
|
t2 = Thread.new(browser) do |b|
|
946
1077
|
context = b.contexts.create
|
947
1078
|
page = context.create_page
|
948
|
-
page.
|
1079
|
+
page.go_to("https://www.google.com/search?q=Ruby+static+typing")
|
949
1080
|
page.screenshot(path: "t2.png")
|
950
1081
|
context.dispose
|
951
1082
|
end
|
@@ -956,26 +1087,20 @@ t2.join
|
|
956
1087
|
browser.quit
|
957
1088
|
```
|
958
1089
|
|
1090
|
+
## Development
|
1091
|
+
|
1092
|
+
After checking out the repo, run `bundle install` to install dependencies.
|
1093
|
+
|
1094
|
+
Then, run `bundle exec rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
1095
|
+
|
1096
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
1097
|
+
|
1098
|
+
|
1099
|
+
## Contributing
|
1100
|
+
|
1101
|
+
Bug reports and pull requests are welcome on [GitHub](https://github.com/rubycdp/ferrum).
|
959
1102
|
|
960
1103
|
## License
|
961
1104
|
|
962
|
-
|
963
|
-
|
964
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
965
|
-
a copy of this software and associated documentation files (the
|
966
|
-
"Software"), to deal in the Software without restriction, including
|
967
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
968
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
969
|
-
permit persons to whom the Software is furnished to do so, subject to
|
970
|
-
the following conditions:
|
971
|
-
|
972
|
-
The above copyright notice and this permission notice shall be
|
973
|
-
included in all copies or substantial portions of the Software.
|
974
|
-
|
975
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
976
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
977
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
978
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
979
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
980
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
981
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
1105
|
+
The gem is available as open source under the terms of the
|
1106
|
+
[MIT License](https://opensource.org/licenses/MIT).
|