ferrum 0.7 → 0.10.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 34f864b5679986d8580fee118735ea2bf62b5b35f1d2ae9f403cdc08168d1d48
4
- data.tar.gz: 5899a23fdf4219dfd7aa70b7f1d72d0dcee167a6102b07a5062c36b8c4588f90
3
+ metadata.gz: a2256dbc8ed2c2fca2e3209c13e29009c69b4c2ccf328e8a73ade73ed69c89f0
4
+ data.tar.gz: 8d5604f8d4f8120b699ec3e341c37f77f25e90a794d3206660ecc0465b22e7b1
5
5
  SHA512:
6
- metadata.gz: 3732e2ba120edbd7e1d28759d6d9fe75c4416f41cc08a535e63751324faec35117a805de3dfdb1467fa3aa55c2885b8c7058d1fce46bb0b69e642210f89bac26
7
- data.tar.gz: 426b53078a92ddc04187250335c200dd35dac489eb2fe887f07a7ae8bb07f0652588d278ef18d7389221f692ae3b55488cedfcec0ea8511b57d9ebc9776060db
6
+ metadata.gz: 7aa18fd5a01f387c27ade8ecdf6aa30df8118f4e90badddc242ed979e5be49c890036049f284555a937ccc79699bcbc954d62c077f45ff0770d9eeeec255a6ea
7
+ data.tar.gz: 25c4cc92e59a297a344cf85301a21c3f9e634f25ea685eb6c9d2f4ea1896fcba2898dc5f4cfcc8f3af358001a0e451034bb79bf24981e16a17a51cdd3f07d6a3
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2019 Dmitry Vorotilin
3
+ Copyright (c) 2019-2020 Dmitry Vorotilin
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,62 +1,83 @@
1
- # Ferrum - fearless Ruby Chrome driver
1
+ # Ferrum - high-level API to control Chrome in Ruby
2
2
 
