diff --git a/go.sum b/go.sum index 398c77f3..f959d265 100644 --- a/go.sum +++ b/go.sum @@ -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= diff --git a/lib/launcher/browser.go b/lib/launcher/browser.go index b3417e42..6d604660 100644 --- a/lib/launcher/browser.go +++ b/lib/launcher/browser.go @@ -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: @@ -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" @@ -226,10 +227,6 @@ 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 @@ -237,9 +234,19 @@ func resolveLatestDownloadURL(os string, arch string) (string, string, error) { 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 + } } } } diff --git a/lib/launcher/launcher_test.go b/lib/launcher/launcher_test.go index 2d802354..2d76702d 100644 --- a/lib/launcher/launcher_test.go +++ b/lib/launcher/launcher_test.go @@ -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{ @@ -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 {