Skip to content

Commit

Permalink
Merge pull request #298 from rusq/i293
Browse files Browse the repository at this point in the history
#293: browser compatibility
  • Loading branch information
rusq authored Jul 7, 2024
2 parents 485eaa8 + e6afe27 commit dff8889
Show file tree
Hide file tree
Showing 10 changed files with 209 additions and 44 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/codespell.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ name: Codespell

on:
push:
branches: [master]
branches: [v2]
pull_request:
branches: [master]
branches: [v2]

permissions:
contents: read
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: Go

on:
push:
branches: [ master ]
branches: [ v2 ]
pull_request:
branches: [ master ]
branches: [ v2 ]

jobs:

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/shellcheck.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ name: Shellcheck

on:
push:
branches: [master]
branches: [v2]
pull_request:
branches: [master]
branches: [v2]

permissions:
contents: read
Expand Down
16 changes: 7 additions & 9 deletions auth/browser/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"time"

"github.com/playwright-community/playwright-go"
"github.com/rusq/slackdump/v2/auth/browser/pwcompat"
"github.com/rusq/slackdump/v2/logger"
)

Expand All @@ -34,9 +35,6 @@ var Logger logger.Interface = logger.Default

var (
installFn = playwright.Install
// newDriverFn is the function that creates a new driver. It is set to
// playwright.NewDriver by default, but can be overridden for testing.
newDriverFn = playwright.NewDriver
)

// New create new browser based client.
Expand Down Expand Up @@ -227,12 +225,12 @@ func l() logger.Interface {

// pwRepair attempts to repair the playwright installation.
func pwRepair(runopts *playwright.RunOptions) error {
drv, err := newDriverFn(runopts)
driverDirectory, err := pwcompat.DriverDir(runopts)
if err != nil {
return err
}
// check node permissions
if err := pwIsKnownProblem(drv.DriverDirectory); err != nil {
if err := pwIsKnownProblem(driverDirectory); err != nil {
return err
}
return reinstall(runopts)
Expand All @@ -249,17 +247,17 @@ func Reinstall(browser Browser, verbose bool) error {

func reinstall(runopts *playwright.RunOptions) error {
l().Debugf("reinstalling browser: %s", runopts.Browsers[0])
drv, err := newDriverFn(runopts)
drvdir, err := pwcompat.DriverDir(runopts)
if err != nil {
return err
}
l().Debugf("removing %s", drv.DriverDirectory)
if err := os.RemoveAll(drv.DriverDirectory); err != nil {
l().Debugf("removing %s", drvdir)
if err := os.RemoveAll(drvdir); err != nil {
return err
}

// attempt to reinstall
l().Debugf("reinstalling %s", drv.DriverDirectory)
l().Debugf("reinstalling %s", drvdir)
if err := installFn(runopts); err != nil {
// we did everything we could, but it still failed.
return err
Expand Down
23 changes: 10 additions & 13 deletions auth/browser/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"time"

"github.com/playwright-community/playwright-go"
"github.com/rusq/slackdump/v2/auth/browser/pwcompat"
)

func Test_float2time(t *testing.T) {
Expand Down Expand Up @@ -40,7 +41,6 @@ func Test_pwRepair(t *testing.T) {
}
t.Run("known executable permissions problem causes reinstall", func(t *testing.T) {
baseDir := t.TempDir()
fakePwDir := filepath.Join(baseDir, "playwright-99.20.0")

// installCalledi should be set to true if the install function is
// called.
Expand All @@ -52,20 +52,17 @@ func Test_pwRepair(t *testing.T) {
installCalled = true
return nil
}
oldNewDriverFn := newDriverFn
defer func() { newDriverFn = oldNewDriverFn }()
newDriverFn = func(*playwright.RunOptions) (*playwright.PlaywrightDriver, error) {
return &playwright.PlaywrightDriver{
DriverDirectory: fakePwDir,
}, nil
}

// create a fake node file with the wrong permissions.
makeFakeNode(t, fakePwDir, 0o644)
// run the repair function.
runopts := &playwright.RunOptions{
Browsers: []string{"chromium"},
Browsers: []string{"chromium"},
DriverDirectory: baseDir,
}
dir, err := pwcompat.DriverDir(runopts)
if err != nil {
t.Fatal(err)
}
// create a fake node file with the wrong permissions.
makeFakeNode(t, dir, 0o644)
if err := pwRepair(runopts); err != nil {
t.Fatal(err)
}
Expand All @@ -74,7 +71,7 @@ func Test_pwRepair(t *testing.T) {
t.Fatal("install was not called")
}
// check that the directory was removed
if _, err := os.Stat(fakePwDir); !os.IsNotExist(err) {
if _, err := os.Stat(dir); !os.IsNotExist(err) {
t.Fatal("directory was not removed")
}
})
Expand Down
72 changes: 72 additions & 0 deletions auth/browser/pwcompat/pwcompat.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// 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.
package pwcompat

import (
"errors"
"fmt"
"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

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
}
return "", errors.New("could not determine cache directory")
}

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
}

// 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)
if err != nil {
return "", err
}
baseDriverDirectory, err := getDefaultCacheDirectory()
if err != nil {
return "", fmt.Errorf("it's just not your day: %w", err)
}
driverDirectory := filepath.Join(nvl(runopts.DriverDirectory, baseDriverDirectory), "ms-playwright-go", drv.Version)
return driverDirectory, nil
}

func nvl(first string, rest ...string) string {
if first != "" {
return first
}
for _, s := range rest {
if s != "" {
return s
}
}
return ""
}
49 changes: 49 additions & 0 deletions auth/browser/pwcompat/pwcompat_darwin_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// 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)
}
})
}
}
51 changes: 51 additions & 0 deletions auth/browser/pwcompat/pwcompat_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// 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.
package pwcompat

