Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC4
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
Expand Down
27 changes: 17 additions & 10 deletions lib/launcher/browser.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
)

/*
Google's Chromium-for-Testing (CfT) project provides builds for macOS (Intel and ARM), Windows (x86 and x64), and Linux (x64):
Google's Chromium-for-Testing (CfT) project provides builds for macOS (Intel and ARM), Windows (x86, x64, and ARM64), and Linux (x64):
- https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions-with-downloads.json

Playwright offers Chromium builds for Linux on ARM:
Expand Down Expand Up @@ -150,8 +150,9 @@ func ResolveChromiumForTestingPlatform(os string, arch string) string {
}
case "windows":
switch arch {
case "amd64",
"arm64": // Windows ARM64 uses the x86_64 binary via emulation
case "arm64": // Windows 11 ARM64 has native Chrome-for-Testing builds
return "win-arm64"
case "amd64":
return "win64"
case "386":
return "win32"
Expand Down Expand Up @@ -226,20 +227,26 @@ func ResolveLatestDownloadURLWithCache(os string, arch string) (string, string,
// resolveLatestDownloadURL fetches the latest Chromium download URL for the specified OS and architecture.
// It returns an error if the platform is unsupported or if there are issues fetching or parsing the metadata.
func resolveLatestDownloadURL(os string, arch string) (string, string, error) {
// Microsoft's Playwright does not support Windows ARM64 and falls back to emulation using Win64
if os == "windows" && arch == "arm64" {
arch = "amd64"
}
// First try Google Chromium-for-Testing for common platforms
if cftPlatform := ResolveChromiumForTestingPlatform(os, arch); cftPlatform != "" {
var latestJSON GoogleCFTLatestDownloadsMeta
if err := downloadAndParseJSON(ChromiumForTestingLatestDownloadsURL, &latestJSON); err != nil {
return "", "", err
}
stable := latestJSON.Channels.Stable
for _, download := range stable.Downloads.Chrome {
if download.Platform == cftPlatform {
return download.URL, stable.Revision, nil

// Prefer the native platform build, but on Windows ARM64 fall back to
// the x86_64 (win64) build via emulation when Chromium-for-Testing does
// not publish a native win-arm64 build for the stable channel.
candidatePlatforms := []string{cftPlatform}
if os == "windows" && arch == "arm64" {
candidatePlatforms = append(candidatePlatforms, "win64")
}
for _, platform := range candidatePlatforms {
for _, download := range stable.Downloads.Chrome {
if download.Platform == platform {
return download.URL, stable.Revision, nil
}
}
}
}
Expand Down
34 changes: 34 additions & 0 deletions lib/launcher/launcher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,16 @@ func Test_ResolveDownloadURL(t *testing.T) {
},
wantMatch: regexp.MustCompile(`https://storage.googleapis.com/chrome-for-testing-public/[\d.]+/win64/chrome-win64.zip`),
},
{
name: "windows-arm64",
platform: srcPlatform{
os: "windows",
arch: "arm64",
},
// Prefer the native win-arm64 build, but accept the win64 build
// when Chromium-for-Testing has not published a native build.
wantMatch: regexp.MustCompile(`https://storage.googleapis.com/chrome-for-testing-public/[\d.]+/win(-arm64|64)/chrome-win(-arm64|64).zip`),
},
{
name: "windows-x86",
platform: srcPlatform{
Expand Down Expand Up @@ -291,6 +301,30 @@ func Test_ResolveDownloadURL(t *testing.T) {
}
}

func Test_ResolveChromiumForTestingPlatform(t *testing.T) {
tests := []struct {
name string
os string
arch string
want string
}{
{name: "windows-arm64", os: "windows", arch: "arm64", want: "win-arm64"},
{name: "windows-amd64", os: "windows", arch: "amd64", want: "win64"},
{name: "windows-386", os: "windows", arch: "386", want: "win32"},
{name: "darwin-arm64", os: "darwin", arch: "arm64", want: "mac-arm64"},
{name: "darwin-amd64", os: "darwin", arch: "amd64", want: "mac-x64"},
{name: "linux-amd64", os: "linux", arch: "amd64", want: "linux64"},
{name: "linux-arm64", os: "linux", arch: "arm64", want: ""},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := launcher.ResolveChromiumForTestingPlatform(tt.os, tt.arch); got != tt.want {
t.Errorf("ResolveChromiumForTestingPlatform(%q, %q) = %q, want %q", tt.os, tt.arch, got, tt.want)
}
})
}
}

func Test_ResolveDownloader(t *testing.T) {
b, err := launcher.NewBrowser()
if err != nil {
Expand Down