venetian 0.3.0-aarch64-linux → 0.3.1-aarch64-linux
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 +4 -4
- data/README.md +10 -3
- data/lib/venetian/browser_installer.rb +82 -5
- data/lib/venetian/browser_runner_extensions.rb +7 -3
- data/lib/venetian/connection_extensions.rb +28 -0
- data/lib/venetian/executable.rb +139 -45
- data/lib/venetian/playwright.rb +1 -0
- data/lib/venetian/system_test_case_extension.rb +21 -8
- data/lib/venetian/upstream.rb +2 -2
- data/lib/venetian/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 42659ef11b918624297a6f22b27b26bf83c5b7b036e6e3d11b1b08987239a682
|
|
4
|
+
data.tar.gz: 19348cc2e88614446c99c212f999ffa186ce7972564f5579763d11ad664f0577
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bfed6f8650a1af0ebd5609018e789360fa7de20edd5b48359650cfdcc77a8267552775aa8f79999e6cfcd0bb2172c7c98cca4dfe974e4c2b7828c1344b62e3f2
|
|
7
|
+
data.tar.gz: f88f99189c70cdf492117484b33f04e3c65433064ee043a788dcbc650ab9c77444db8d008b39f18fb023864c2d6dce7ac4dd8040beccf59acc9171332cda8514
|
data/README.md
CHANGED
|
@@ -80,13 +80,20 @@ due to e.g. differences between package managers and package names across distro
|
|
|
80
80
|
so dependency installation happens only if a compatible package manager is found.
|
|
81
81
|
Depending on what you're doing, you may not need to install dependencies,
|
|
82
82
|
but if you do and your distro is unsupported, you will need to work out what you need and deal with that first.
|
|
83
|
+
On Windows, Firefox also needs the [Microsoft Visual C++ Redistributable](https://learn.microsoft.com/cpp/windows/latest-supported-vc-redist),
|
|
84
|
+
which Playwright doesn't install; you'll get a warning after installation if it's missing.
|
|
83
85
|
|
|
84
|
-
|
|
85
|
-
if
|
|
86
|
-
|
|
86
|
+
Browsers already installed (e.g. from a restored cache) are left alone. If the browsers directory
|
|
87
|
+
(or `PLAYWRIGHT_BROWSERS_PATH`, if set) is read-only, as with a prepopulated cache, browsers aren't installed at all,
|
|
88
|
+
since Playwright can't take its lock there, though dependencies still are if needed.
|
|
89
|
+
When parallelizing tests, there's also the issue of multiple processes all trying to acquire the package manager lock,
|
|
90
|
+
so installations are serialized across processes. On top of this, if you use Rails system tests with `ActionDispatch::SystemTestCase`,
|
|
91
|
+
all required browsers are installed before disabling auto-installation and then forking.
|
|
87
92
|
|
|
88
93
|
Browsers aren't installed automatically if you pass your own `:playwright_cli_executable_path`, or connect to a server with
|
|
89
94
|
`:playwright_server_endpoint_url` or `:browser_server_endpoint_url`, since the bundled executable won't be the one running them.
|
|
95
|
+
Nor are they if you pass `:executablePath`, or a `:channel` for a system-wide browser like `chrome` or `msedge`
|
|
96
|
+
(install these with e.g. `playwright install chrome`), but other channels are installed instead of the browser type.
|
|
90
97
|
You can also turn installation off with `Venetian.auto_install_browsers = false`, or just dependency installation with
|
|
91
98
|
`Venetian.auto_install_dependencies = false`.
|
|
92
99
|
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "pathname"
|
|
4
|
+
require "tmpdir"
|
|
5
|
+
|
|
3
6
|
module Venetian
|
|
4
7
|
# # Browser Installer
|
|
5
8
|
#
|
|
@@ -18,10 +21,63 @@ module Venetian
|
|
|
18
21
|
Executable.capture("install-deps", *browser&.to_s, "--dry-run", echo: debug?)
|
|
19
22
|
end
|
|
20
23
|
|
|
24
|
+
def install_into_browsers_path(browser, deps: nil)
|
|
25
|
+
if browsers_to_install.fetch(browser) { browsers_path_writable? }
|
|
26
|
+
run_installer "install", *browser, *("--with-deps" if deps)
|
|
27
|
+
elsif deps
|
|
28
|
+
run_installer "install-deps", *browser
|
|
29
|
+
end
|
|
30
|
+
browsers_to_install[browser] = false
|
|
31
|
+
dependencies_to_install[browser] = false if deps
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def browsers_path_writable?
|
|
35
|
+
[expanded_browsers_path, expanded_browsers_path.join(LINKS_DIRECTORY)].all? do |path|
|
|
36
|
+
Dir.mktmpdir(WRITE_PROBE_PREFIX, path.ascend.find(&:directory?)) { true }
|
|
37
|
+
end
|
|
38
|
+
rescue SystemCallError
|
|
39
|
+
false
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def default_cache_path
|
|
43
|
+
if Gem.win_platform?
|
|
44
|
+
env_path("LOCALAPPDATA") || Pathname(Dir.home).join("AppData", "Local")
|
|
45
|
+
elsif Gem::Platform.local.os == "darwin"
|
|
46
|
+
Pathname(Dir.home).join("Library", "Caches")
|
|
47
|
+
else
|
|
48
|
+
env_path("XDG_CACHE_HOME") || Pathname(Dir.home).join(".cache")
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def env_path(name)
|
|
53
|
+
return if (path = ENV.fetch(name, "")).empty?
|
|
54
|
+
|
|
55
|
+
Pathname(path)
|
|
56
|
+
end
|
|
57
|
+
|
|
21
58
|
def dependencies_to_install
|
|
22
59
|
@dependencies_to_install ||= {}
|
|
23
60
|
end
|
|
24
61
|
|
|
62
|
+
def browsers_to_install
|
|
63
|
+
@browsers_to_install ||= {}
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def with_install_lock
|
|
67
|
+
File.open(File.join(Dir.tmpdir, "venetian-#{Process.uid}.lock"), File::RDWR | File::CREAT, 0o600) do |file|
|
|
68
|
+
file.flock(File::LOCK_EX)
|
|
69
|
+
yield
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def run_installer(*args)
|
|
74
|
+
return Venetian.system(*args, exception: true, echo: true) if debug?
|
|
75
|
+
|
|
76
|
+
Executable.capture(*args, echo: false, merge_stderr: false).then do |output, status|
|
|
77
|
+
raise InstallError, "exit status #{status.exitstatus}\n#{output}".strip unless status.success?
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
25
81
|
def debug?
|
|
26
82
|
ENV.fetch("VENETIAN_DEBUG", nil)
|
|
27
83
|
end
|
|
@@ -36,17 +92,26 @@ module Venetian
|
|
|
36
92
|
def initialize(message = nil)
|
|
37
93
|
super([INSTALL_FAILED_MESSAGE, *message].join(": "))
|
|
38
94
|
end
|
|
95
|
+
|
|
96
|
+
def self.wrap(error) # :nodoc:
|
|
97
|
+
error.is_a?(self) ? error : new(error.message)
|
|
98
|
+
end
|
|
39
99
|
end
|
|
40
100
|
|
|
41
|
-
# Installs a browser.
|
|
101
|
+
# Installs a browser, unless it and any dependencies are already installed. Playwright skips browsers already in the
|
|
102
|
+
# browsers path, and if that's read-only (e.g. a prepopulated cache), only dependencies are installed. Raises
|
|
103
|
+
# InstallError if installation fails.
|
|
42
104
|
def self.install(browser = nil, install_dependencies: nil)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
105
|
+
with_install_lock do
|
|
106
|
+
install_into_browsers_path(browser&.to_s, deps: install_dependencies?(browser, force: install_dependencies))
|
|
107
|
+
end
|
|
46
108
|
rescue StandardError => e
|
|
47
|
-
raise InstallError
|
|
109
|
+
raise InstallError.wrap(e)
|
|
48
110
|
end
|
|
49
111
|
|
|
112
|
+
LINKS_DIRECTORY = ".links" # :nodoc:
|
|
113
|
+
WRITE_PROBE_PREFIX = ".venetian-write-probe" # :nodoc:
|
|
114
|
+
|
|
50
115
|
# Output from a dry run where Playwright couldn't spawn its package manager, so has no way to install dependencies.
|
|
51
116
|
NO_PACKAGE_MANAGER_OUTPUT = "ENOENT" # :nodoc:
|
|
52
117
|
|
|
@@ -68,6 +133,18 @@ module Venetian
|
|
|
68
133
|
end
|
|
69
134
|
end
|
|
70
135
|
|
|
136
|
+
def self.browsers_path # :nodoc:
|
|
137
|
+
case ENV.fetch("PLAYWRIGHT_BROWSERS_PATH", "")
|
|
138
|
+
when "" then default_cache_path.join("ms-playwright")
|
|
139
|
+
when "0" then Pathname(Executable.base_command.last).dirname.join(".local-browsers")
|
|
140
|
+
else Pathname(ENV.fetch("PLAYWRIGHT_BROWSERS_PATH"))
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def self.expanded_browsers_path # :nodoc:
|
|
145
|
+
browsers_path.expand_path(ENV.fetch("INIT_CWD", nil) || Dir.pwd)
|
|
146
|
+
end
|
|
147
|
+
|
|
71
148
|
def self.dependencies_supported?(...) # :nodoc:
|
|
72
149
|
warn "Venetian::BrowserInstaller.dependencies_supported? is deprecated; use dependencies_to_install? instead.",
|
|
73
150
|
category: :deprecated, uplevel: 1
|
|
@@ -4,18 +4,22 @@ module Venetian
|
|
|
4
4
|
module BrowserRunnerExtensions # :nodoc:
|
|
5
5
|
ALTERNATIVE_DRIVER_OPTIONS = %i[playwright_cli_executable_path playwright_server_endpoint_url
|
|
6
6
|
browser_server_endpoint_url].freeze
|
|
7
|
+
SYSTEM_CHANNEL_PATTERN = /\A(chrome|msedge)/
|
|
7
8
|
|
|
8
9
|
def self.browser_to_preinstall_from(options)
|
|
9
|
-
|
|
10
|
+
return if options.values_at(*ALTERNATIVE_DRIVER_OPTIONS, :executablePath).any?
|
|
11
|
+
return if options[:channel].to_s.match?(SYSTEM_CHANNEL_PATTERN)
|
|
12
|
+
|
|
13
|
+
(options[:channel] || options[:browser_type] || :chromium).to_sym
|
|
10
14
|
end
|
|
11
15
|
|
|
12
16
|
def initialize(options = {}, *args)
|
|
13
|
-
@venetian_browser = BrowserRunnerExtensions.browser_to_preinstall_from(options)
|
|
17
|
+
@venetian_browser = BrowserRunnerExtensions.browser_to_preinstall_from(options)
|
|
14
18
|
super
|
|
15
19
|
end
|
|
16
20
|
|
|
17
21
|
def start
|
|
18
|
-
BrowserInstaller.install(@venetian_browser) if @venetian_browser
|
|
22
|
+
BrowserInstaller.install(@venetian_browser) if @venetian_browser && Venetian.auto_install_browsers
|
|
19
23
|
super
|
|
20
24
|
end
|
|
21
25
|
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Venetian
|
|
4
|
+
# # Forked Connection Error
|
|
5
|
+
#
|
|
6
|
+
# Raised when a Playwright connection is used by a process forked from the one that started it.
|
|
7
|
+
class ForkedConnectionError < Error
|
|
8
|
+
def initialize(pid) # :nodoc:
|
|
9
|
+
super("This Playwright connection belongs to process #{pid}, so can't be used after forking. " \
|
|
10
|
+
"Start Playwright again in this process instead.")
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
module ConnectionExtensions # :nodoc:
|
|
15
|
+
def initialize(...)
|
|
16
|
+
@venetian_pid = Process.pid
|
|
17
|
+
super
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def async_send_message_to_server(...)
|
|
21
|
+
raise ForkedConnectionError, @venetian_pid unless Process.pid == @venetian_pid
|
|
22
|
+
|
|
23
|
+
super
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
Playwright::Connection.prepend(Venetian::ConnectionExtensions)
|
data/lib/venetian/executable.rb
CHANGED
|
@@ -11,8 +11,12 @@ module Venetian
|
|
|
11
11
|
class Executor # :nodoc:
|
|
12
12
|
public :system, :exec
|
|
13
13
|
|
|
14
|
-
def capture(*command)
|
|
15
|
-
Open3.capture2e(*command)
|
|
14
|
+
def capture(*command, merge_stderr: true, **)
|
|
15
|
+
merge_stderr ? Open3.capture2e(*command, **) : Open3.capture2(*command, **)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def run(*command, **)
|
|
19
|
+
Process.wait2(Process.spawn(*command, **)).last
|
|
16
20
|
end
|
|
17
21
|
end
|
|
18
22
|
|
|
@@ -51,11 +55,14 @@ module Venetian
|
|
|
51
55
|
#
|
|
52
56
|
# Raised when the Playwright executable cannot be found for the current platform.
|
|
53
57
|
class ExecutableNotFoundError < StandardError
|
|
54
|
-
def initialize(reason,
|
|
58
|
+
def initialize(reason, exe_dir: nil, exe_path: nil, cli_path: nil, platform: nil) # :nodoc:
|
|
55
59
|
super(case reason
|
|
56
|
-
in :directory_missing then directory_missing_message(
|
|
57
|
-
in :executable_missing then executable_missing_message(
|
|
58
|
-
|
|
60
|
+
in :directory_missing then directory_missing_message(exe_dir)
|
|
61
|
+
in :executable_missing then executable_missing_message(exe_dir)
|
|
62
|
+
in :missing_platform then unsupported_platform_message(platform, exe_dir)
|
|
63
|
+
in :not_a_file then incomplete_message(exe_path, "#{exe_path} is not a file")
|
|
64
|
+
in :not_executable then incomplete_message(exe_path, "#{exe_path} is not executable")
|
|
65
|
+
in :cli_missing then incomplete_message(exe_path, "#{cli_path} is missing")
|
|
59
66
|
end)
|
|
60
67
|
end
|
|
61
68
|
|
|
@@ -69,6 +76,14 @@ module Venetian
|
|
|
69
76
|
"#{INSTALL_DIR_ENV_VAR} is set to #{exe_dir} but playwright was not found there."
|
|
70
77
|
end
|
|
71
78
|
|
|
79
|
+
def incomplete_message(exe_path, problem)
|
|
80
|
+
<<~MSG
|
|
81
|
+
The Playwright driver at #{File.dirname(exe_path)} is incomplete: #{problem}.
|
|
82
|
+
|
|
83
|
+
Reinstall the gem, or check #{INSTALL_DIR_ENV_VAR} points to a complete driver.
|
|
84
|
+
MSG
|
|
85
|
+
end
|
|
86
|
+
|
|
72
87
|
def unsupported_platform_message(platform, exe_dir)
|
|
73
88
|
<<~MSG
|
|
74
89
|
Cannot find the Playwright executable for #{platform} in #{exe_dir}.
|
|
@@ -82,28 +97,103 @@ module Venetian
|
|
|
82
97
|
end
|
|
83
98
|
end
|
|
84
99
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
100
|
+
# # Unsupported Path Error
|
|
101
|
+
#
|
|
102
|
+
# Raised on Windows when the path to the Playwright executable contains an environment variable reference such as
|
|
103
|
+
# +%USERNAME%+, as Ruby would then run the command with +cmd.exe+, which expands it.
|
|
104
|
+
class UnsupportedPathError < StandardError
|
|
105
|
+
def initialize(path) # :nodoc:
|
|
106
|
+
super(<<~MSG)
|
|
107
|
+
Cannot run Playwright from #{path} as Windows would expand the environment variable references in its path.
|
|
108
|
+
|
|
109
|
+
Set #{INSTALL_DIR_ENV_VAR} to a directory without them (e.g. %NAME%) containing your Playwright executable.
|
|
110
|
+
MSG
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
module Command # :nodoc:
|
|
115
|
+
TOKEN_PATTERN = /\\.?|%[A-Za-z_][A-Za-z0-9_]*.?|./m
|
|
116
|
+
VARIABLE_REFERENCE_PATTERN = /\A%[A-Za-z_][A-Za-z0-9_]*%\z/
|
|
117
|
+
|
|
118
|
+
def self.shelljoin(command)
|
|
119
|
+
return command.shelljoin unless Gem.win_platform?
|
|
120
|
+
|
|
121
|
+
command.collect { |arg| %("#{arg}") }
|
|
122
|
+
.join(" ")
|
|
123
|
+
.tap { |string| raise UnsupportedPathError, command.first if run_by_cmd?(string) }
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def self.run_by_cmd?(string)
|
|
127
|
+
string.scan(TOKEN_PATTERN).any? { |token| token.match?(VARIABLE_REFERENCE_PATTERN) }
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
module Validations # :nodoc:
|
|
132
|
+
private
|
|
133
|
+
|
|
134
|
+
def validate!
|
|
88
135
|
ensure_exe_dir_exists!
|
|
89
136
|
ensure_gem_platform_supported! unless ENV.key?(INSTALL_DIR_ENV_VAR)
|
|
90
137
|
ensure_executable_exists!
|
|
138
|
+
ensure_exe_file!
|
|
139
|
+
ensure_exe_executable!
|
|
140
|
+
ensure_cli_path_exists!
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def ensure_exe_dir_exists!
|
|
144
|
+
raise ExecutableNotFoundError.new(:directory_missing, exe_dir: exe_dir) unless exe_dir_exists?
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def ensure_gem_platform_supported!
|
|
148
|
+
raise UnsupportedPlatformError, platform if gem_platforms_unsupported?
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def ensure_executable_exists!
|
|
152
|
+
return unless exe_path.nil?
|
|
153
|
+
|
|
154
|
+
raise ExecutableNotFoundError.new ENV.key?(INSTALL_DIR_ENV_VAR) ? :executable_missing : :missing_platform,
|
|
155
|
+
exe_dir: exe_dir, platform: platform
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def ensure_exe_file!
|
|
159
|
+
return if exe_file?
|
|
160
|
+
|
|
161
|
+
raise ExecutableNotFoundError.new(:not_a_file, exe_path: exe_path)
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def ensure_exe_executable!
|
|
165
|
+
return if exe_executable?
|
|
166
|
+
|
|
167
|
+
raise ExecutableNotFoundError.new(:not_executable, exe_path: exe_path)
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def ensure_cli_path_exists!
|
|
171
|
+
return if cli_path_exists?
|
|
172
|
+
|
|
173
|
+
raise ExecutableNotFoundError.new(:cli_missing, exe_path: exe_path, cli_path: cli_path_for(exe_path))
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
extend Validations
|
|
178
|
+
|
|
179
|
+
class << self
|
|
180
|
+
# Returns the path to the Node executable. Raises an error if the executable cannot be found.
|
|
181
|
+
def path
|
|
182
|
+
validate!
|
|
91
183
|
|
|
92
184
|
exe_path
|
|
93
185
|
end
|
|
94
186
|
|
|
95
|
-
# Executes the Playwright executable with the given arguments.
|
|
187
|
+
# Executes the Playwright executable with the given arguments, replacing the current process.
|
|
96
188
|
def execute(*args, echo: true, exception: true, **)
|
|
97
189
|
[*base_command, *args].then do |command|
|
|
98
|
-
# due to mysterious Windows behavior; see equivalent in `tailwindcss-ruby`
|
|
99
|
-
next system(*args, exception:, echo:) if Gem.win_platform?
|
|
100
|
-
|
|
101
190
|
puts command.shelljoin if echo
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
191
|
+
# exec misbehaves on Windows (see equivalent in `tailwindcss-ruby`), so run Playwright and exit likewise
|
|
192
|
+
exit executor.run(*command, **).exitstatus if Gem.win_platform?
|
|
193
|
+
|
|
194
|
+
executor.exec(*command, **)
|
|
195
|
+
rescue StandardError
|
|
196
|
+
exception ? raise : false
|
|
107
197
|
end
|
|
108
198
|
end
|
|
109
199
|
|
|
@@ -111,16 +201,15 @@ module Venetian
|
|
|
111
201
|
def system(*args, echo: true, exception: true, **)
|
|
112
202
|
[*base_command, *args].then do |command|
|
|
113
203
|
puts command.shelljoin if echo
|
|
114
|
-
executor.system(*command,
|
|
115
|
-
exception:, **{ out: echo ? nil : File::NULL, err: echo ? nil : File::NULL }.compact)
|
|
204
|
+
executor.system(*command, exception:, **(echo ? {} : { out: File::NULL, err: File::NULL }), **)
|
|
116
205
|
end
|
|
117
206
|
end
|
|
118
207
|
|
|
119
208
|
# Runs the Playwright executable with the given arguments, returning its combined output and status.
|
|
120
|
-
def capture(*args, echo: true)
|
|
209
|
+
def capture(*args, echo: true, **)
|
|
121
210
|
[*base_command, *args].then do |command|
|
|
122
211
|
puts command.shelljoin if echo
|
|
123
|
-
executor.capture(*command).tap do |output, _|
|
|
212
|
+
executor.capture(*command, **).tap do |output, _|
|
|
124
213
|
puts output if echo
|
|
125
214
|
end
|
|
126
215
|
end
|
|
@@ -128,50 +217,45 @@ module Venetian
|
|
|
128
217
|
|
|
129
218
|
# Returns the base command to execute Playwright.
|
|
130
219
|
def base_command
|
|
131
|
-
[path,
|
|
220
|
+
path.then { |path| [path, cli_path_for(path)] }
|
|
132
221
|
end
|
|
133
222
|
|
|
134
223
|
# Returns the base command as a single string, as expected by +:playwright_cli_executable_path+.
|
|
135
224
|
def cli_command
|
|
136
|
-
|
|
137
|
-
base_command.collect { |arg| %("#{arg}") }
|
|
138
|
-
.join(" ")
|
|
139
|
-
else
|
|
140
|
-
base_command.shelljoin
|
|
141
|
-
end
|
|
225
|
+
Command.shelljoin(base_command)
|
|
142
226
|
end
|
|
143
227
|
|
|
144
228
|
private
|
|
145
229
|
|
|
146
|
-
def
|
|
147
|
-
|
|
230
|
+
def exe_dir_exists?
|
|
231
|
+
File.directory?(exe_dir)
|
|
148
232
|
end
|
|
149
233
|
|
|
150
|
-
def
|
|
151
|
-
|
|
234
|
+
def exe_dir
|
|
235
|
+
ENV[INSTALL_DIR_ENV_VAR] || DEFAULT_DIR
|
|
152
236
|
end
|
|
153
237
|
|
|
154
|
-
def
|
|
155
|
-
|
|
238
|
+
def exe_file?
|
|
239
|
+
File.file?(exe_path.to_s)
|
|
240
|
+
end
|
|
156
241
|
|
|
157
|
-
|
|
158
|
-
|
|
242
|
+
def exe_executable?
|
|
243
|
+
File.executable?(exe_path.to_s)
|
|
159
244
|
end
|
|
160
245
|
|
|
161
|
-
def
|
|
162
|
-
File.
|
|
246
|
+
def cli_path_exists?
|
|
247
|
+
File.file?(cli_path_for(exe_path))
|
|
163
248
|
end
|
|
164
249
|
|
|
165
|
-
def
|
|
166
|
-
|
|
250
|
+
def cli_path_for(exe_path)
|
|
251
|
+
File.join(File.dirname(exe_path), "package", "cli.js")
|
|
167
252
|
end
|
|
168
253
|
|
|
169
254
|
def exe_path
|
|
170
255
|
return custom_exe_path if ENV.key?(INSTALL_DIR_ENV_VAR)
|
|
171
256
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
.detect { |candidate| File.exist?(candidate) }
|
|
257
|
+
native_platforms.collect { |platform, info| File.join(exe_dir, platform, info.executable_name) }
|
|
258
|
+
.detect { |candidate| File.exist?(candidate) }
|
|
175
259
|
end
|
|
176
260
|
|
|
177
261
|
def custom_exe_path
|
|
@@ -183,7 +267,17 @@ module Venetian
|
|
|
183
267
|
end
|
|
184
268
|
|
|
185
269
|
def gem_platforms_unsupported?
|
|
186
|
-
|
|
270
|
+
native_platforms.none?
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
def native_platforms
|
|
274
|
+
return {} if musl? # musl isn't supported because official Linux Node binaries require glibc
|
|
275
|
+
|
|
276
|
+
Upstream::NATIVE_PLATFORMS.select { |platform, _| Gem::Platform.match_gem?(Gem::Platform.new(platform), gem_name) }
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
def musl?
|
|
280
|
+
Gem::Platform.local.then { |local| local.os == "linux" && local.version.to_s.start_with?("musl") }
|
|
187
281
|
end
|
|
188
282
|
|
|
189
283
|
def gem_name
|
data/lib/venetian/playwright.rb
CHANGED
|
@@ -1,24 +1,33 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Venetian
|
|
4
|
-
module SystemTestCaseExtension # :nodoc:
|
|
4
|
+
module SystemTestCaseExtension # :nodoc: all
|
|
5
5
|
extend ActiveSupport::Concern
|
|
6
6
|
|
|
7
|
+
module ParallelizationExtension
|
|
8
|
+
def start
|
|
9
|
+
ActionDispatch::SystemTestCase.venetian_before_fork
|
|
10
|
+
super
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
7
14
|
prepended do
|
|
8
|
-
|
|
15
|
+
# Set by +driven_by+, so classes using a driver registered under another name are still included.
|
|
16
|
+
class_attribute :venetian_browser_type, default: nil, instance_writer: false
|
|
9
17
|
|
|
10
|
-
parallelize_before_fork
|
|
11
|
-
|
|
18
|
+
if respond_to?(:parallelize_before_fork)
|
|
19
|
+
parallelize_before_fork { venetian_before_fork }
|
|
20
|
+
else
|
|
21
|
+
ActiveSupport::Testing::Parallelization.prepend(ParallelizationExtension)
|
|
12
22
|
end
|
|
13
23
|
end
|
|
14
24
|
|
|
15
|
-
class_methods do
|
|
25
|
+
class_methods do
|
|
16
26
|
def driven_by(driver, options: {}, **)
|
|
17
|
-
super
|
|
18
|
-
|
|
19
27
|
self.venetian_browser_type = if driver == :playwright
|
|
20
28
|
BrowserRunnerExtensions.browser_to_preinstall_from(options)
|
|
21
29
|
end
|
|
30
|
+
super
|
|
22
31
|
end
|
|
23
32
|
|
|
24
33
|
def install_playwright_browsers
|
|
@@ -28,6 +37,10 @@ module Venetian
|
|
|
28
37
|
end
|
|
29
38
|
end
|
|
30
39
|
|
|
40
|
+
def venetian_before_fork
|
|
41
|
+
install_playwright_browsers if venetian_preinstall_browsers_before_fork?
|
|
42
|
+
end
|
|
43
|
+
|
|
31
44
|
private
|
|
32
45
|
|
|
33
46
|
def venetian_preinstall_browsers_before_fork?
|
|
@@ -36,7 +49,7 @@ module Venetian
|
|
|
36
49
|
|
|
37
50
|
def venetian_browsers
|
|
38
51
|
Minitest::Runnable.runnables
|
|
39
|
-
.select { |klass| klass < ActionDispatch::SystemTestCase
|
|
52
|
+
.select { |klass| klass < ActionDispatch::SystemTestCase }
|
|
40
53
|
.filter_map(&:venetian_browser_type)
|
|
41
54
|
.uniq
|
|
42
55
|
end
|
data/lib/venetian/upstream.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "
|
|
3
|
+
require "venetian/version"
|
|
4
4
|
|
|
5
5
|
module Venetian
|
|
6
6
|
# # \Upstream
|
|
@@ -43,7 +43,7 @@ module Venetian
|
|
|
43
43
|
|
|
44
44
|
# Returns the URL to download the playwright-core npm package containing the driver's JS sources.
|
|
45
45
|
def self.playwright_core_url
|
|
46
|
-
"#{NPM_REGISTRY_URL}/playwright-core/-/playwright-core-#{
|
|
46
|
+
"#{NPM_REGISTRY_URL}/playwright-core/-/playwright-core-#{COMPATIBLE_PLAYWRIGHT_VERSION}.tgz"
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
# Returns the gemspec files for the base gem.
|
data/lib/venetian/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: venetian
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.1
|
|
5
5
|
platform: aarch64-linux
|
|
6
6
|
authors:
|
|
7
7
|
- Justin Malčić
|
|
@@ -27,14 +27,14 @@ dependencies:
|
|
|
27
27
|
name: playwright-ruby-client
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
29
29
|
requirements:
|
|
30
|
-
- - "
|
|
30
|
+
- - "~>"
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
32
|
version: 1.63.0
|
|
33
33
|
type: :runtime
|
|
34
34
|
prerelease: false
|
|
35
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
36
36
|
requirements:
|
|
37
|
-
- - "
|
|
37
|
+
- - "~>"
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
39
|
version: 1.63.0
|
|
40
40
|
description: Bundles the Playwright driver binary in platform-specific gem variants
|
|
@@ -171,6 +171,7 @@ files:
|
|
|
171
171
|
- lib/venetian.rb
|
|
172
172
|
- lib/venetian/browser_installer.rb
|
|
173
173
|
- lib/venetian/browser_runner_extensions.rb
|
|
174
|
+
- lib/venetian/connection_extensions.rb
|
|
174
175
|
- lib/venetian/core.rb
|
|
175
176
|
- lib/venetian/executable.rb
|
|
176
177
|
- lib/venetian/gemspec.rb
|