Skip to content

Commit

Permalink
Implement channel parameter for Puppeteer.launch
Browse files Browse the repository at this point in the history
  • Loading branch information
YusukeIwaki committed Jul 2, 2021
1 parent b5f9cdb commit 12c3f2a
Show file tree
Hide file tree
Showing 7 changed files with 188 additions and 78 deletions.
1 change: 0 additions & 1 deletion lib/puppeteer/launcher.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
require_relative './launcher/base'
require_relative './launcher/browser_options'
require_relative './launcher/chrome'
require_relative './launcher/chrome_arg_options'
Expand Down
66 changes: 0 additions & 66 deletions lib/puppeteer/launcher/base.rb

This file was deleted.

68 changes: 64 additions & 4 deletions lib/puppeteer/launcher/chrome.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@

# https://github.com/puppeteer/puppeteer/blob/main/src/node/Launcher.ts
module Puppeteer::Launcher
class Chrome < Base
class Chrome
def initialize(project_root:, preferred_revision:, is_puppeteer_core:)
@project_root = project_root
@preferred_revision = preferred_revision
@is_puppeteer_core = is_puppeteer_core
end

# @param {!(Launcher.LaunchOptions & Launcher.ChromeArgOptions & Launcher.BrowserOptions)=} options
# @return {!Promise<!Browser>}
def launch(options = {})
Expand Down Expand Up @@ -38,7 +44,12 @@ def launch(options = {})
chrome_arguments << "--user-data-dir=#{temporary_user_data_dir}"
end

