lighthouse-matchers 1.1.0 → 1.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d59475b53e41779753dc20a7d0775dc4300494da79af101d2671b235d9952192
4
- data.tar.gz: 41d0d01d7494075bc18d6dc3bca107f5de9ec3400cf89eac689c8834fd24efdd
3
+ metadata.gz: e47d9c8b9ac4ff8fe209317f9054fafd3c5d7c81f1f241cb61be6035940ea50a
4
+ data.tar.gz: 6627e960001bad68703a9a0d5eb2a20691f97f137b8293fcd24f70813c1df6d9
5
5
  SHA512:
6
- metadata.gz: 201ae5239f163fc312f4edb460b7e9a5969757c06b7093792b7f0ff8cff7e5baccf9ec8aa8c5ac612d537bb6a371fb605c6099d833ca7b5ed918abbde2932ede
7
- data.tar.gz: 2879723cd480d9e67e2578c5e89f78e6251350cd01702a3cd7150705fdf2e3245ed9319a44b929280e65d8640a4d6508b876065f9dbb5e1bbc434149e96bfe4a
6
+ metadata.gz: 2628e449c6d825aea0eed45bfbd2a3e9f3c63d925495033003f4c3eae649a6a4686f72ca90e388e61131aacd893a491733ed23b4762698b21bfd8c31ef7cbb04
7
+ data.tar.gz: 6da50b69d8d31d21ab669c3b7e1de4d74f731af703d9bae63ee8082836fa6be0a92d53bf1a64bef0bcf21c2598edaef58f6b153f3c716da3fe3a45f753f78a26
@@ -22,24 +22,35 @@ permissions:
22
22
  contents: read # to fetch code (actions/checkout)
23
23
 
24
24
  jobs:
25
+ lint:
26
+ runs-on: ubuntu-latest
27
+ steps:
28
+ - uses: actions/checkout@v4
29
+ with:
30
+ persist-credentials: false
31
+ - uses: ruby/setup-ruby@v1
32
+ with:
33
+ ruby-version: '3.2'
34
+ bundler-cache: true
35
+ - run: bundle exec rubocop
25
36
  test:
26
37
  runs-on: ubuntu-latest
27
38
  strategy:
28
39
  fail-fast: false
29
40
  matrix:
30
- ruby-version: ['2.5', '2.6', '2.7', '3.0', '3.1']
41
+ ruby-version: ['2.5', '2.6', '2.7', '3.0', '3.1', '3.2', '3.3']
31
42
  steps:
32
- - uses: actions/checkout@v3
43
+ - uses: actions/checkout@v4
33
44
  with:
34
45
  persist-credentials: false
35
46
  - uses: ruby/setup-ruby@v1
36
47
  with:
37
48
  ruby-version: ${{ matrix.ruby-version }}
38
49
  bundler-cache: true # runs 'bundle install' and caches installed gems automatically
39
- - uses: actions/setup-node@v3
50
+ - uses: actions/setup-node@v4
40
51
  with:
41
52
  cache: 'npm'
42
53
  - run: npm ci
43
- - run: npm test
54
+ - run: bundle exec rake spec
44
55
  env:
45
56
  CI_CHROME_FLAGS: "--headless"
