Skip to content

Commit

Permalink
Merge pull request #336 from YusukeIwaki/fix-335
Browse files Browse the repository at this point in the history
Fix logic for launching Firefox >= 129
  • Loading branch information
YusukeIwaki authored Sep 14, 2024
2 parents 2cb9cb6 + 46d79f9 commit 7bd632c
Show file tree
Hide file tree
Showing 14 changed files with 84 additions and 54 deletions.
24 changes: 11 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,19 +44,19 @@ require 'puppeteer-ruby'
Puppeteer.launch(headless: false, slow_mo: 50, args: ['--window-size=1280,800']) do |browser|
page = browser.new_page
page.viewport = Puppeteer::Viewport.new(width: 1280, height: 800)
page.goto("https://github.com/", wait_until: 'domcontentloaded')
with_network_retry { page.goto("https://github.com/", wait_until: 'domcontentloaded') }

form = page.query_selector("form.js-site-search-form")
search_input = form.query_selector("input.header-search-input")
page.wait_for_selector('[placeholder="Search or jump to..."]').click
search_input = page.wait_for_selector('input[name="query-builder-test"]')
search_input.click
page.keyboard.type_text("puppeteer")

page.wait_for_navigation do
search_input.press('Enter')
search_input.press("Enter")
end

list = page.query_selector("ul.repo-list")
items = list.query_selector_all("div.f4")
list = page.wait_for_selector('[data-testid="results-list"]')
items = list.query_selector_all(".search-title")
items.each do |item|
title = item.eval_on_selector("a", "a => a.innerText")
puts("==> #{title}")
Expand Down Expand Up @@ -95,16 +95,16 @@ More usage examples can be found [here](https://github.com/YusukeIwaki/puppeteer

Following packages are required.

* Google Chrome or Chromium
* In Debian-based images, `google-chrome-stable`
* In Alpine-based images, `chromium`
- Google Chrome or Chromium
- In Debian-based images, `google-chrome-stable`
- In Alpine-based images, `chromium`

Also, CJK font will be required for Chinese, Japanese, Korean sites.

### References

* Puppeteer official README: https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md#running-puppeteer-in-docker
* puppeteer-ruby example: https://github.com/YusukeIwaki/puppeteer-ruby-example/tree/master/docker_chromium
- Puppeteer official README: https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md#running-puppeteer-in-docker
- puppeteer-ruby example: https://github.com/YusukeIwaki/puppeteer-ruby-example/tree/master/docker_chromium

## :bulb: Collaboration with Selenium or Capybara

Expand Down Expand Up @@ -224,12 +224,10 @@ RSpec.describe 'Sample integration tests', driver: :null do
end
```


## API

https://yusukeiwaki.github.io/puppeteer-ruby-docs/


## Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/YusukeIwaki/puppeteer-ruby.
2 changes: 1 addition & 1 deletion docs/api_coverage.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# API coverages
- Puppeteer version: v19.5.0
- puppeteer-ruby version: 0.45.4
- puppeteer-ruby version: 0.45.5

## Puppeteer

Expand Down
4 changes: 4 additions & 0 deletions lib/puppeteer/browser_runner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,10 @@ def setup_connection(use_pipe:, timeout:, slow_mo:, preferred_revision:)
Timeout.timeout(timeout / 1000.0) do
loop do
line = browser_process.stderr.readline
/^WebDriver BiDi listening on (ws:\/\/.*)$/.match(line) do |m|
raise NotImplementedError.new('WebDriver BiDi support is not yet implemented')
end

/^DevTools listening on (ws:\/\/.*)$/.match(line) do |m|
return m[1].gsub(/\r/, '')
end
Expand Down
2 changes: 2 additions & 0 deletions lib/puppeteer/connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,10 @@ class ResponseDebugPrinter
NON_DEBUG_PRINT_METHODS = [
'Network.dataReceived',
'Network.loadingFinished',
'Network.requestServedFromCache',
'Network.requestWillBeSent',
'Network.requestWillBeSentExtraInfo',
'Network.resourceChangedPriority',
'Network.responseReceived',
'Network.responseReceivedExtraInfo',
'Page.lifecycleEvent',
Expand Down
57 changes: 43 additions & 14 deletions lib/puppeteer/launcher/firefox.rb
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,11 @@ def executable_path(channel: nil)

FIREFOX_EXECUTABLE_PATHS = {
windows: "#{ENV['PROGRAMFILES']}\\Firefox Nightly\\firefox.exe",
darwin: '/Applications/Firefox Nightly.app/Contents/MacOS/firefox',
darwin: -> {
['Firefox Nightly.app', 'Firefox Developer Edition.app'].map do |app|
"/Applications/#{app}/Contents/MacOS/firefox"
end.find { |path| File.exist?(path) }
},
linux: -> { Puppeteer::ExecutablePathFinder.new('firefox').find_first },
}.freeze

Expand Down Expand Up @@ -161,7 +165,7 @@ class DefaultArgs

# @param options [Launcher::ChromeArgOptions]
def initialize(chrome_arg_options)
firefox_arguments = ['--no-remote']
firefox_arguments = []

if Puppeteer.env.darwin?
firefox_arguments << '--foreground'
Expand Down Expand Up @@ -236,7 +240,6 @@ def default_args(options = nil)
'browser.safebrowsing.blockedURIs.enabled': false,
'browser.safebrowsing.downloads.enabled': false,
'browser.safebrowsing.malware.enabled': false,
'browser.safebrowsing.passwords.enabled': false,
'browser.safebrowsing.phishing.enabled': false,

# Disable updates to search engines.
Expand All @@ -262,6 +265,9 @@ def default_args(options = nil)
# Do not warn when multiple tabs will be opened
'browser.tabs.warnOnOpen': false,

# Do not automatically offer translations, as tests do not expect this.
'browser.translations.automaticallyPopup': false,

# Disable the UI tour.
'browser.uitour.enabled': false,
# Turn off search suggestions in the location bar so as not to trigger
Expand Down Expand Up @@ -324,30 +330,33 @@ def default_args(options = nil)
# Make sure opening about:addons will not hit the network
'extensions.webservice.discoverURL': "http://#{server}/dummy/discoveryURL",

# Temporarily force disable BFCache in parent (https://bit.ly/bug-1732263)
'fission.bfcacheInParent': false,
# Force all web content to use a single content process
'fission.webContentIsolationStrategy': 0,

# Allow the application to have focus even it runs in the background
'focusmanager.testmode': true,

# Disable useragent updates
'general.useragent.updates.enabled': false,

# Always use network provider for geolocation tests so we bypass the
# macOS dialog raised by the corelocation provider
'geo.provider.testing': true,

# Do not scan Wifi
'geo.wifi.scan': false,

# No hang monitor
'hangmonitor.timeout': 0,

# Show chrome errors and warnings in the error console
'javascript.options.showInConsole': true,

# Disable download and usage of OpenH264: and Widevine plugins
'media.gmp-manager.updateEnabled': false,
# Prevent various error message on the console
# jest-puppeteer asserts that no error message is emitted by the console
'network.cookie.cookieBehavior': 0,

# Disable the GFX sanity window
'media.sanity-test.disabled': true,

# Disable experimental feature that is only available in Nightly
'network.cookie.sameSite.laxByDefault': false,

# Do not prompt for temporary redirects
'network.http.prompt-temp-redirect': false,
Expand All @@ -367,15 +376,17 @@ def default_args(options = nil)

'privacy.trackingprotection.enabled': false,

# Enable Remote Agent
# https://bugzilla.mozilla.org/show_bug.cgi?id=1544393
# Can be removed once Firefox 89 is no longer supported
# https://bugzilla.mozilla.org/show_bug.cgi?id=1710839
'remote.enabled': true,

# Don't do network connections for mitm priming
'security.certerrors.mitm.priming.enabled': false,

# Local documents have access to all other local documents,
# including directory listings
'security.fileuri.strict_origin_policy': false,

# Do not wait for the notification button security delay
'security.notification_enable_delay': 0,

Expand All @@ -385,6 +396,7 @@ def default_args(options = nil)
# Do not automatically fill sign-in forms with known usernames and
# passwords
'signon.autofillForms': false,

# Disable password capture, so that tests that include forms are not
# influenced by the presence of the persistent doorhanger notification
'signon.rememberSignons': false,
Expand All @@ -400,7 +412,24 @@ def default_args(options = nil)

# Prevent starting into safe mode after application crashes
'toolkit.startup.max_resumed_crashes': -1,
}
}.merge({ # https://github.com/puppeteer/puppeteer/blob/puppeteer-v23.2.2/packages/puppeteer-core/src/node/FirefoxLauncher.ts#L45-L53
# Do not close the window when the last tab gets closed
'browser.tabs.closeWindowWithLastTab': false,
# Prevent various error message on the console
# jest-puppeteer asserts that no error message is emitted by the console
'network.cookie.cookieBehavior': 0,
# Temporarily force disable BFCache in parent (https://bit.ly/bug-1732263)
'fission.bfcacheInParent': false,
# Only enable the CDP protocol
'remote.active-protocols': 2,
}).merge({ # https://github.com/puppeteer/puppeteer/blob/puppeteer-v23.2.2/packages/puppeteer-core/src/node/FirefoxLauncher.ts#L55-L60
# Force all web content to use a single content process. TODO: remove
# this once Firefox supports mouse event dispatch from the main frame
# context. Once this happens, webContentIsolationStrategy should only
# be set for CDP. See
# https://bugzilla.mozilla.org/show_bug.cgi?id=1773393
'fission.webContentIsolationStrategy': 0,
})

default_preferences.merge(extra_prefs)
end
Expand Down
2 changes: 1 addition & 1 deletion puppeteer-ruby.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Gem::Specification.new do |spec|
spec.add_development_dependency 'rspec_junit_formatter' # for CircleCI.
spec.add_development_dependency 'rubocop', '~> 1.50.0'
spec.add_development_dependency 'rubocop-rspec'
spec.add_development_dependency 'sinatra'
spec.add_development_dependency 'sinatra', '< 4.0.0'
spec.add_development_dependency 'webrick'
spec.add_development_dependency 'yard'
end
4 changes: 2 additions & 2 deletions spec/integration/browser_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

RSpec.describe Puppeteer::Browser, puppeteer: :browser do
describe 'version' do
it 'should indicate we are in headless' do
expect(browser.version).to start_with('Headless')
it 'should return version' do
expect(browser.version).to match(/Chrome|Firefox/)
end
end

Expand Down
5 changes: 4 additions & 1 deletion spec/integration/coverage_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,10 @@
end
expect(coverage.size).to eq(1)
expect(coverage.first.url).to include('/csscoverage/media.html')
expect(coverage.first.ranges).to contain_exactly({ start: 17, end: 38 })
expect(coverage.first.ranges).to contain_exactly(
{ start: 8, end: 15 },
{ start: 17, end: 38 },
)
end

it 'should work with complicated usecases', sinatra: true do
Expand Down
3 changes: 2 additions & 1 deletion spec/integration/element_handle_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -260,11 +260,12 @@
}
JAVASCRIPT

page.evaluate(<<~JAVASCRIPT)
page.async_evaluate(<<~JAVASCRIPT)
async () => {
return new Promise((resolve) => window.requestAnimationFrame(resolve));
}
JAVASCRIPT
sleep 1

frame = page.frames[1]
div_handle = frame.query_selector('div')
Expand Down
8 changes: 4 additions & 4 deletions spec/integration/example_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,17 +67,17 @@ def with_network_retry(max_retry: 2, timeout: 4, &block)
page.viewport = Puppeteer::Viewport.new(width: 1280, height: 800)
with_network_retry { page.goto("https://github.com/", wait_until: 'domcontentloaded') }

form = page.query_selector("form.js-site-search-form")
search_input = form.query_selector("input.header-search-input")
page.wait_for_selector('[placeholder="Search or jump to..."]').click
search_input = page.wait_for_selector('input[name="query-builder-test"]')
search_input.click
page.keyboard.type_text("puppeteer")

page.wait_for_navigation do
search_input.press("Enter")
end

list = page.query_selector("ul.repo-list")
items = list.query_selector_all("div.f4")
list = page.wait_for_selector('[data-testid="results-list"]')
items = list.query_selector_all(".search-title")
items.each do |item|
title = item.eval_on_selector("a", "a => a.innerText")
puts("==> #{title}")
Expand Down
6 changes: 5 additions & 1 deletion spec/integration/golden-chromium/csscoverage-involved.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@
"start": 149,
"end": 297
},
{
"start": 306,
"end": 323
},
{
"start": 327,
"end": 433
}
],
"text": "\n@charset \"utf-8\";\n@namespace svg url(http://www.w3.org/2000/svg);\n@font-face {\n font-family: \"Example Font\";\n src: url(\"./Dosis-Regular.ttf\");\n}\n\n#fluffy {\n border: 1px solid black;\n z-index: 1;\n /* -webkit-disabled-property: rgb(1, 2, 3) */\n -lol-cats: \"dogs\" /* non-existing property */\n}\n\n@media (min-width: 1px) {\n span {\n -webkit-border-radius: 10px;\n font-family: \"Example Font\";\n animation: 1s identifier;\n }\n}\n"
}
]
]
10 changes: 1 addition & 9 deletions spec/integration/keyboard_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -354,15 +354,7 @@

key, code, meta_key = page.evaluate('result')
expect(key).to eq('Meta')
if Puppeteer.env.firefox?
if Puppeteer.env.darwin?
expect(code).to eq('OSLeft')
else
expect(code).to eq('AltLeft')
end
else
expect(code).to eq('MetaLeft')
end
expect(code).to eq('MetaLeft')
expect(meta_key).to eq(true)
end
end
Expand Down
8 changes: 4 additions & 4 deletions spec/integration/launcher_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -307,13 +307,13 @@
if Puppeteer.env.firefox?
expected_args =
if Puppeteer.env.darwin?
%w(--headless --no-remote --foreground)
%w(--headless --foreground)
elsif Puppeteer.env.windows?
%w(--headless --no-remote --wait-for-browser)
%w(--headless --wait-for-browser)
else
%w(--headless --no-remote)
%w(--headless)
end
unexpected_args = %w(--headless --no-remote --foreground --wait-for-browser) - expected_args
unexpected_args = %w(--headless --foreground --wait-for-browser) - expected_args
expect(Puppeteer.default_args).to include(*expected_args)
expect(Puppeteer.default_args).not_to include(*unexpected_args)
else
Expand Down
3 changes: 0 additions & 3 deletions spec/integration/oopif_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,8 @@ def oopifs(context)
attach_frame(page, 'frame1', server_empty_page)
end

expect(frame).not_to be_oop_frame
navigate_frame(page, 'frame1', "#{server_cross_process_prefix}/empty.html")
expect(frame).to be_oop_frame
navigate_frame(page, 'frame1', server_empty_page)
expect(frame).not_to be_oop_frame

expect(page.frames.size).to eq(2)
end
Expand Down

0 comments on commit 7bd632c

Please sign in to comment.