import (
"testing"

"github.com/playwright-community/playwright-go"
)

func TestNewDriver(t *testing.T) {
t.Parallel()
type args struct {
runopts *playwright.RunOptions
}
tests := []struct {
name string
args args
wantErr bool
}{
{
"default dir",
args{&playwright.RunOptions{
DriverDirectory: "",
SkipInstallBrowsers: true,
Browsers: []string{"chrome"}},
},
false,
},
{
"custom dir",
args{&playwright.RunOptions{
DriverDirectory: t.TempDir(),
SkipInstallBrowsers: true,
Browsers: []string{"chrome"}},
},
false,
},
}
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
}
})
}
}
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ require (
github.com/denisbrodbeck/machineid v1.0.1
github.com/fatih/color v1.16.0
github.com/joho/godotenv v1.5.1
github.com/playwright-community/playwright-go v0.4201.0
github.com/playwright-community/playwright-go v0.4401.1
github.com/rusq/chttp v1.0.2
github.com/rusq/dlog v1.4.0
github.com/rusq/osenv/v2 v2.0.1
Expand All @@ -37,7 +37,7 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/deckarep/golang-set/v2 v2.6.0 // indirect
github.com/go-jose/go-jose/v3 v3.0.3 // indirect
github.com/go-rod/rod v0.114.8 // indirect
github.com/go-rod/rod v0.116.1 // indirect
github.com/go-stack/stack v1.8.1 // indirect
github.com/gorilla/websocket v1.5.1 // indirect
github.com/kr/text v0.2.0 // indirect
Expand All @@ -55,12 +55,12 @@ require (
github.com/rivo/uniseg v0.4.7 // indirect
github.com/ysmood/fetchup v0.2.4 // indirect
github.com/ysmood/goob v0.4.0 // indirect
github.com/ysmood/got v0.39.4 // indirect
github.com/ysmood/got v0.40.0 // indirect
github.com/ysmood/gson v0.7.3 // indirect
github.com/ysmood/leakless v0.8.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/crypto v0.25.0 // indirect
golang.org/x/exp v0.0.0-20240318143956-a85f2c67cd81 // indirect
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect
golang.org/x/net v0.27.0 // indirect
golang.org/x/sys v0.22.0 // indirect
golang.org/x/text v0.16.0 // indirect
Expand Down
Loading

0 comments on commit dff8889

Please sign in to comment.