ferrum-har 0.1.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 +7 -0
- data/README.md +80 -0
- data/lib/ferrum/har/page_extension.rb +33 -0
- data/lib/ferrum/har/version.rb +7 -0
- data/lib/ferrum/har.rb +23 -0
- metadata +81 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 414fff66d2b47e26b96047c18388bde8a698c01809454be9b01f213dcf33de82
|
4
|
+
data.tar.gz: be6b275d34536d3220859ad031a8abf952140a8699211fc48124dbbbafe673f3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a617c9a354448656f0ca8fe3b5a8c58b889b009f3db3535eb0b0f19ac844806141cd3f9d19e3ea84e16fa2d4580abcd86dc851da20d41258606d252cf8055224
|
7
|
+
data.tar.gz: f8e60c45799a5b0654994df861e7890d65ce20871cfccdc343d5449092e1d2d13b37fdb05e1e9c54add2904c53602e1b5bea1ee6c7c9e82252bc52d4145ff552
|
data/README.md
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
ferrum-har
|
2
|
+
================
|
3
|
+
|
4
|
+
[](https://img.shields.io/gem/v/ferrum-har?color=green)
|
5
|
+
|
6
|
+
[ferrum-har](https://github.com/hlascelles/ferrum-har) is a gem that adds the ability to capture
|
7
|
+
HAR files while running tests using [ferrum](https://github.com/rubycdp/ferrum)
|
8
|
+
|
9
|
+
### Installation
|
10
|
+
|
11
|
+
Add ferrum-har to your Gemfile and `bundle install`:
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
gem "ferrum-har"
|
15
|
+
```
|
16
|
+
|
17
|
+
### Usage
|
18
|
+
|
19
|
+
Use [ferrum](https://github.com/rubycdp/ferrum) as normal and call the `har` method on
|
20
|
+
the `page` (or `browser`) object. Note, you will have to use some of the required browser options
|
21
|
+
by using the `Ferrum::Har::REQUIRED_BROWSER_OPTIONS` constant.
|
22
|
+
|
23
|
+
Note, the devtools window in Chrome will be opened. This is mandatory to obtain the HAR from Chrome.
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
browser = Ferrum::Browser.new(
|
27
|
+
browser_options: Ferrum::Har::REQUIRED_BROWSER_OPTIONS,
|
28
|
+
)
|
29
|
+
page = browser.create_page
|
30
|
+
page.go_to("https://www.bbc.co.uk")
|
31
|
+
|
32
|
+
# Returns the HAR as a JSON string
|
33
|
+
puts page.har
|
34
|
+
```
|
35
|
+
|
36
|
+
### How it works
|
37
|
+
|
38
|
+
Creating a HAR file from [ferrum](https://github.com/rubycdp/ferrum) network objects is complex and
|
39
|
+
potentially incompatible with the HAR generated
|
40
|
+
by other tools (including Chrome).
|
41
|
+
|
42
|
+
Instead, ferrum-har contains a small Chrome extension that
|
43
|
+
is automatically loaded into the test browser. When the `har` method is called, this extension
|
44
|
+
asks the Chrome devtools Network panel for the HAR file and returns it to the Ruby process. This
|
45
|
+
means the HAR is always a valid version of exactly what Chrome would produce.
|
46
|
+
|
47
|
+
The JS method that is ultimately called is `chrome.devtools.network.getHAR()` and you can read more
|
48
|
+
about it [here](https://developer.chrome.com/docs/extensions/reference/api/devtools/network#method-getHAR).
|
49
|
+
|
50
|
+
One ramification of this is that the Chrome devtools must be open for the extension to work.
|
51
|
+
|
52
|
+
To get the extension to be loaded we must pass some switches to the Chrome process via ferrum,
|
53
|
+
specifically the `--auto-open-devtools-for-tabs` and `--load-extension` switches. This is done
|
54
|
+
by the `Ferrum::Har::REQUIRED_BROWSER_OPTIONS` constant.
|
55
|
+
|
56
|
+
For further reading, a full list of Chrome switches can be found
|
57
|
+
[here](https://peter.sh/experiments/chromium-command-line-switches/).
|
58
|
+
|
59
|
+
### Further work
|
60
|
+
|
61
|
+
Some ideas for improvements.
|
62
|
+
|
63
|
+
1. Add functionality to minimise the devtools sidepanel size.
|
64
|
+
To do this we would have to pass in a "profile" to the ferrum start switches like this:
|
65
|
+
```ruby
|
66
|
+
"user-data-dir=profile" => "somedir"
|
67
|
+
```
|
68
|
+
And have a "Default/Preferences" file in there that contains a sizing element like this:
|
69
|
+
```json
|
70
|
+
{
|
71
|
+
"devtools": {
|
72
|
+
"preferences": {
|
73
|
+
"inspector-view.split-view-state": "{\"vertical\":{\"size\":1},\"horizontal\":{\"size\":0}}"
|
74
|
+
}
|
75
|
+
}
|
76
|
+
}
|
77
|
+
```
|
78
|
+
However, that doesn't work as it stands as it is just a partial profile. We could add an entire
|
79
|
+
Chrome profile but that would be hundreds of files.
|
80
|
+
2. Add GitHub Actions tests.
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This module is prepended to Ferrum::Page to add the #har method.
|
4
|
+
module Ferrum
|
5
|
+
module Har
|
6
|
+
module PageExtension
|
7
|
+
class HarNotReadyError < RuntimeError
|
8
|
+
# Used to loop until the HAR is ready.
|
9
|
+
end
|
10
|
+
|
11
|
+
# This method waits until the page is idle, then fetches the HAR and decodes it.
|
12
|
+
def har
|
13
|
+
network.wait_for_idle
|
14
|
+
execute("document.ferrumHarRequested = true;")
|
15
|
+
base64_encoded_har = Ferrum::Utils::Attempt.with_retry(
|
16
|
+
errors: [HarNotReadyError],
|
17
|
+
max: 200,
|
18
|
+
wait: 0.5
|
19
|
+
) do
|
20
|
+
found = evaluate("document.ferrumHar;")
|
21
|
+
raise HarNotReadyError unless found
|
22
|
+
|
23
|
+
found
|
24
|
+
end
|
25
|
+
inlined_har = Base64.decode64(base64_encoded_har)
|
26
|
+
har_hash = JSON.parse(inlined_har)
|
27
|
+
raise "Result does not appear to be a HAR" unless har_hash.key?("log")
|
28
|
+
|
29
|
+
JSON.pretty_generate(har_hash)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/ferrum/har.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "ferrum"
|
4
|
+
require "ferrum/har/version"
|
5
|
+
require "ferrum/har/page_extension"
|
6
|
+
|
7
|
+
module Ferrum
|
8
|
+
module Har
|
9
|
+
GEM_DIR = File.expand_path("../..", __dir__)
|
10
|
+
REQUIRED_BROWSER_OPTIONS = {
|
11
|
+
"auto-open-devtools-for-tabs" => nil, # The chrome devtools must be open to invoke getHAR
|
12
|
+
"load-extension" => "#{Ferrum::Har::GEM_DIR}/extension", # The extension that gets the HAR
|
13
|
+
}.freeze
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# We have to remove the "disable-extensions" option from the default browser extension list because
|
18
|
+
# the ferrum-har gem requires an (internal) extension to work.
|
19
|
+
Ferrum::Browser::Options::Chrome::DEFAULT_OPTIONS =
|
20
|
+
Ferrum::Browser::Options::Chrome::DEFAULT_OPTIONS.except("disable-extensions")
|
21
|
+
|
22
|
+
# Add the #har method to Ferrum::Page
|
23
|
+
Ferrum::Page.prepend(Ferrum::Har::PageExtension)
|
metadata
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ferrum-har
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Harry Lascelles
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-04-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: ferrum
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: base64
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: Rubygem to convert ferrum traffic to HAR files
|
42
|
+
email:
|
43
|
+
- harry@harrylascelles.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- README.md
|
49
|
+
- lib/ferrum/har.rb
|
50
|
+
- lib/ferrum/har/page_extension.rb
|
51
|
+
- lib/ferrum/har/version.rb
|
52
|
+
homepage: https://github.com/hlascelles/ferrum-har
|
53
|
+
licenses:
|
54
|
+
- MIT
|
55
|
+
metadata:
|
56
|
+
homepage_uri: https://github.com/hlascelles/ferrum-har
|
57
|
+
documentation_uri: https://github.com/hlascelles/ferrum-har
|
58
|
+
changelog_uri: https://github.com/hlascelles/ferrum-har/blob/master/CHANGELOG.md
|
59
|
+
source_code_uri: https://github.com/hlascelles/ferrum-har/
|
60
|
+
bug_tracker_uri: https://github.com/hlascelles/ferrum-har/issues
|
61
|
+
rubygems_mfa_required: 'true'
|
62
|
+
post_install_message:
|
63
|
+
rdoc_options: []
|
64
|
+
require_paths:
|
65
|
+
- lib
|
66
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '3.0'
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
requirements: []
|
77
|
+
rubygems_version: 3.5.3
|
78
|
+
signing_key:
|
79
|
+
specification_version: 4
|
80
|
+
summary: Rubygem to convert ferrum traffic to HAR files
|
81
|
+
test_files: []
|