From 3f5c023b723f769cc03a2879cf74ea04f7937c6e Mon Sep 17 00:00:00 2001 From: Rustam Gilyazov <16064414+rusq@users.noreply.github.com> Date: Thu, 11 Jul 2024 20:38:34 +1000 Subject: [PATCH] update browser package from master --- auth/browser/client.go | 23 +++--- auth/browser/client_test.go | 12 ++-- auth/browser/pwcompat/pwcompat.go | 71 +++++++++---------- auth/browser/pwcompat/pwcompat_darwin.go | 8 +++ auth/browser/pwcompat/pwcompat_darwin_test.go | 49 ------------- auth/browser/pwcompat/pwcompat_linux.go | 8 +++ auth/browser/pwcompat/pwcompat_test.go | 55 +++++++------- auth/browser/pwcompat/pwcompat_windows.go | 8 +++ 8 files changed, 103 insertions(+), 131 deletions(-) create mode 100644 auth/browser/pwcompat/pwcompat_darwin.go delete mode 100644 auth/browser/pwcompat/pwcompat_darwin_test.go create mode 100644 auth/browser/pwcompat/pwcompat_linux.go create mode 100644 auth/browser/pwcompat/pwcompat_windows.go diff --git a/auth/browser/client.go b/auth/browser/client.go index d6e55be9..b6753abd 100644 --- a/auth/browser/client.go +++ b/auth/browser/client.go @@ -6,7 +6,6 @@ import ( "fmt" "net/http" "os" - "path/filepath" "runtime" "runtime/trace" "strings" @@ -225,12 +224,12 @@ func l() logger.Interface { // pwRepair attempts to repair the playwright installation. func pwRepair(runopts *playwright.RunOptions) error { - driverDirectory, err := pwcompat.DriverDir(runopts) + ad, err := pwcompat.NewAdapter(runopts) + // check node permissions if err != nil { - return err + return fmt.Errorf("repair: %w", err) } - // check node permissions - if err := pwIsKnownProblem(driverDirectory); err != nil { + if err := pwWrongNodePerms(ad.DriverBinaryLocation); err != nil { return err } return reinstall(runopts) @@ -247,17 +246,17 @@ func Reinstall(browser Browser, verbose bool) error { func reinstall(runopts *playwright.RunOptions) error { l().Debugf("reinstalling browser: %s", runopts.Browsers[0]) - drvdir, err := pwcompat.DriverDir(runopts) + ad, err := pwcompat.NewAdapter(runopts) if err != nil { return err } - l().Debugf("removing %s", drvdir) - if err := os.RemoveAll(drvdir); err != nil { + l().Debugf("removing %s", ad.DriverDirectory) + if err := os.RemoveAll(ad.DriverDirectory); err != nil { return err } // attempt to reinstall - l().Debugf("reinstalling %s", drvdir) + l().Debugf("reinstalling %s", ad.DriverDirectory) if err := installFn(runopts); err != nil { // we did everything we could, but it still failed. return err @@ -267,17 +266,17 @@ func reinstall(runopts *playwright.RunOptions) error { var errUnknownProblem = errors.New("unknown problem") -// pwIsKnownProblem checks if the playwright installation is in a known +// pwWrongNodePerms checks if the playwright installation is in a known // problematic state, and if yes, return nil. If the problem is unknown, // returns an errUnknownProblem. -func pwIsKnownProblem(path string) error { +func pwWrongNodePerms(path string) error { if runtime.GOOS == "windows" { // this should not ever happen on windows, as this problem relates to // executable flag not being set, which is not a thing in a // DOS/Windows world. return errors.New("impossible has just happened, call the exorcist") } - fi, err := os.Stat(filepath.Join(path, "node")) + fi, err := os.Stat(path) if err != nil { return err } diff --git a/auth/browser/client_test.go b/auth/browser/client_test.go index 0f3eb4ce..a2ad277b 100644 --- a/auth/browser/client_test.go +++ b/auth/browser/client_test.go @@ -57,7 +57,11 @@ func Test_pwRepair(t *testing.T) { Browsers: []string{"chromium"}, DriverDirectory: baseDir, } - dir, err := pwcompat.DriverDir(runopts) + ad, err := pwcompat.NewAdapter(runopts) + if err != nil { + t.Fatal(err) + } + dir := ad.DriverDirectory if err != nil { t.Fatal(err) } @@ -81,7 +85,7 @@ func makeFakeNode(t *testing.T, dir string, mode fs.FileMode) { if err := os.MkdirAll(dir, 0o755); err != nil { t.Fatal(err) } - if err := os.WriteFile(filepath.Join(dir, "node"), []byte("hello"), mode); err != nil { + if err := os.WriteFile(filepath.Join(dir, pwcompat.NodeExe), []byte("hello"), mode); err != nil { t.Fatal(err) } } @@ -90,14 +94,14 @@ func Test_pwIsKnownProblem(t *testing.T) { t.Run("known executable permissions problem", func(t *testing.T) { baseDir := t.TempDir() makeFakeNode(t, baseDir, 0o644) - if err := pwIsKnownProblem(baseDir); err != nil { + if err := pwWrongNodePerms(filepath.Join(baseDir, pwcompat.NodeExe)); err != nil { t.Fatal(err) } }) t.Run("other problem", func(t *testing.T) { baseDir := t.TempDir() makeFakeNode(t, baseDir, 0o755) - err := pwIsKnownProblem(baseDir) + err := pwWrongNodePerms(filepath.Join(baseDir, pwcompat.NodeExe)) if err == nil { t.Fatal("unexpected success") } diff --git a/auth/browser/pwcompat/pwcompat.go b/auth/browser/pwcompat/pwcompat.go index 30f11412..3e15d164 100644 --- a/auth/browser/pwcompat/pwcompat.go +++ b/auth/browser/pwcompat/pwcompat.go @@ -4,59 +4,58 @@ package pwcompat import ( - "errors" - "fmt" + "log" "os" "path/filepath" - "runtime" "github.com/playwright-community/playwright-go" ) // Workaround for unexported driver dir in playwright. -// newDriverFn is the function that creates a new driver. It is set to -// playwright.NewDriver by default, but can be overridden for testing. -var newDriverFn = playwright.NewDriver +var ( + // environment related variables + homedir string = must(os.UserHomeDir()) + cacheDir string // platform dependent + NodeExe string = "node" +) -func getDefaultCacheDirectory() (string, error) { - // pinched from playwright - userHomeDir, err := os.UserHomeDir() - if err != nil { - return "", fmt.Errorf("could not get user home directory: %w", err) - } - switch runtime.GOOS { - case "windows": - return filepath.Join(userHomeDir, "AppData", "Local"), nil - case "darwin": - return filepath.Join(userHomeDir, "Library", "Caches"), nil - case "linux": - return filepath.Join(userHomeDir, ".cache"), nil +func must[T any](v T, e error) T { + if e != nil { + log.Panicf("error getting user home directory: %s", e) } - return "", errors.New("could not determine cache directory") + return v } -func NewDriver(runopts *playwright.RunOptions) (*playwright.PlaywrightDriver, error) { - drv, err := newDriverFn(runopts) - if err != nil { - return nil, fmt.Errorf("error initialising driver: %w", err) - } - return drv, nil +type Adapter struct { + DriverDirectory string + DriverBinaryLocation string + + drv *playwright.PlaywrightDriver + opts *playwright.RunOptions } -// DriverDir returns the driver directory, broken in this commit: -// https://github.com/playwright-community/playwright-go/pull/449/commits/372e209c776222f4681cf1b24a1379e3648dd982 -func DriverDir(runopts *playwright.RunOptions) (string, error) { - drv, err := NewDriver(runopts) +func NewAdapter(runopts *playwright.RunOptions) (*Adapter, error) { + drv, err := playwright.NewDriver(runopts) if err != nil { - return "", err + return nil, err } - baseDriverDirectory, err := getDefaultCacheDirectory() - if err != nil { - return "", fmt.Errorf("it's just not your day: %w", err) + if cacheDir == "" { // i.e. freebsd etc. + cacheDir, _ = os.UserCacheDir() } - driverDirectory := filepath.Join(nvl(runopts.DriverDirectory, baseDriverDirectory), "ms-playwright-go", drv.Version) - return driverDirectory, nil + drvdir := filepath.Join(nvl(runopts.DriverDirectory, cacheDir), "ms-playwright-go", drv.Version) + drvbin := filepath.Join(drvdir, NodeExe) + + return &Adapter{ + drv: drv, + opts: runopts, + DriverDirectory: drvdir, + DriverBinaryLocation: drvbin, + }, nil +} + +func (a *Adapter) Driver() *playwright.PlaywrightDriver { + return a.drv } func nvl(first string, rest ...string) string { diff --git a/auth/browser/pwcompat/pwcompat_darwin.go b/auth/browser/pwcompat/pwcompat_darwin.go new file mode 100644 index 00000000..810d31aa --- /dev/null +++ b/auth/browser/pwcompat/pwcompat_darwin.go @@ -0,0 +1,8 @@ +package pwcompat + +import "path/filepath" + +func init() { + cacheDir = filepath.Join(homedir, "Library", "Caches") + NodeExe = "node" +} diff --git a/auth/browser/pwcompat/pwcompat_darwin_test.go b/auth/browser/pwcompat/pwcompat_darwin_test.go deleted file mode 100644 index be8adb09..00000000 --- a/auth/browser/pwcompat/pwcompat_darwin_test.go +++ /dev/null @@ -1,49 +0,0 @@ -// Package pwcompat provides a compatibility layer, so when the playwright-go -// team decides to break compatibility again, there's a place to write a -// workaround. -// -//go:build: darwin -package pwcompat - -import ( - "os" - "path/filepath" - "testing" -) - -func bailonerr(t *testing.T, err error) { - t.Helper() - if err != nil { - t.Fatal(err) - } -} - -func Test_getDefaultCacheDirectory(t *testing.T) { - t.Parallel() - home, err := os.UserHomeDir() - bailonerr(t, err) - tests := []struct { - name string - want string - wantErr bool - }{ - { - "darwin", - filepath.Join(home, "Library", "Caches"), - false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - t.Parallel() - got, err := getDefaultCacheDirectory() - if (err != nil) != tt.wantErr { - t.Errorf("getDefaultCacheDirectory() error = %v, wantErr %v", err, tt.wantErr) - return - } - if got != tt.want { - t.Errorf("getDefaultCacheDirectory() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/auth/browser/pwcompat/pwcompat_linux.go b/auth/browser/pwcompat/pwcompat_linux.go new file mode 100644 index 00000000..ca223dcc --- /dev/null +++ b/auth/browser/pwcompat/pwcompat_linux.go @@ -0,0 +1,8 @@ +package pwcompat + +import "path/filepath" + +func init() { + cacheDir = filepath.Join(homedir, ".cache") + NodeExe = "node" +} diff --git a/auth/browser/pwcompat/pwcompat_test.go b/auth/browser/pwcompat/pwcompat_test.go index 6d0392d1..37130e2e 100644 --- a/auth/browser/pwcompat/pwcompat_test.go +++ b/auth/browser/pwcompat/pwcompat_test.go @@ -3,48 +3,43 @@ // workaround. package pwcompat -import ( - "testing" +import "testing" - "github.com/playwright-community/playwright-go" -) - -func TestNewDriver(t *testing.T) { - t.Parallel() +func Test_nvl(t *testing.T) { type args struct { - runopts *playwright.RunOptions + first string + rest []string } tests := []struct { - name string - args args - wantErr bool + name string + args args + want string }{ { - "default dir", - args{&playwright.RunOptions{ - DriverDirectory: "", - SkipInstallBrowsers: true, - Browsers: []string{"chrome"}}, - }, - false, + "first", + args{"first", []string{"second", "third"}}, + "first", + }, + { + "second", + args{"", []string{"second", "third"}}, + "second", + }, + { + "third", + args{"", []string{"", "third"}}, + "third", }, { - "custom dir", - args{&playwright.RunOptions{ - DriverDirectory: t.TempDir(), - SkipInstallBrowsers: true, - Browsers: []string{"chrome"}}, - }, - false, + "empty", + args{"", []string{""}}, + "", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - t.Parallel() - _, err := NewDriver(tt.args.runopts) - if (err != nil) != tt.wantErr { - t.Errorf("NewDriver() error = %v, wantErr %v", err, tt.wantErr) - return + if got := nvl(tt.args.first, tt.args.rest...); got != tt.want { + t.Errorf("nvl() = %v, want %v", got, tt.want) } }) } diff --git a/auth/browser/pwcompat/pwcompat_windows.go b/auth/browser/pwcompat/pwcompat_windows.go new file mode 100644 index 00000000..5a6e0946 --- /dev/null +++ b/auth/browser/pwcompat/pwcompat_windows.go @@ -0,0 +1,8 @@ +package pwcompat + +import "path/filepath" + +func init() { + cacheDir = filepath.Join(homedir, "AppData", "Local") + NodeExe = "node.exe" +}