ferrum 0.7 → 0.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 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).