chrome_executable = @launch_options.executable_path || resolve_executable_path
chrome_executable =
if @launch_options.channel
executable_path_for_channel(@launch_options.channel.to_s)
else
@launch_options.executable_path || executable_path_for_channel('chrome')
end
use_pipe = chrome_arguments.include?('--remote-debugging-pipe')
runner = Puppeteer::BrowserRunner.new(chrome_executable, chrome_arguments, temporary_user_data_dir)
runner.start(
Expand Down Expand Up @@ -201,8 +212,57 @@ def connect(options = {})
end

# @return {string}
def executable_path
resolve_executable_path
def executable_path(channel: nil)
if channel
executable_path_for_channel(channel.to_s)
else
executable_path_for_channel('chrome')
end
end

CHROMIUM_CHANNELS = {
windows: {
'chrome' => "#{ENV['PROGRAMFILES']}\\Google\\Chrome\\Application\\chrome.exe",
'chrome-beta' => "#{ENV['PROGRAMFILES']}\\Google\\Chrome Beta\\Application\\chrome.exe",
'chrome-canary' => "#{ENV['PROGRAMFILES']}\\Google\\Chrome SxS\\Application\\chrome.exe",
'chrome-dev' => "#{ENV['PROGRAMFILES']}\\Google\\Chrome Dev\\Application\\chrome.exe",
'msedge' => "#{ENV['PROGRAMFILES(X86)']}\\Microsoft\\Edge\\Application\\msedge.exe",
},
darwin: {
'chrome' => '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
'chrome-beta' => '/Applications/Google Chrome Beta.app/Contents/MacOS/Google Chrome Beta',
'chrome-canary' => '/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary',
'chrome-dev' => '/Applications/Google Chrome Dev.app/Contents/MacOS/Google Chrome Dev',
'msedge' => '/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge',
},
linux: {
'chrome' => '/opt/google/chrome/chrome',
'chrome-beta' => '/opt/google/chrome-beta/chrome',
'chrome-dev' => '/opt/google/chrome-unstable/chrome',
},
}.freeze

# @param channel [String]
private def executable_path_for_channel(channel)
chrome_path_map =
if Puppeteer.env.windows?
CHROMIUM_CHANNELS[:windows]
elsif Puppeteer.env.darwin?
CHROMIUM_CHANNELS[:darwin]
else
CHROMIUM_CHANNELS[:linux]
end

chrome_path = chrome_path_map[channel]
unless chrome_path
raise ArgumentError.new("Invalid channel: '#{channel}'. Allowed channel is #{chrome_path_map.keys}")
end

unless File.exist?(chrome_path)
raise "#{channel} is not installed on this system.\nExpected path: #{chrome_path}"
end

chrome_path
end

def product
Expand Down
52 changes: 48 additions & 4 deletions lib/puppeteer/launcher/firefox.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@

# https://github.com/puppeteer/puppeteer/blob/main/src/node/Launcher.ts
module Puppeteer::Launcher
class Firefox < Base
class Firefox
def initialize(project_root:, preferred_revision:, is_puppeteer_core:)
@project_root = project_root
@preferred_revision = preferred_revision
@is_puppeteer_core = is_puppeteer_core
end

# @param {!(Launcher.LaunchOptions & Launcher.ChromeArgOptions & Launcher.BrowserOptions)=} options
# @return {!Promise<!Browser>}
def launch(options = {})
Expand Down Expand Up @@ -32,7 +38,12 @@ def launch(options = {})
firefox_arguments << temporary_user_data_dir
end

firefox_executable = @launch_options.executable_path || resolve_executable_path
firefox_executable =
if @launch_options.channel
executable_path_for_channel(@launch_options.channel.to_s)
else
@launch_options.executable_path || executable_path_for_channel('nightly')
end
runner = Puppeteer::BrowserRunner.new(firefox_executable, firefox_arguments, temporary_user_data_dir)
runner.start(
handle_SIGHUP: @launch_options.handle_SIGHUP?,
Expand Down Expand Up @@ -123,8 +134,41 @@ def connect(options = {})
end

# @return {string}
def executable_path
resolve_executable_path
def executable_path(channel: nil)
if channel
executable_path_for_channel(channel.to_s)
else
executable_path_for_channel('firefox')
end
end

FIREFOX_EXECUTABLE_PATHS = {
windows: "#{ENV['PROGRAMFILES']}\\Firefox Nightly\\firefox.exe",
darwin: '/Applications/Firefox Nightly.app/Contents/MacOS/firefox',
linux: '/usr/bin/firefox',
}.freeze

# @param channel [String]
private def executable_path_for_channel(channel)
allowed = ['firefox', 'firefox-nightly', 'nightly']
unless allowed.include?(channel)
raise ArgumentError.new("Invalid channel: '#{channel}'. Allowed channel is #{allowed}")
end

firefox_path =
if Puppeteer.env.windows?
FIREFOX_EXECUTABLE_PATHS[:windows]
elsif Puppeteer.env.darwin?
FIREFOX_EXECUTABLE_PATHS[:darwin]
else
FIREFOX_EXECUTABLE_PATHS[:linux]
end

unless File.exist?(firefox_path)
raise "Nightly version of Firefox is not installed on this system.\nExpected path: #{firefox_path}"
end

firefox_path
end

def product
Expand Down
3 changes: 2 additions & 1 deletion lib/puppeteer/launcher/launch_options.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class LaunchOptions
# @property {!Object<string, string | undefined>=} env
# @property {boolean=} pipe
def initialize(options)
@channel = options[:channel]
@executable_path = options[:executable_path]
@ignore_default_args = options[:ignore_default_args] || false
@handle_SIGINT = options[:handle_SIGINT] || true
Expand All @@ -43,7 +44,7 @@ def initialize(options)
@pipe = options[:pipe] || false
end

attr_reader :executable_path, :ignore_default_args, :timeout, :env
attr_reader :channel, :executable_path, :ignore_default_args, :timeout, :env

def handle_SIGINT?
@handle_SIGINT
Expand Down
7 changes: 5 additions & 2 deletions lib/puppeteer/puppeteer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ def initialize(project_root:, preferred_revision:, is_puppeteer_core:)
class NoViewport ; end

# @param product [String]
# @param channel [String|Symbol]
# @param executable_path [String]
# @param ignore_default_args [Array<String>|nil]
# @param handle_SIGINT [Boolean]
Expand All @@ -30,6 +31,7 @@ class NoViewport ; end
# @return [Puppeteer::Browser]
def launch(
product: nil,
channel: nil,
executable_path: nil,
ignore_default_args: nil,
handle_SIGINT: nil,
Expand All @@ -48,6 +50,7 @@ def launch(
slow_mo: nil
)
options = {
channel: channel&.to_s,
executable_path: executable_path,
ignore_default_args: ignore_default_args,
handle_SIGINT: handle_SIGINT,
Expand Down Expand Up @@ -118,8 +121,8 @@ def connect(
end

# @return [String]
def executable_path
launcher.executable_path
def executable_path(channel: nil)
launcher.executable_path(channel: channel)
end

private def launcher
Expand Down
69 changes: 69 additions & 0 deletions spec/puppeteer/launcher_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
require 'spec_helper'

RSpec.describe Puppeteer::Launcher do
before { skip unless Puppeteer.env.darwin? }
let(:instance) {
Puppeteer::Launcher.new(
project_root: '/tmp',
preferred_revision: 'latest',
is_puppeteer_core: true,
product: product,
)
}

describe 'executable_path' do
subject { instance.executable_path(channel: channel) }

context 'chrome' do
let(:product) { 'chrome' }

context 'without channel param' do
subject { instance.executable_path }

it { is_expected.to eq('/Applications/Google Chrome.app/Contents/MacOS/Google Chrome') }
end

context 'with invalid channel param' do
let(:channel) { 'hoge' }

it 'raises ArgumentError' do
expect { subject }.to raise_error(/Allowed channel is \["chrome", "chrome-beta", "chrome-canary", "chrome-dev", "msedge"\]/)
end
end

context 'with channel: chrome' do
let(:channel) { :chrome }

it { is_expected.to eq('/Applications/Google Chrome.app/Contents/MacOS/Google Chrome') }
end

context 'with channel: chrome-canary' do
let(:channel) { 'chrome-canary' }

it { is_expected.to eq('/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary') }
end
end

context 'firefox' do
let(:product) { 'firefox' }

context 'without channel param' do
subject { instance.executable_path }
end

context 'with invalid channel param' do
let(:channel) { 'hoge' }

it 'raises ArgumentError' do
expect { subject }.to raise_error(/\["firefox", "firefox-nightly", "nightly"\]/)
end
end

context 'with channel: nightly' do
let(:channel) { 'nightly' }

it { is_expected.to eq('/Applications/Firefox Nightly.app/Contents/MacOS/firefox') }
end
end
end
end

0 comments on commit 12c3f2a

Please sign in to comment.