diff --git a/README.md b/README.md index 3563235..34d71ff 100644 --- a/README.md +++ b/README.md @@ -164,6 +164,8 @@ if the initial content request or any subsequent asset request returns a bad res The `raise_on_js_error` option, when enabled, will raise a `Grover::JavaScript::PageRenderError` if any uncaught Javascript errors occur when trying to render the page. +The `javascript_enabled` option can be used to disable JavaScript. See https://github.com/puppeteer/puppeteer/blob/main/docs/api/puppeteer.page.setjavascriptenabled.md + The Chrome/Chromium executable path can be overridden with the `executable_path` option. Supplementary JavaScript can be executed on the page (after render and before conversion to PDF/image) diff --git a/lib/grover/js/processor.cjs b/lib/grover/js/processor.cjs index 844268d..180e1dd 100644 --- a/lib/grover/js/processor.cjs +++ b/lib/grover/js/processor.cjs @@ -214,6 +214,11 @@ const _processPage = (async (convertAction, uriOrHtml, options) => { await cdp.send('Browser.setPermission', { permission: { name: 'local-network-access' }, setting: 'granted' }); } + const javaScriptEnabled = options.javaScriptEnabled; delete options.javaScriptEnabled; + if (javaScriptEnabled !== undefined) { + await page.setJavaScriptEnabled(javaScriptEnabled); + } + const raiseOnRequestFailure = options.raiseOnRequestFailure; delete options.raiseOnRequestFailure; if (raiseOnRequestFailure) { page.on('requestfinished', (request) => { diff --git a/lib/grover/options_fixer.rb b/lib/grover/options_fixer.rb index 4296d5a..4e66a1e 100644 --- a/lib/grover/options_fixer.rb +++ b/lib/grover/options_fixer.rb @@ -9,6 +9,9 @@ class Grover class OptionsFixer FALSE_VALUES = [nil, false, 0, '0', 'f', 'F', 'false', 'FALSE', 'off', 'OFF'].freeze + JAVASCRIPT_OPTIONS = %w[evaluate_on_new_document execute_script script_tag_options wait_for_function].freeze + private_constant :JAVASCRIPT_OPTIONS + def initialize(options) @options = options end @@ -18,6 +21,7 @@ def run fix_integer_options! fix_float_options! fix_array_options! + disable_javascript_options! @options end @@ -35,7 +39,7 @@ def fix_boolean_options! fix_options!( 'display_header_footer', 'full_page', 'landscape', 'omit_background', 'prefer_css_page_size', 'print_background', 'viewport.has_touch', 'viewport.is_landscape', 'viewport.is_mobile', 'bypass_csp', - 'raise_on_request_failure', 'raise_on_js_error' + 'raise_on_request_failure', 'raise_on_js_error', 'javascript_enabled' ) { |value| !FALSE_VALUES.include?(value) } end @@ -60,5 +64,20 @@ def fix_array_options! value.is_a?(String) ? YAML.safe_load(value) : value end end + + def disable_javascript_options! + return if @options['javascript_enabled'] != false + + JAVASCRIPT_OPTIONS.each do |option| + disable_javascript_option!(option) + end + end + + def disable_javascript_option!(option) + return unless @options.key?(option) + + @options.delete(option) + warn "#{self.class}: option #{option} has been disabled because javascript_enabled is set to false" + end end end diff --git a/lib/grover/utils.rb b/lib/grover/utils.rb index 317b1e1..b884381 100644 --- a/lib/grover/utils.rb +++ b/lib/grover/utils.rb @@ -9,7 +9,8 @@ class Utils 'css' => 'CSS', 'csp' => 'CSP', 'http' => 'HTTP', - 'js' => 'JS' + 'js' => 'JS', + 'javascript' => 'JavaScript' }.freeze private_constant :ACRONYMS @@ -94,9 +95,9 @@ def self.normalize_object(object, excluding: []) # Regex sourced from ActiveSupport camelize # def self.normalize_key(key) - key.to_s.downcase.gsub(%r{(?:_|(/))([a-z\d]*)}) do + key.to_s.downcase.gsub(%r{(?:^|_|(/))([a-z\d]*)}) do "#{Regexp.last_match(1)}#{ACRONYMS[Regexp.last_match(2)] || Regexp.last_match(2).capitalize}" - end + end.sub(/^[[:alpha:]]/, &:downcase) end private_class_method :normalize_key end diff --git a/spec/grover/options_fixer_spec.rb b/spec/grover/options_fixer_spec.rb index b328ff9..5c55c75 100644 --- a/spec/grover/options_fixer_spec.rb +++ b/spec/grover/options_fixer_spec.rb @@ -109,4 +109,40 @@ expect(fixed_options['launch_args']).to eq ['--some-option'] end end + + context 'when javascript_enabled option is set' do + let(:options) do + { + 'javascript_enabled' => enabled, + 'evaluate_on_new_document' => 'test 1', + 'execute_script' => 'test 2', + 'script_tag_options' => 'test 3', + 'wait_for_function' => 'test 4' + } + end + + context 'when it is true' do + let(:enabled) { 'true' } + + it 'keep javascript options' do + expect(fixed_options['javascript_enabled']).to be true + expect(fixed_options['evaluate_on_new_document']).to eq 'test 1' + expect(fixed_options['execute_script']).to eq 'test 2' + expect(fixed_options['script_tag_options']).to eq 'test 3' + expect(fixed_options['wait_for_function']).to eq 'test 4' + end + end + + context 'when it is false' do + let(:enabled) { 'false' } + + it 'disable javascript options' do + expect(fixed_options['javascript_enabled']).to be false + expect(fixed_options['evaluate_on_new_document']).to be_nil + expect(fixed_options['execute_script']).to be_nil + expect(fixed_options['script_tag_options']).to be_nil + expect(fixed_options['wait_for_function']).to be_nil + end + end + end end diff --git a/spec/grover/processor_spec.rb b/spec/grover/processor_spec.rb index c8189e6..441f34d 100644 --- a/spec/grover/processor_spec.rb +++ b/spec/grover/processor_spec.rb @@ -1190,6 +1190,35 @@ end end + context 'when javaScriptEnabled option is set' do + let(:options) { basic_header_footer_options.merge('javaScriptEnabled' => enabled) } + + let(:url_or_html) do + <<-HTML + +
+ + + + + HTML + end + + context 'when it is true' do + let(:enabled) { true } + + it { expect(pdf_text_content).to include 'output from script tag' } + it { expect(pdf_text_content).not_to include 'output from noscript tag' } + end + + context 'when it is false' do + let(:enabled) { false } + + it { expect(pdf_text_content).not_to include 'output from script tag' } + it { expect(pdf_text_content).to include 'output from noscript tag' } + end + end + # < 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 diff --git a/spec/grover/utils_spec.rb b/spec/grover/utils_spec.rb index a47d089..dc7c9d4 100644 --- a/spec/grover/utils_spec.rb +++ b/spec/grover/utils_spec.rb @@ -304,7 +304,8 @@ prefer_css_page_size: true, bypass_csp: false, extra_http_headers: { 'Foo' => 'Bar' }, - raise_on_js_error: true + raise_on_js_error: true, + javascript_enabled: false } end @@ -314,7 +315,8 @@ 'preferCSSPageSize' => true, 'bypassCSP' => false, 'extraHTTPHeaders' => { 'foo' => 'Bar' }, - 'raiseOnJSError' => true + 'raiseOnJSError' => true, + 'javaScriptEnabled' => false ) ) end @@ -328,7 +330,8 @@ 'preferCSSPageSize' => true, 'bypassCSP' => false, 'extraHTTPHeaders' => { 'Foo' => 'Bar' }, - 'raiseOnJSError' => true + 'raiseOnJSError' => true, + 'javaScriptEnabled' => false ) ) end