Skip to content

Support JavaScript Playwright CLI paths - #67

Open
dannote wants to merge 2 commits into
ftes:mainfrom
dannote:javascript-cli-launcher
Open

Support JavaScript Playwright CLI paths#67
dannote wants to merge 2 commits into
ftes:mainfrom
dannote:javascript-cli-launcher

Conversation

@dannote

@dannote dannote commented Jul 20, 2026

Copy link
Copy Markdown

Summary

  • launch JavaScript Playwright CLI paths through the Node executable
  • use the same command resolution for version checks and run-driver
  • cover CLI paths containing spaces with a self-contained Node fixture

This allows configurations such as assets/node_modules/playwright/cli.js to work on Windows, where JavaScript files cannot be passed directly to Port.open/2 as executables.

Testing

  • mix format --check-formatted
  • mix test test/playwright_ex/processes/port_transport_test.exs — 1 passed
  • Hologram Windows browser suite — 6 passed using playwright/cli.js

mix credo --strict reports two pre-existing line-length findings in connection.ex and supervisor.ex; this change adds no Credo findings.

@ftes ftes left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Danila, thanks for looking into this!
A few thoughts:

I'm not sure we should limit ourselves to node from PATH.
On Unix, we could keep supporting the shebang.

Or we could look at what the official playwright clients do.

Reference: Official Playwright clients

Explicit interpreter everywhere. Do not rely on shebang, but bundle matching Node executable and allow overriding through PLAYWRIGHT_NODEJS_PATH. No dependency on arbitrary node from PATH.

  # https://github.com/microsoft/playwright-python/blob/main/playwright/_impl/_driver.py#L28

if sys.platform == "win32":
  return (
    os.getenv("PLAYWRIGHT_NODEJS_PATH", str(driver_path / "node.exe")),
    cli_path,
  )
return (os.getenv("PLAYWRIGHT_NODEJS_PATH", str(driver_path / "node")), cli_path)

Comment on lines +129 to +136
defp executable_command(executable, args) do
if String.downcase(Path.extname(executable)) == ".js" do
node = System.find_executable("node") || raise "Node.js executable not found on PATH"
{node, [executable | args]}
else
{executable, args}
end
end

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Restrict node resolution to Windows only?
Honor shebang on Unix.

Suggested change
defp executable_command(executable, args) do
if String.downcase(Path.extname(executable)) == ".js" do
node = System.find_executable("node") || raise "Node.js executable not found on PATH"
{node, [executable | args]}
else
{executable, args}
end
end
defp executable_command(executable, args) do
windows? = match?({:win32, _}, :os.type())
javascript? = String.downcase(Path.extname(executable)) == ".js"
if windows? and javascript? do
node = System.find_executable("node") || raise "Node.js executable not found on PATH"
{node, [executable | args]}
else
{executable, args}
end
end


alias PlaywrightEx.PortTransport

test "launches JavaScript CLI files through Node" do

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this unit test is worth the complexity it adds.

If anything, we should expand the test matrix to also run on Windows.
Out of scope for this PR.

@dannote

dannote commented Jul 22, 2026

Copy link
Copy Markdown
Author

Thanks, good point. I’ve updated the PR to honor PLAYWRIGHT_NODEJS_PATH, keep shebang execution on Unix, and use node from PATH only as the Windows fallback.

PlaywrightEx doesn’t currently bundle Node, so the explicit override matches the official clients’ convention. Focused tests pass on Linux and Windows.

defp check_version(executable) do
{"Version " <> version, 0} = executable |> Path.expand() |> System.cmd(~w(--version))
defp check_version(executable, env) do
{command, args} = executable_command(Path.expand(executable), ["--version"], env)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why Path.expand executable here, but not in init?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants