From d9d6a0819fbbaf128bff37795e49d4eab278d8be Mon Sep 17 00:00:00 2001 From: Andrew Bromwich Date: Fri, 31 Oct 2025 10:59:45 +1000 Subject: [PATCH 01/16] Add support for Firefox browser --- .github/workflows/test.yml | 4 ++++ lib/grover/js/processor.cjs | 6 ++++++ spec/grover/processor_spec.rb | 9 +++++++++ 3 files changed, 19 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 90b8d53..8a205bb 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -67,6 +67,10 @@ jobs: - name: Install Puppeteer run: npm install puppeteer@${{ matrix.puppeteer-version }} + - name: Install Firefox + uses: browser-actions/setup-firefox@v1 + run: firefox --version + - name: Install Imagemagick uses: mfinelli/setup-imagemagick@v5 diff --git a/lib/grover/js/processor.cjs b/lib/grover/js/processor.cjs index 4655415..76271f0 100644 --- a/lib/grover/js/processor.cjs +++ b/lib/grover/js/processor.cjs @@ -92,6 +92,12 @@ const _processPage = (async (convertAction, uriOrHtml, options) => { launchParams.args = launchParams.args.concat(args); } + // Set browser type if given + const browserType = options.browser; delete options.browser; + if (browserType) { + launchParams.browser = browserType; + } + // Set executable path if given const executablePath = options.executablePath; delete options.executablePath; if (executablePath) { diff --git a/spec/grover/processor_spec.rb b/spec/grover/processor_spec.rb index cbbbc87..390d498 100644 --- a/spec/grover/processor_spec.rb +++ b/spec/grover/processor_spec.rb @@ -1085,6 +1085,15 @@ end end end + + context 'when specifying Firefox browser' do + let(:options) { { browser: 'firefox' } } + let(:url_or_html) { 'http://localhost:4567/headers' } + + it { expect(pdf_text_content).to match(/Request contained \d+ headers/) } + it { expect(pdf_text_content).to include '1. host localhost:4567' } + it { expect(pdf_text_content).to match(/\d\. user-agent Mozilla\/5.0 .* Firefox\//) } + end end context 'when converting to an image' do From ca514df69e9da91976d2de6af835a270145456da Mon Sep 17 00:00:00 2001 From: Andrew Bromwich Date: Fri, 31 Oct 2025 13:49:12 +1000 Subject: [PATCH 02/16] Fix up github actions file --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fb7aeea..a50ad99 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -72,7 +72,7 @@ jobs: - name: Install Firefox uses: browser-actions/setup-firefox@v1 - run: firefox --version + - run: firefox --version - name: Install Imagemagick uses: mfinelli/setup-imagemagick@v5 From 86d9ff62ade9450a1b50e0d36af8c3e2e1da50bf Mon Sep 17 00:00:00 2001 From: Andrew Bromwich Date: Fri, 31 Oct 2025 13:53:45 +1000 Subject: [PATCH 03/16] Fix rubocop lint --- spec/grover/processor_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/grover/processor_spec.rb b/spec/grover/processor_spec.rb index 5210a17..4c97935 100644 --- a/spec/grover/processor_spec.rb +++ b/spec/grover/processor_spec.rb @@ -1092,7 +1092,7 @@ it { expect(pdf_text_content).to match(/Request contained \d+ headers/) } it { expect(pdf_text_content).to include '1. host localhost:4567' } - it { expect(pdf_text_content).to match(/\d\. user-agent Mozilla\/5.0 .* Firefox\//) } + it { expect(pdf_text_content).to match %r{\d\. user-agent Mozilla/5.0 .* Firefox/} } end end From e069db7c0bf76d759fb53efb6c2987ff76e8d9ed Mon Sep 17 00:00:00 2001 From: Andrew Bromwich Date: Fri, 31 Oct 2025 14:05:55 +1000 Subject: [PATCH 04/16] Switch to installing firefox using puppeteer --- .github/workflows/test.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a50ad99..12f0c63 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -71,8 +71,7 @@ jobs: run: npm install puppeteer@${{ matrix.puppeteer-version }} - name: Install Firefox - uses: browser-actions/setup-firefox@v1 - - run: firefox --version + run: npx puppeteer browsers install firefox - name: Install Imagemagick uses: mfinelli/setup-imagemagick@v5 From 758091a3739c9c1a5ce10cfd0cf6f5f9f3d74a66 Mon Sep 17 00:00:00 2001 From: Andrew Bromwich Date: Fri, 31 Oct 2025 14:11:50 +1000 Subject: [PATCH 05/16] Install firefox stable --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 12f0c63..44c2fc4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -71,7 +71,7 @@ jobs: run: npm install puppeteer@${{ matrix.puppeteer-version }} - name: Install Firefox - run: npx puppeteer browsers install firefox + run: npx puppeteer browsers install firefox@stable - name: Install Imagemagick uses: mfinelli/setup-imagemagick@v5 From e0f5294a561e183ce4784364fb1e84d1d6a729c6 Mon Sep 17 00:00:00 2001 From: Andrew Bromwich Date: Fri, 31 Oct 2025 14:52:27 +1000 Subject: [PATCH 06/16] Specify firefox path --- .github/workflows/test.yml | 3 ++- README.md | 12 ++++++++++-- spec/grover/processor_spec.rb | 16 ++++++++++------ 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 44c2fc4..d45df91 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -25,7 +25,7 @@ jobs: puppeteer-version: [ '22.15.0', '23.11.1', - '24.10.2', + '24.27.0', ] include: - ruby-version: '3.0' @@ -71,6 +71,7 @@ jobs: run: npm install puppeteer@${{ matrix.puppeteer-version }} - name: Install Firefox + if: ${{ matrix.puppeteer-version != '22.15.0' }} run: npx puppeteer browsers install firefox@stable - name: Install Imagemagick diff --git a/README.md b/README.md index 0e7151e..703864b 100644 --- a/README.md +++ b/README.md @@ -168,13 +168,13 @@ The Chrome/Chromium executable path can be overridden with the `executable_path` Supplementary JavaScript can be executed on the page (after render and before conversion to PDF/image) by passing it to the `execute_script` option. -```javascript +```ruby Grover.new(, execute_script: 'document.getElementsByTagName("footer")[0].innerText = "Hey"').to_pdf ``` You can also evaluate JavaScript on the page before any of its scripts is run, by passing it a string to the `evaluate_on_new_document` option. See https://github.com/puppeteer/puppeteer/blob/main/docs/api/puppeteer.page.evaluateonnewdocument.md -```javascript +```ruby Grover.new(, evaluate_on_new_document: 'window.someConfig = "some value"').to_pdf ``` @@ -186,6 +186,14 @@ only really makes sense if you're calling Grover directly (and not via middlewar Grover.new('', browser: 'firefox').to_pdf +``` + #### Remote Chromium By default, Grover launches a local Chromium instance. You can connect to a remote/external diff --git a/spec/grover/processor_spec.rb b/spec/grover/processor_spec.rb index 4c97935..44f8204 100644 --- a/spec/grover/processor_spec.rb +++ b/spec/grover/processor_spec.rb @@ -1086,13 +1086,17 @@ end end - context 'when specifying Firefox browser' do - let(:options) { { browser: 'firefox' } } - let(:url_or_html) { 'http://localhost:4567/headers' } + # < v23 of puppeteer has issues installing the latest firefox versions (bz2 vs xz compression used for packaging) + if puppeteer_version_on_or_after? '23' + context 'when specifying Firefox browser' do + let(:options) { { browser: 'firefox', executable_path: firefox_path } } + let(:firefox_path) { Dir["#{ENV['HOME']}/.cache/puppeteer/firefox/**/firefox"].last } + let(:url_or_html) { 'http://localhost:4567/headers' } - it { expect(pdf_text_content).to match(/Request contained \d+ headers/) } - it { expect(pdf_text_content).to include '1. host localhost:4567' } - it { expect(pdf_text_content).to match %r{\d\. user-agent Mozilla/5.0 .* Firefox/} } + it { expect(pdf_text_content).to match(/Request contained \d+ headers/) } + it { expect(pdf_text_content).to include '1. host localhost:4567' } + it { expect(pdf_text_content).to match %r{\d\. user-agent Mozilla/5.0 .* Firefox/} } + end end end From dbac32325457f521ab283073f4ce331d40b9b95f Mon Sep 17 00:00:00 2001 From: Andrew Bromwich Date: Fri, 31 Oct 2025 15:12:57 +1000 Subject: [PATCH 07/16] Fix code lint --- spec/grover/processor_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/grover/processor_spec.rb b/spec/grover/processor_spec.rb index 44f8204..f98f147 100644 --- a/spec/grover/processor_spec.rb +++ b/spec/grover/processor_spec.rb @@ -1090,7 +1090,7 @@ if puppeteer_version_on_or_after? '23' context 'when specifying Firefox browser' do let(:options) { { browser: 'firefox', executable_path: firefox_path } } - let(:firefox_path) { Dir["#{ENV['HOME']}/.cache/puppeteer/firefox/**/firefox"].last } + let(:firefox_path) { Dir[File.expand_path('~/.cache/puppeteer/firefox/**/firefox')].last } let(:url_or_html) { 'http://localhost:4567/headers' } it { expect(pdf_text_content).to match(/Request contained \d+ headers/) } From bc0b42461849b6f47f41bb93739b449c048af48a Mon Sep 17 00:00:00 2001 From: Andrew Bromwich Date: Mon, 3 Nov 2025 09:38:08 +1000 Subject: [PATCH 08/16] Add launch debugging --- .github/workflows/test.yml | 1 + lib/grover/js/processor.cjs | 5 +++++ spec/grover/processor_spec.rb | 2 ++ 3 files changed, 8 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d45df91..d044c2a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,6 +8,7 @@ on: env: CC_TEST_REPORTER_ID: 5cfed40102c670b5c9e509730782b751939ddbe53fc57c317b718f635bab1ce8 + DEBUG: "puppeteer:*" jobs: test: diff --git a/lib/grover/js/processor.cjs b/lib/grover/js/processor.cjs index 76271f0..9003849 100644 --- a/lib/grover/js/processor.cjs +++ b/lib/grover/js/processor.cjs @@ -104,6 +104,11 @@ const _processPage = (async (convertAction, uriOrHtml, options) => { launchParams.executablePath = executablePath; } + if (launchParams.browser === 'firefox') { + // Temporary debug measure + launchParams.extraPrefsFirefox = { "remote.log.level": "Trace" }; + } + // Launch the browser and create a page browser = await puppeteer.launch(launchParams); } diff --git a/spec/grover/processor_spec.rb b/spec/grover/processor_spec.rb index f98f147..462c8a5 100644 --- a/spec/grover/processor_spec.rb +++ b/spec/grover/processor_spec.rb @@ -1093,6 +1093,8 @@ let(:firefox_path) { Dir[File.expand_path('~/.cache/puppeteer/firefox/**/firefox')].last } let(:url_or_html) { 'http://localhost:4567/headers' } + before { puts "FF path: #{firefox_path}" } + it { expect(pdf_text_content).to match(/Request contained \d+ headers/) } it { expect(pdf_text_content).to include '1. host localhost:4567' } it { expect(pdf_text_content).to match %r{\d\. user-agent Mozilla/5.0 .* Firefox/} } From 3bf96567e3147030650af40d0e26a55148459945 Mon Sep 17 00:00:00 2001 From: Andrew Bromwich Date: Mon, 3 Nov 2025 09:40:19 +1000 Subject: [PATCH 09/16] Fix launch debugging --- .github/workflows/test.yml | 1 - spec/grover/processor_spec.rb | 5 ++++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d044c2a..d45df91 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,7 +8,6 @@ on: env: CC_TEST_REPORTER_ID: 5cfed40102c670b5c9e509730782b751939ddbe53fc57c317b718f635bab1ce8 - DEBUG: "puppeteer:*" jobs: test: diff --git a/spec/grover/processor_spec.rb b/spec/grover/processor_spec.rb index 462c8a5..f36dc91 100644 --- a/spec/grover/processor_spec.rb +++ b/spec/grover/processor_spec.rb @@ -1093,7 +1093,10 @@ let(:firefox_path) { Dir[File.expand_path('~/.cache/puppeteer/firefox/**/firefox')].last } let(:url_or_html) { 'http://localhost:4567/headers' } - before { puts "FF path: #{firefox_path}" } + before do + puts "FF path: #{firefox_path}" + before { allow(Grover.configuration).to receive(:node_env_vars).and_return 'DEBUG' => 'puppeteer:*' } + end it { expect(pdf_text_content).to match(/Request contained \d+ headers/) } it { expect(pdf_text_content).to include '1. host localhost:4567' } From dc22a6f4c778b47acef12c16c1bbd63b0b3c4039 Mon Sep 17 00:00:00 2001 From: Andrew Bromwich Date: Mon, 3 Nov 2025 10:06:34 +1000 Subject: [PATCH 10/16] Add more launch debugging --- lib/grover/processor.rb | 12 ++++++++++++ spec/grover/processor_spec.rb | 4 ++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/grover/processor.rb b/lib/grover/processor.rb index 92cf913..01be404 100644 --- a/lib/grover/processor.rb +++ b/lib/grover/processor.rb @@ -85,6 +85,18 @@ def call_js_method(method, url_or_html, options) # rubocop:disable Metrics/AbcSi status, message, error_class, errors = JSON.parse(input) + if options['browser'] == 'firefox' + err = '' + begin + while e = stderr.read_nonblock(100) + print '.' + err += e + end + rescue IO::EAGAINWaitReadable + end + puts "Std err:\n#{err}" + end + if status == 'ok' message elsif error_class.nil? diff --git a/spec/grover/processor_spec.rb b/spec/grover/processor_spec.rb index f36dc91..ec04373 100644 --- a/spec/grover/processor_spec.rb +++ b/spec/grover/processor_spec.rb @@ -1089,13 +1089,13 @@ # < v23 of puppeteer has issues installing the latest firefox versions (bz2 vs xz compression used for packaging) if puppeteer_version_on_or_after? '23' context 'when specifying Firefox browser' do - let(:options) { { browser: 'firefox', executable_path: firefox_path } } + let(:options) { { 'browser' => 'firefox', 'executablePath' => firefox_path } } let(:firefox_path) { Dir[File.expand_path('~/.cache/puppeteer/firefox/**/firefox')].last } let(:url_or_html) { 'http://localhost:4567/headers' } before do puts "FF path: #{firefox_path}" - before { allow(Grover.configuration).to receive(:node_env_vars).and_return 'DEBUG' => 'puppeteer:*' } + allow(Grover.configuration).to receive(:node_env_vars).and_return 'DEBUG' => 'puppeteer:*' end it { expect(pdf_text_content).to match(/Request contained \d+ headers/) } From 681ee833fa1b1c10a5f6762b5b47ccf36689d8e3 Mon Sep 17 00:00:00 2001 From: Andrew Bromwich Date: Mon, 3 Nov 2025 14:50:48 +1000 Subject: [PATCH 11/16] Disable rubocop temporarily --- .github/workflows/test.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d45df91..073260e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -77,9 +77,6 @@ jobs: - name: Install Imagemagick uses: mfinelli/setup-imagemagick@v5 - - name: Lint code - Rubocop - run: bundle exec rubocop - - name: Run tests run: bundle exec rspec env: From a8e644180b3ae025de56324e39591b9b13dcfea2 Mon Sep 17 00:00:00 2001 From: Andrew Bromwich Date: Mon, 3 Nov 2025 16:43:08 +1000 Subject: [PATCH 12/16] Tidy up debugging --- lib/grover/js/processor.cjs | 5 ----- lib/grover/processor.rb | 12 ------------ 2 files changed, 17 deletions(-) diff --git a/lib/grover/js/processor.cjs b/lib/grover/js/processor.cjs index 9003849..76271f0 100644 --- a/lib/grover/js/processor.cjs +++ b/lib/grover/js/processor.cjs @@ -104,11 +104,6 @@ const _processPage = (async (convertAction, uriOrHtml, options) => { launchParams.executablePath = executablePath; } - if (launchParams.browser === 'firefox') { - // Temporary debug measure - launchParams.extraPrefsFirefox = { "remote.log.level": "Trace" }; - } - // Launch the browser and create a page browser = await puppeteer.launch(launchParams); } diff --git a/lib/grover/processor.rb b/lib/grover/processor.rb index 01be404..92cf913 100644 --- a/lib/grover/processor.rb +++ b/lib/grover/processor.rb @@ -85,18 +85,6 @@ def call_js_method(method, url_or_html, options) # rubocop:disable Metrics/AbcSi status, message, error_class, errors = JSON.parse(input) - if options['browser'] == 'firefox' - err = '' - begin - while e = stderr.read_nonblock(100) - print '.' - err += e - end - rescue IO::EAGAINWaitReadable - end - puts "Std err:\n#{err}" - end - if status == 'ok' message elsif error_class.nil? From d1dc28a11cf9d72b84ae5c5e13b1331c560e1ddd Mon Sep 17 00:00:00 2001 From: Andrew Bromwich Date: Mon, 3 Nov 2025 22:10:39 +1000 Subject: [PATCH 13/16] Remove remainder of debug foo --- .github/workflows/test.yml | 3 +++ spec/grover/processor_spec.rb | 5 +---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 073260e..d45df91 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -77,6 +77,9 @@ jobs: - name: Install Imagemagick uses: mfinelli/setup-imagemagick@v5 + - name: Lint code - Rubocop + run: bundle exec rubocop + - name: Run tests run: bundle exec rspec env: diff --git a/spec/grover/processor_spec.rb b/spec/grover/processor_spec.rb index ec04373..f89f37c 100644 --- a/spec/grover/processor_spec.rb +++ b/spec/grover/processor_spec.rb @@ -1093,10 +1093,7 @@ let(:firefox_path) { Dir[File.expand_path('~/.cache/puppeteer/firefox/**/firefox')].last } let(:url_or_html) { 'http://localhost:4567/headers' } - before do - puts "FF path: #{firefox_path}" - allow(Grover.configuration).to receive(:node_env_vars).and_return 'DEBUG' => 'puppeteer:*' - end + before { allow(Grover.configuration).to receive(:node_env_vars).and_return 'DEBUG' => 'puppeteer:*' } it { expect(pdf_text_content).to match(/Request contained \d+ headers/) } it { expect(pdf_text_content).to include '1. host localhost:4567' } From b29438e489437b1f3f7cbf143edb8ce40ae4b999 Mon Sep 17 00:00:00 2001 From: Andrew Bromwich Date: Mon, 3 Nov 2025 22:43:21 +1000 Subject: [PATCH 14/16] Increase retry count :/ --- spec/spec_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 215d140..044eea2 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -17,7 +17,7 @@ if ENV['CI'] == 'true' # Retry config.verbose_retry = true - config.default_retry_count = 2 + config.default_retry_count = 3 config.default_sleep_interval = 5 end From a772e48a7cff52d83f6a5186ad97c10ac1a59524 Mon Sep 17 00:00:00 2001 From: Andrew Bromwich Date: Tue, 4 Nov 2025 09:37:13 +1000 Subject: [PATCH 15/16] Revert puppeteer version bump (changes to colour profile.. again) --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d45df91..1ab808e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -25,7 +25,7 @@ jobs: puppeteer-version: [ '22.15.0', '23.11.1', - '24.27.0', + '24.10.2', ] include: - ruby-version: '3.0' From 38dbc12d789467e66a19669b99a79ef064fc0df9 Mon Sep 17 00:00:00 2001 From: Andrew Bromwich Date: Tue, 4 Nov 2025 09:37:58 +1000 Subject: [PATCH 16/16] Remove more debug foo --- spec/grover/processor_spec.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/spec/grover/processor_spec.rb b/spec/grover/processor_spec.rb index f89f37c..d74e532 100644 --- a/spec/grover/processor_spec.rb +++ b/spec/grover/processor_spec.rb @@ -1093,8 +1093,6 @@ let(:firefox_path) { Dir[File.expand_path('~/.cache/puppeteer/firefox/**/firefox')].last } let(:url_or_html) { 'http://localhost:4567/headers' } - before { allow(Grover.configuration).to receive(:node_env_vars).and_return 'DEBUG' => 'puppeteer:*' } - it { expect(pdf_text_content).to match(/Request contained \d+ headers/) } it { expect(pdf_text_content).to include '1. host localhost:4567' } it { expect(pdf_text_content).to match %r{\d\. user-agent Mozilla/5.0 .* Firefox/} }