3
- [![Build Status](https://travis-ci.org/route/ferrum.svg?branch=master)](https://travis-ci.org/route/ferrum)
4
-
5
- <img align="right" width="95" height="95"
3
+ <img align="right"
4
+ width="320" height="241"
6
5
  alt="Ferrum logo"
7
- src="https://raw.githubusercontent.com/route/ferrum/master/logo.svg?sanitize=true">
6
+ src="https://raw.githubusercontent.com/rubycdp/ferrum/master/logo.svg?sanitize=true">
7
+
8
+ #### As simple as Puppeteer, though even simpler.
8
9
 
9
- As simple as Puppeteer, though even simpler.
10
+ It is Ruby clean and high-level API to Chrome. Runs headless by default, but you
11
+ can configure it to run in a headful mode. All you need is Ruby and
12
+ [Chrome](https://www.google.com/chrome/) or
13
+ [Chromium](https://www.chromium.org/). Ferrum connects to the browser by [CDP
14
+ protocol](https://chromedevtools.github.io/devtools-protocol/) and there's _no_
15
+ Selenium/WebDriver/ChromeDriver dependency. The emphasis was made on a raw CDP
16
+ protocol because Chrome allows you to do so many things that are barely
17
+ supported by WebDriver because it should have consistent design with other
18
+ browsers.
10
19
 
11
- It is Ruby clean and high-level API to Chrome. Runs headless by default,
12
- but you can configure it to run in a non-headless mode. All you need is Ruby and
13
- Chrome/Chromium. Ferrum connects to the browser via DevTools Protocol.
20
+ * [Cuprite](https://github.com/rubycdp/cuprite) is a pure Ruby driver for
21
+ [Capybara](https://github.com/teamcapybara/capybara) based on Ferrum. If you are
22
+ going to crawl sites you better use Ferrum or
23
+ [Vessel](https://github.com/rubycdp/vessel) because you crawl, not test.
14
24
 
15
- [Cuprite](https://github.com/machinio/cuprite) used to have this code inside in
16
- one form or another but the thing is you don't need Capybara if you are going to
17
- crawl sites. You crawl, not test. Besides that clean lightweight API to browser
18
- is what Ruby was missing, so here it comes.
25
+ * [Vessel](https://github.com/rubycdp/vessel) high-level web crawling framework
26
+ based on Ferrum. It looks like [Scrapy](https://scrapy.org/) except that it uses
27
+ a real browser in order to grab data.
19
28
 
20
- [Vessel](https://github.com/route/vessel) high-level web crawling framework
21
- based on Ferrum.
29
+ Web design by [Evrone](https://evrone.com/), what else
30
+ [we build with Ruby on Rails](https://evrone.com/ruby), what else
31
+ [we do at Evrone](https://evrone.com/cases#case-studies).
22
32
 
23
- If you like this project, please consider to _[become a backer](https://www.patreon.com/rferrum)_
24
- on Patreon.
25
33
 
26
34
  ## Index
27
35
 
28
- * [Customization](https://github.com/route/ferrum#customization)
29
- * [Navigation](https://github.com/route/ferrum#navigation)
30
- * [Finders](https://github.com/route/ferrum#finders)
31
- * [Screenshots](https://github.com/route/ferrum#screenshots)
32
- * [Network](https://github.com/route/ferrum#network)
33
- * [Mouse](https://github.com/route/ferrum#mouse)
34
- * [Keyboard](https://github.com/route/ferrum#keyboard)
35
- * [Cookies](https://github.com/route/ferrum#cookies)
36
- * [Headers](https://github.com/route/ferrum#headers)
37
- * [JavaScript](https://github.com/route/ferrum#javascript)
38
- * [Frames](https://github.com/route/ferrum#frames)
39
- * [Dialog](https://github.com/route/ferrum#dialog)
36
+ * [Install](https://github.com/rubycdp/ferrum#install)
37
+ * [Examples](https://github.com/rubycdp/ferrum#examples)
38
+ * [Docker](https://github.com/rubycdp/ferrum#docker)
39
+ * [Customization](https://github.com/rubycdp/ferrum#customization)
40
+ * [Navigation](https://github.com/rubycdp/ferrum#navigation)
41
+ * [Finders](https://github.com/rubycdp/ferrum#finders)
42
+ * [Screenshots](https://github.com/rubycdp/ferrum#screenshots)
43
+ * [Network](https://github.com/rubycdp/ferrum#network)
44
+ * [Mouse](https://github.com/rubycdp/ferrum#mouse)
45
+ * [Keyboard](https://github.com/rubycdp/ferrum#keyboard)
46
+ * [Cookies](https://github.com/rubycdp/ferrum#cookies)
47
+ * [Headers](https://github.com/rubycdp/ferrum#headers)
48
+ * [JavaScript](https://github.com/rubycdp/ferrum#javascript)
49
+ * [Frames](https://github.com/rubycdp/ferrum#frames)
50
+ * [Frame](https://github.com/rubycdp/ferrum#frame)
51
+ * [Dialog](https://github.com/rubycdp/ferrum#dialog)
52
+ * [Thread safety](https://github.com/rubycdp/ferrum#thread-safety)
53
+ * [Development](https://github.com/rubycdp/ferrum#development)
54
+ * [Contributing](https://github.com/rubycdp/ferrum#contributing)
55
+ * [License](https://github.com/rubycdp/ferrum#license)
56
+
40
57
 
41
58
  ## Install
42
59
 
43
60
  There's no official Chrome or Chromium package for Linux don't install it this
44
- way because it either will be outdated or unofficial, both are bad. Download it
45
- from official [source](https://www.chromium.org/getting-involved/download-chromium).
61
+ way because it's either outdated or unofficial, both are bad. Download it from
62
+ official [source](https://www.chromium.org/getting-involved/download-chromium).
46
63
  Chrome binary should be in the `PATH` or `BROWSER_PATH` or you can pass it as an
47
- option to browser instance `:browser_path`.
64
+ option to browser instance see `:browser_path` in
65
+ [Customization](https://github.com/rubycdp/ferrum#customization).
48
66
 
49
- Add this to your Gemfile:
67
+ Add this to your `Gemfile` and run `bundle install`.
50
68
 
51
69
  ``` ruby
52
70
  gem "ferrum"
53
71
  ```
54
72
 
73
+
74
+ ## Examples
75
+
55
76
  Navigate to a website and save a screenshot:
56
77
 
57
78
  ```ruby
58
79
  browser = Ferrum::Browser.new
59
- browser.goto("https://google.com")
80
+ browser.go_to("https://google.com")
60
81
  browser.screenshot(path: "google.png")
61
82
  browser.quit
62
83
  ```
@@ -65,10 +86,10 @@ Interact with a page:
65
86
 
66
87
  ```ruby
67
88
  browser = Ferrum::Browser.new
68
- browser.goto("https://google.com")
69
- input = browser.at_xpath("//div[@id='searchform']/form//input[@type='text']")
89
+ browser.go_to("https://google.com")
90
+ input = browser.at_xpath("//input[@name='q']")
70
91
  input.focus.type("Ruby headless driver for Chrome", :Enter)
71
- browser.at_css("a > h3").text # => "route/ferrum: Ruby Chrome/Chromium driver - GitHub"
92
+ browser.at_css("a > h3").text # => "rubycdp/ferrum: Ruby Chrome/Chromium driver - GitHub"
72
93
  browser.quit
73
94
  ```
74
95
 
@@ -76,7 +97,7 @@ Evaluate some JavaScript and get full width/height:
76
97
 
77
98
  ```ruby
78
99
  browser = Ferrum::Browser.new
79
- browser.goto("https://www.google.com/search?q=Ruby+headless+driver+for+Capybara")
100
+ browser.go_to("https://www.google.com/search?q=Ruby+headless+driver+for+Capybara")
80
101
  width, height = browser.evaluate <<~JS
81
102
  [document.documentElement.offsetWidth,
82
103
  document.documentElement.offsetHeight]
@@ -90,7 +111,7 @@ Do any mouse movements you like:
90
111
  ```ruby
91
112
  # Trace a 100x100 square
92
113
  browser = Ferrum::Browser.new
93
- browser.goto("https://google.com")
114
+ browser.go_to("https://google.com")
94
115
  browser.mouse
95
116
  .move(x: 0, y: 0)
96
117
  .down
@@ -103,7 +124,17 @@ browser.mouse
103
124
  browser.quit
104
125
  ```
105
126
 
106
- ## Customization ##
127
+
128
+ ## Docker
129
+
130
+ In docker as root you must pass the no-sandbox browser option:
131
+
132
+ ```ruby
133
+ Ferrum::Browser.new(browser_options: { 'no-sandbox': nil })
134
+ ```
135
+
136
+
137
+ ## Customization
107
138
 
108
139
  You can customize options with the following code in your test setup:
109
140
 
@@ -113,6 +144,7 @@ Ferrum::Browser.new(options)
113
144
 
114
145
  * options `Hash`
115
146
  * `:headless` (Boolean) - Set browser as headless or not, `true` by default.
147
+ * `:xvfb` (Boolean) - Run browser in a virtual framebuffer, `false` by default.
116
148
  * `:window_size` (Array) - The dimensions of the browser window in which to
117
149
  test, expressed as a 2-element array, e.g. [1024, 768]. Default: [1024, 768]
118
150
  * `:extensions` (Array[String | Hash]) - An array of paths to files or JS
@@ -120,32 +152,39 @@ Ferrum::Browser.new(options)
120
152
  `["/path/to/script.js", { source: "window.secret = 'top'" }]`
121
153
  * `:logger` (Object responding to `puts`) - When present, debug output is
122
154
  written to this object.
123
- * `:slowmo` (Integer | Float) - Set a delay to wait before sending command.
155
+ * `:slowmo` (Integer | Float) - Set a delay in seconds to wait before sending command.
124
156
  Usefull companion of headless option, so that you have time to see changes.
125
157
  * `:timeout` (Numeric) - The number of seconds we'll wait for a response when
126
158
  communicating with browser. Default is 5.
127
159
  * `:js_errors` (Boolean) - When true, JavaScript errors get re-raised in Ruby.
160
+ * `:pending_connection_errors` (Boolean) - When main frame is still waiting for slow responses while timeout is
161
+ reached `PendingConnectionsError` is raised. It's better to figure out why you have slow responses and fix or
162
+ block them rather than turn this setting off. Default is true.
128
163
  * `:browser_name` (Symbol) - `:chrome` by default, only experimental support
129
164
  for `:firefox` for now.
130
- * `:browser_path` (String) - Path to chrome binary, you can also set ENV
165
+ * `:browser_path` (String) - Path to Chrome binary, you can also set ENV
131
166
  variable as `BROWSER_PATH=some/path/chrome bundle exec rspec`.
132
167
  * `:browser_options` (Hash) - Additional command line options,
133
168
  [see them all](https://peter.sh/experiments/chromium-command-line-switches/)
134
169
  e.g. `{ "ignore-certificate-errors" => nil }`
170
+ * `:ignore_default_browser_options` (Boolean) - Ferrum has a number of default
171
+ options it passes to the browser, if you set this to `true` then only
172
+ options you put in `:browser_options` will be passed to the browser,
173
+ except required ones of course.
135
174
  * `:port` (Integer) - Remote debugging port for headless Chrome
136
175
  * `:host` (String) - Remote debugging address for headless Chrome
137
176
  * `:url` (String) - URL for a running instance of Chrome. If this is set, a
138
177
  browser process will not be spawned.
139
178
  * `:process_timeout` (Integer) - How long to wait for the Chrome process to
140
179
  respond on startup
141
-
142
-
143
- #### The API below is for master branch and a subject to change before 1.0
180
+ * `:ws_max_receive_size` (Integer) - How big messages to accept from Chrome
181
+ over the web socket, in bytes. Defaults to 64MB. Incoming messages larger
182
+ than this will cause a `Ferrum::DeadBrowserError`.
144
183
 
145
184
 
146
185
  ## Navigation
147
186
 
148
- #### goto(url) : `String`
187
+ #### go_to(url) : `String`
149
188
 
150
189
  Navigate page to.
151
190
 
@@ -153,7 +192,7 @@ Navigate page to.
153
192
  configuring driver.
154
193
 
155
194
  ```ruby
156
- browser.goto("https://github.com/")
195
+ browser.go_to("https://github.com/")
157
196
  ```
158
197
 
159
198
  #### back
@@ -161,7 +200,7 @@ browser.goto("https://github.com/")
161
200
  Navigate to the previous page in history.
162
201
 
163
202
  ```ruby
164
- browser.goto("https://github.com/")
203
+ browser.go_to("https://github.com/")
165
204
  browser.at_xpath("//a").click
166
205
  browser.back
167
206
  ```
@@ -171,7 +210,7 @@ browser.back
171
210
  Navigate to the next page in history.
172
211
 
173
212
  ```ruby
174
- browser.goto("https://github.com/")
213
+ browser.go_to("https://github.com/")
175
214
  browser.at_xpath("//a").click
176
215
  browser.back
177
216
  browser.forward
@@ -182,10 +221,19 @@ browser.forward
182
221
  Reload current page.
183
222
 
184
223
  ```ruby
185
- browser.goto("https://github.com/")
224
+ browser.go_to("https://github.com/")
186
225
  browser.refresh
187
226
  ```
188
227
 
228
+ #### stop
229
+
230
+ Stop all navigations and loading pending resources on the page
231
+
232
+ ```ruby
233
+ browser.go_to("https://github.com/")
234
+ browser.stop
235
+ ```
236
+
189
237
 
190
238
  ## Finders
191
239
 
@@ -199,7 +247,7 @@ provided node.
199
247
  * :within `Node` | `nil`
200
248
 
201
249
  ```ruby
202
- browser.goto("https://github.com/")
250
+ browser.go_to("https://github.com/")
203
251
  browser.at_css("a[aria-label='Issues you created']") # => Node
204
252
  ```
205
253
 
@@ -214,7 +262,7 @@ document or provided node.
214
262
  * :within `Node` | `nil`
215
263
 
216
264
  ```ruby
217
- browser.goto("https://github.com/")
265
+ browser.go_to("https://github.com/")
218
266
  browser.css("a[aria-label='Issues you created']") # => [Node]
219
267
  ```
220
268
 
@@ -227,7 +275,7 @@ Find node by xpath.
227
275
  * :within `Node` | `nil`
228
276
 
229
277
  ```ruby
230
- browser.goto("https://github.com/")
278
+ browser.go_to("https://github.com/")
231
279
  browser.at_xpath("//a[@aria-label='Issues you created']") # => Node
232
280
  ```
233
281
 
@@ -240,7 +288,7 @@ Find nodes by xpath.
240
288
  * :within `Node` | `nil`
241
289
 
242
290
  ```ruby
243
- browser.goto("https://github.com/")
291
+ browser.go_to("https://github.com/")
244
292
  browser.xpath("//a[@aria-label='Issues you created']") # => [Node]
245
293
  ```
246
294
 
@@ -249,7 +297,7 @@ browser.xpath("//a[@aria-label='Issues you created']") # => [Node]
249
297
  Returns current top window location href.
250
298
 
251
299
  ```ruby
252
- browser.goto("https://google.com/")
300
+ browser.go_to("https://google.com/")
253
301
  browser.current_url # => "https://www.google.com/"
254
302
  ```
255
303
 
@@ -258,7 +306,7 @@ browser.current_url # => "https://www.google.com/"
258
306
  Returns current top window title
259
307
 
260
308
  ```ruby
261
- browser.goto("https://google.com/")
309
+ browser.go_to("https://google.com/")
262
310
  browser.current_title # => "Google"
263
311
  ```
264
312
 
@@ -267,7 +315,7 @@ browser.current_title # => "Google"
267
315
  Returns current page's html.
268
316
 
269
317
  ```ruby
270
- browser.goto("https://google.com/")
318
+ browser.go_to("https://google.com/")
271
319
  browser.body # => '<html itemscope="" itemtype="http://schema.org/WebPage" lang="ru"><head>...
272
320
  ```
273
321
 
@@ -288,18 +336,21 @@ Saves screenshot on a disk or returns it as base64.
288
336
  * :full `Boolean` whether you need full page screenshot or a viewport
289
337
  * :selector `String` css selector for given element
290
338
  * :scale `Float` zoom in/out
339
+ * :background_color `Ferrum::RGBA.new(0, 0, 0, 0.0)` to have specific background color
291
340
 
292
341
  ```ruby
293
- browser.goto("https://google.com/")
342
+ browser.go_to("https://google.com/")
294
343
  # Save on the disk in PNG
295
344
  browser.screenshot(path: "google.png") # => 134660
296
345
  # Save on the disk in JPG
297
346
  browser.screenshot(path: "google.jpg") # => 30902
298
347
  # Save to Base64 the whole page not only viewport and reduce quality
299
348
  browser.screenshot(full: true, quality: 60) # "iVBORw0KGgoAAAANSUhEUgAABAAAAAMACAYAAAC6uhUNAAAAAXNSR0IArs4c6Q...
349
+ # Save with specific background color
350
+ browser.screenshot(background_color: Ferrum::RGBA.new(0, 0, 0, 0.0))
300
351
  ```
301
352
 
302
- #### pdf(\*\*options) : `String` | `Integer`
353
+ #### pdf(\*\*options) : `String` | `Boolean`
303
354
 
304
355
  Saves PDF on a disk or returns it as base64.
305
356
 
@@ -317,9 +368,21 @@ Saves PDF on a disk or returns it as base64.
317
368
  * See other [native options](https://chromedevtools.github.io/devtools-protocol/tot/Page#method-printToPDF) you can pass
318
369
 
319
370
  ```ruby
320
- browser.goto("https://google.com/")
371
+ browser.go_to("https://google.com/")
321
372
  # Save to disk as a PDF
322
- browser.pdf(path: "google.pdf", paper_width: 1.0, paper_height: 1.0) # => 14983
373
+ browser.pdf(path: "google.pdf", paper_width: 1.0, paper_height: 1.0) # => true
374
+ ```
375
+
376
+ #### mhtml(\*\*options) : `String` | `Integer`
377
+
378
+ Saves MHTML on a disk or returns it as a string.
379
+
380
+ * options `Hash`
381
+ * :path `String` to save a file on the disk.
382
+
383
+ ```ruby
384
+ browser.go_to("https://google.com/")
385
+ browser.mhtml(path: "google.mhtml") # => 87742
323
386
  ```
324
387
 
325
388
 
@@ -333,7 +396,7 @@ Returns all information about network traffic as `Network::Exchange` instance
333
396
  which in general is a wrapper around `request`, `response` and `error`.
334
397
 
335
398
  ```ruby
336
- browser.goto("https://github.com/")
399
+ browser.go_to("https://github.com/")
337
400
  browser.network.traffic # => [#<Ferrum::Network::Exchange, ...]
338
401
  ```
339
402
 
@@ -342,7 +405,7 @@ browser.network.traffic # => [#<Ferrum::Network::Exchange, ...]
342
405
  Page request of the main frame.
343
406
 
344
407
  ```ruby
345
- browser.goto("https://github.com/")
408
+ browser.go_to("https://github.com/")
346
409
  browser.network.request # => #<Ferrum::Network::Request...
347
410
  ```
348
411
 
@@ -351,7 +414,7 @@ browser.network.request # => #<Ferrum::Network::Request...
351
414
  Page response of the main frame.
352
415
 
353
416
  ```ruby
354
- browser.goto("https://github.com/")
417
+ browser.go_to("https://github.com/")
355
418
  browser.network.response # => #<Ferrum::Network::Response...
356
419
  ```
357
420
 
@@ -361,7 +424,7 @@ Contains the status code of the main page response (e.g., 200 for a
361
424
  success). This is just a shortcut for `response.status`.
362
425
 
363
426
  ```ruby
364
- browser.goto("https://github.com/")
427
+ browser.go_to("https://github.com/")
365
428
  browser.network.status # => 200
366
429
  ```
367
430
 
@@ -378,7 +441,7 @@ Waits for network idle or raises `Ferrum::TimeoutError` error
378
441
  by default
379
442
 
380
443
  ```ruby
381
- browser.goto("https://example.com/")
444
+ browser.go_to("https://example.com/")
382
445
  browser.at_xpath("//a[text() = 'No UI changes button']").click
383
446
  browser.network.wait_for_idle
384
447
  ```
@@ -391,7 +454,7 @@ Clear browser's cache or collected traffic.
391
454
 
392
455
  ```ruby
393
456
  traffic = browser.network.traffic # => []
394
- browser.goto("https://github.com/")
457
+ browser.go_to("https://github.com/")
395
458
  traffic.size # => 51
396
459
  browser.network.clear(:traffic)
397
460
  traffic.size # => 0
@@ -419,25 +482,52 @@ browser.on(:request) do |request|
419
482
  request.continue
420
483
  end
421
484
  end
422
- browser.goto("https://google.com")
485
+ browser.go_to("https://google.com")
423
486
  ```
424
487
 
425
- #### authorize(\*\*options)
488
+ #### authorize(\*\*options, &block)
426
489
 
427
- If site uses authorization you can provide credentials using this method.
490
+ If site or proxy uses authorization you can provide credentials using this method.
428
491
 
429
492
  * options `Hash`
430
493
  * :type `Symbol` `:server` | `:proxy` site or proxy authorization
431
494
  * :user `String`
432
495
  * :password `String`
496
+ * &block accepts authenticated request, which you must subsequently allow or deny, if you don't
497
+ care about unwanted requests just call `request.continue`.
433
498
 
434
499
  ```ruby
435
- browser.network.authorize(user: "login", password: "pass")
436
- browser.goto("http://example.com/authenticated")
500
+ browser.network.authorize(user: "login", password: "pass") { |req| req.continue }
501
+ browser.go_to("http://example.com/authenticated")
437
502
  puts browser.network.status # => 200
438
503
  puts browser.body # => Welcome, authenticated client
439
504
  ```
440
505
 
506
+ Since Chrome implements authorize using request interception you must continue or abort authorized requests. If you
507
+ already have code that uses interception you can use `authorize` without block, but if not you are obliged to pass
508
+ block, so this is version doesn't pass block and can work just fine:
509
+
510
+ ```ruby
511
+ browser = Ferrum::Browser.new
512
+ browser.network.intercept
513
+ browser.on(:request) do |request|
514
+ if request.resource_type == "Image"
515
+ request.abort
516
+ else
517
+ request.continue
518
+ end
519
+ end
520
+
521
+ browser.network.authorize(user: "login", password: "pass", type: :proxy)
522
+
523
+ browser.go_to("https://google.com")
524
+
525
+ ```
526
+
527
+ You used to call `authorize` method without block, but since it's implemented using request interception there could be
528
+ a collision with another part of your code that also uses request interception, so that authorize allows the request
529
+ while your code denies but it's too late. The block is mandatory now.
530
+
441
531
 
442
532
  ### Mouse
443
533
 
@@ -453,7 +543,7 @@ Scroll page to a given x, y
453
543
  displayed in the upper left
454
544
 
455
545
  ```ruby
456
- browser.goto("https://www.google.com/search?q=Ruby+headless+driver+for+Capybara")
546
+ browser.go_to("https://www.google.com/search?q=Ruby+headless+driver+for+Capybara")
457
547
  browser.mouse.scroll_to(0, 400)
458
548
  ```
459
549
 
@@ -558,6 +648,8 @@ Sets given values as cookie
558
648
  * :value `String`
559
649
  * :domain `String`
560
650
  * :expires `Integer`
651
+ * :samesite `String`
652
+ * :httponly `Boolean`
561
653
 
562
654
  ```ruby
563
655
  browser.cookies.set(name: "stealth", value: "omg", domain: "google.com") # => true
@@ -677,7 +769,7 @@ browser.add_style_tag(content: "h1 { font-size: 40px; }") # => true
677
769
 
678
770
  ```ruby
679
771
  browser.bypass_csp # => true
680
- browser.goto("https://github.com/ruby-concurrency/concurrent-ruby/blob/master/docs-source/promises.in.md")
772
+ browser.go_to("https://github.com/ruby-concurrency/concurrent-ruby/blob/master/docs-source/promises.in.md")
681
773
  browser.refresh
682
774
  browser.add_script_tag(content: "window.__injected = 42")
683
775
  browser.evaluate("window.__injected") # => 42
@@ -686,17 +778,146 @@ browser.evaluate("window.__injected") # => 42
686
778
 
687
779
  ## Frames
688
780
 
689
- #### frames
690
- #### main_frame
691
- #### frame_by
781
+ #### frames : `Array[Frame] | []`
782
+
783
+ Returns all the frames current page have.
784
+
785
+ ```ruby
786
+ browser.go_to("https://www.w3schools.com/tags/tag_frame.asp")
787
+ browser.frames # =>
788
+ # [
789
+ # #<Ferrum::Frame @id="C6D104CE454A025FBCF22B98DE612B12" @parent_id=nil @name=nil @state=:stopped_loading @execution_id=1>,
790
+ # #<Ferrum::Frame @id="C09C4E4404314AAEAE85928EAC109A93" @parent_id="C6D104CE454A025FBCF22B98DE612B12" @state=:stopped_loading @execution_id=2>,
791
+ # #<Ferrum::Frame @id="2E9C7F476ED09D87A42F2FEE3C6FBC3C" @parent_id="C6D104CE454A025FBCF22B98DE612B12" @state=:stopped_loading @execution_id=3>,
792
+ # ...
793
+ # ]
794
+ ```
795
+
796
+ #### main_frame : `Frame`
797
+
798
+ Returns page's main frame, the top of the tree and the parent of all frames.
799
+
800
+ #### frame_by(\*\*options) : `Frame | nil`
692
801
 
693
- Play around inside given frame
802
+ Find frame by given options.
803
+
804
+ * options `Hash`
805
+ * :id `String` - Unique frame's id that browser provides
806
+ * :name `String` - Frame's name if there's one
694
807
 
695
808
  ```ruby
696
- browser.goto("https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe")
809
+ browser.frame_by(id: "C6D104CE454A025FBCF22B98DE612B12")
810
+ ```
811
+
812
+
813
+ ## Frame
814
+
815
+ #### id : `String`
816
+
817
+ Frame's unique id.
818
+
819
+ #### parent_id : `String | nil`
820
+
821
+ Parent frame id if this one is nested in another one.
822
+
823
+ #### execution_id : `Integer`
824
+
825
+ Execution context id which is used by JS, each frame has it's own context in
826
+ which JS evaluates.
827
+
828
+ #### name : `String | nil`
829
+
830
+ If frame was given a name it should be here.
831
+
832
+ #### state : `Symbol | nil`
833
+
834
+ One of the states frame's in:
835
+
836
+ * `:started_loading`
837
+ * `:navigated`
838
+ * `:stopped_loading`
839
+
840
+ #### url : `String`
841
+
842
+ Returns current frame's location href.
843
+
844
+ ```ruby
845
+ browser.go_to("https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe")
846
+ frame = browser.frames[1]
847
+ frame.url # => https://interactive-examples.mdn.mozilla.net/pages/tabbed/iframe.html
848
+ ```
849
+
850
+ #### title
851
+
852
+ Returns current frame's title.
853
+
854
+ ```ruby
855
+ browser.go_to("https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe")
697
856
  frame = browser.frames[1]
698
- puts frame.title # => HTML Demo: <iframe>
699
- puts frame.url # => https://interactive-examples.mdn.mozilla.net/pages/tabbed/iframe.html
857
+ frame.title # => HTML Demo: <iframe>
858
+ ```
859
+
860
+ #### main? : `Boolean`
861
+
862
+ If current frame is the main frame of the page (top of the tree).
863
+
864
+ ```ruby
865
+ browser.go_to("https://www.w3schools.com/tags/tag_frame.asp")
866
+ frame = browser.frame_by(id: "C09C4E4404314AAEAE85928EAC109A93")
867
+ frame.main? # => false
868
+ ```
869
+
870
+ #### current_url : `String`
871
+
872
+ Returns current frame's top window location href.
873
+
874
+ ```ruby
875
+ browser.go_to("https://www.w3schools.com/tags/tag_frame.asp")
876
+ frame = browser.frame_by(id: "C09C4E4404314AAEAE85928EAC109A93")
877
+ frame.current_url # => "https://www.w3schools.com/tags/tag_frame.asp"
878
+ ```
879
+
880
+ #### current_title : `String`
881
+
882
+ Returns current frame's top window title.
883
+
884
+ ```ruby
885
+ browser.go_to("https://www.w3schools.com/tags/tag_frame.asp")
886
+ frame = browser.frame_by(id: "C09C4E4404314AAEAE85928EAC109A93")
887
+ frame.current_title # => "HTML frame tag"
888
+ ```
889
+
890
+ #### body : `String`
891
+
892
+ Returns current frame's html.
893
+
894
+ ```ruby
895
+ browser.go_to("https://www.w3schools.com/tags/tag_frame.asp")
896
+ frame = browser.frame_by(id: "C09C4E4404314AAEAE85928EAC109A93")
897
+ frame.body # => "<html><head></head><body></body></html>"
898
+ ```
899
+
900
+ #### doctype
901
+
902
+ Returns current frame's doctype.
903
+
904
+ ```ruby
905
+ browser.go_to("https://www.w3schools.com/tags/tag_frame.asp")
906
+ browser.main_frame.doctype # => "<!DOCTYPE html>"
907
+ ```
908
+
909
+ #### set_content(html)
910
+
911
+ Sets a content of a given frame.
912
+
913
+ * html `String`
914
+
915
+ ```ruby
916
+ browser.go_to("https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe")
917
+ frame = browser.frames[1]
918
+ frame.body # <html lang="en"><head><style>body {transition: opacity ease-in 0.2s; }...
919
+ frame.set_content("<html><head></head><body><p>lol</p></body></html>")
920
+ frame.body # => <html><head></head><body><p>lol</p></body></html>
700
921
  ```
701
922
 
702
923
 
@@ -721,7 +942,7 @@ browser.on(:dialog) do |dialog|
721
942
  dialog.dismiss
722
943
  end
723
944
  end
724
- browser.goto("https://google.com")
945
+ browser.go_to("https://google.com")
725
946
  ```
726
947
 
727
948
 
@@ -738,13 +959,13 @@ context = browser.contexts.create
738
959
 
739
960
  t1 = Thread.new(context) do |c|
740
961
  page = c.create_page
741
- page.goto("https://www.google.com/search?q=Ruby+headless+driver+for+Capybara")
962
+ page.go_to("https://www.google.com/search?q=Ruby+headless+driver+for+Capybara")
742
963
  page.screenshot(path: "t1.png")
743
964
  end
744
965
 
745
966
  t2 = Thread.new(context) do |c|
746
967
  page = c.create_page
747
- page.goto("https://www.google.com/search?q=Ruby+static+typing")
968
+ page.go_to("https://www.google.com/search?q=Ruby+static+typing")
748
969
  page.screenshot(path: "t2.png")
749
970
  end
750
971
 
@@ -763,7 +984,7 @@ browser = Ferrum::Browser.new
763
984
  t1 = Thread.new(browser) do |b|
764
985
  context = b.contexts.create
765
986
  page = context.create_page
766
- page.goto("https://www.google.com/search?q=Ruby+headless+driver+for+Capybara")
987
+ page.go_to("https://www.google.com/search?q=Ruby+headless+driver+for+Capybara")
767
988
  page.screenshot(path: "t1.png")
768
989
  context.dispose
769
990
  end
@@ -771,7 +992,7 @@ end
771
992
  t2 = Thread.new(browser) do |b|
772
993
  context = b.contexts.create
773
994
  page = context.create_page
774
- page.goto("https://www.google.com/search?q=Ruby+static+typing")
995
+ page.go_to("https://www.google.com/search?q=Ruby+static+typing")
775
996
  page.screenshot(path: "t2.png")
776
997
  context.dispose
777
998
  end
@@ -781,3 +1002,21 @@ t2.join
781
1002
 
782
1003
  browser.quit
783
1004
  ```
1005
+
1006
+ ## Development
1007
+
1008
+ After checking out the repo, run `bundle install` to install dependencies.
1009
+
1010
+ 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.
1011
+
1012
+ 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).
1013
+
1014
+
1015
+ ## Contributing
1016
+
1017
+ Bug reports and pull requests are welcome on [GitHub](https://github.com/rubycdp/ferrum).
1018
+
1019
+ ## License
1020
+
1021
+ The gem is available as open source under the terms of the
1022
+ [MIT License](https://opensource.org/licenses/MIT).