@@ -0,0 +1,30 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - v*
7
+
8
+ permissions:
9
+ contents: read # to fetch code (actions/checkout)
10
+
11
+ jobs:
12
+ push:
13
+ permissions:
14
+ contents: write
15
+ id-token: write
16
+ if: github.repository == 'ackama/lighthouse-matchers'
17
+ runs-on: ubuntu-latest
18
+ steps:
19
+ - name: Harden Runner
20
+ uses: step-security/harden-runner@v2
21
+ with:
22
+ egress-policy: audit
23
+ - uses: actions/checkout@v4
24
+ with:
25
+ persist-credentials: false
26
+ - uses: ruby/setup-ruby@v1
27
+ with:
28
+ ruby-version: '3.2'
29
+ bundler-cache: true
30
+ - uses: rubygems/release-gem@v1
data/CHANGELOG.md CHANGED
@@ -6,6 +6,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [1.3.0] - 2025-08-13
10
+ ### Added
11
+ - Write audit results to disk on failure so they can be viewed using the browser viewer ([#68](https://github.com/ackama/lighthouse-matchers/pull/68))
12
+
13
+ ### Changed
14
+ - Prefix warnings with the full example description ([#69](https://github.com/ackama/lighthouse-matchers/pull/69))
15
+
16
+ ## [1.2.0] - 2024-07-13
17
+ ### Changed
18
+ - Raise an explict error when the audit category is not found ([#56](https://github.com/ackama/lighthouse-matchers/pull/56))
19
+ - Print run warnings from Lighthouse ([#55](https://github.com/ackama/lighthouse-matchers/pull/55))
20
+
9
21
  ## [1.1.0] - 2023-08-27
10
22
  ### Changed
11
23
  - Only run audits for categories that are requested to improve performance ([#28](https://github.com/ackama/lighthouse-matchers/pull/28))
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- lighthouse-matchers (1.1.0)
4
+ lighthouse-matchers (1.3.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -14,7 +14,7 @@ GEM
14
14
  rainbow (3.0.0)
15
15
  rake (13.0.1)
16
16
  regexp_parser (2.2.0)
17
- rexml (3.2.5)
17
+ rexml (3.3.9)
18
18
  rspec (3.8.0)
19
19
  rspec-core (~> 3.8.0)
20
20
  rspec-expectations (~> 3.8.0)
@@ -43,7 +43,7 @@ GEM
43
43
  parser (>= 3.0.1.1)
44
44
  ruby-progressbar (1.11.0)
45
45
  unicode-display_width (2.1.0)
46
- webrick (1.7.0)
46
+ webrick (1.8.2)
47
47
 
48
48
  PLATFORMS
49
49
  ruby
data/README.md CHANGED
@@ -103,6 +103,9 @@ All configuration keys are accessible against the `Lighthouse::Matchers` object.
103
103
  * **`minimum_score`:** The default minimum score that audits must meet for the matcher to pass.
104
104
  The default value of this configuration setting is '100' - e.g. audits must fully comply to pass.
105
105
  * **`chrome_flags`:** Any additional flags that should be passed to Chrome when Lighthouse launches a browser instance. As an example, running Lighthouse in Docker requires the normal headless Chrome flags (`--headless`, `--no-sandbox`) for Chrome to successfully start. Chrome flags can either be specified as an array (`["headless", "no-sandbox"]`) or as a string (`--headless --no-sandbox`).
106
+ * **`results_directory`:** Directory to write lighthouse results on failure
107
+ * Defaults to `<RSpec.configuration.default_path>/lighthouse` if `RSpec` is defined, otherwise a temporary directory prefixed with `lighthouse-matchers-`
108
+ * For Rails applications, we recommend setting this to `Rails.root.join('/tmp/lighthouse')` in your `rails_helper.rb`
106
109
 
107
110
  ## Compatibility
108
111
 
@@ -121,6 +124,12 @@ for detailed instructions.
121
124
 
122
125
  This gem endeavours to follow Semantic Versioning 2.0 as defined at https://semver.org/.
123
126
 
127
+ ## Releasing
128
+
129
+ Releases are done automatically by GitHub Actions when a new tag is pushed to the repository.
130
+
131
+ To release a new version, create a pull request updating the "Unreleased" section of `CHANGELOG.md` file to reflect the upcoming version and expected release date, and to update the version number in `lib/lighthouse/matchers/version.rb`. Once the pull request is merged, create a new tag in the format `vX.Y.Z`, which will trigger GitHub Actions to publish the new version to RubyGems.
132
+
124
133
  ## License
125
134
 
126
135
  lighthouse-matchers is copyright © 2019 Ackama Group Ltd.
@@ -5,6 +5,8 @@ require 'stringio'
5
5
 
6
6
  # Compares a url's actual score to the expected score.
7
7
  class AuditService
8
+ class Error < StandardError; end
9
+
8
10
  def initialize(url, audit, score)
9
11
  @url = url
10
12
  @audit = audit
@@ -20,11 +22,29 @@ class AuditService
20
22
  end
21
23
 
22
24
  def measured_score
23
- results.dig('categories', @audit.to_s, 'score') * 100
25
+ category['score'] * 100
26
+ end
27
+
28
+ def run_warnings
29
+ results['runWarnings']
30
+ end
31
+
32
+ def results
33
+ @results ||= JSON.parse(output)
24
34
  end
25
35
 
26
36
  private
27
37
 
38
+ def category
39
+ category = results.dig('categories', @audit.to_s)
40
+
41
+ if category.nil?
42
+ raise Error, "Category '#{@audit}' not found in Lighthouse results - maybe it was removed?"
43
+ end
44
+
45
+ category
46
+ end
47
+
28
48
  def opts
29
49
  "'#{@url}'".tap do |builder|
30
50
  builder << ' --quiet'
@@ -38,8 +58,4 @@ class AuditService
38
58
  def output
39
59
  @output ||= @runner.call("#{@cmd} #{opts}")
40
60
  end
41
-
42
- def results
43
- JSON.parse(output)
44
- end
45
61
  end
@@ -4,22 +4,35 @@ require 'rspec/expectations'
4
4
  require 'lighthouse/matchers'
5
5
  require 'lighthouse/audit_service'
6
6
  require 'json'
7
+ require 'digest'
8
+ require 'fileutils'
7
9
 
8
- RSpec::Matchers.define :pass_lighthouse_audit do |audit, args = {}|
10
+ RSpec::Matchers.define :pass_lighthouse_audit do |audit, args = {}| # rubocop:disable Metrics/BlockLength
9
11
  score ||= args.fetch(:score, Lighthouse::Matchers.minimum_score)
10
12
 
11
13
  match do |target|
12
- audit_service = AuditService.new(url(target), audit, score)
14
+ @audit_service = AuditService.new(url(target), audit, score)
13
15
 
14
- @measured_score = audit_service.measured_score
16
+ @audit_service.run_warnings.each do |warning|
17
+ RSpec.configuration.reporter.message(
18
+ "#{RSpec.current_example.full_description}: [lighthouse] #{warning}"
19
+ )
20
+ end
15
21
 
16
- audit_service.passing_score?
22
+ @measured_score = @audit_service.measured_score
23
+
24
+ @audit_service.passing_score?
17
25
  end
18
26
 
19
27
  failure_message do |target|
20
28
  <<~FAIL
21
29
  expected #{url(target)} to pass Lighthouse #{audit} audit
22
30
  with a minimum score of #{score}, but only scored #{@measured_score.to_i}
31
+
32
+ Full report:
33
+ #{save_audit_results}
34
+
35
+ To view this report, load this file into https://googlechrome.github.io/lighthouse/viewer/
23
36
  FAIL
24
37
  end
25
38
 
@@ -28,4 +41,15 @@ RSpec::Matchers.define :pass_lighthouse_audit do |audit, args = {}|
28
41
  def url(target)
29
42
  target.respond_to?(:current_url) ? target.current_url : target
30
43
  end
44
+
45
+ def save_audit_results
46
+ body = JSON.pretty_generate(@audit_service.results)
47
+
48
+ path = File.join(Lighthouse::Matchers.results_directory, "#{Digest::SHA1.hexdigest(body)}.json")
49
+
50
+ FileUtils.mkdir_p(Lighthouse::Matchers.results_directory)
51
+ File.write(path, body)
52
+
53
+ path
54
+ end
31
55
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Lighthouse
4
4
  module Matchers
5
- VERSION = '1.1.0'
5
+ VERSION = '1.3.0'
6
6
  end
7
7
  end
@@ -9,7 +9,7 @@ module Lighthouse
9
9
  module Matchers # rubocop:disable Style/Documentation
10
10
  class Error < StandardError; end
11
11
  class << self
12
- attr_writer :minimum_score, :lighthouse_cli, :runner, :chrome_flags
12
+ attr_writer :minimum_score, :lighthouse_cli, :runner, :chrome_flags, :results_directory
13
13
  attr_accessor :remote_debugging_port
14
14
 
15
15
  def minimum_score
@@ -31,6 +31,14 @@ module Lighthouse
31
31
  @chrome_flags.map { |f| "--#{f}" }.join(' ')
32
32
  end
33
33
 
34
+ def results_directory
35
+ @results_directory ||= if defined?(RSpec)
36
+ File.join(RSpec.configuration.default_path, 'lighthouse')
37
+ else
38
+ Dir.mktmpdir('lighthouse-matchers-')
39
+ end
40
+ end
41
+
34
42
  private
35
43
 
36
44
  def guess_lighthouse_cli