Skip to content

Commit

Permalink
use fixed browser revision by default
Browse files Browse the repository at this point in the history
  • Loading branch information
ysmood committed Feb 4, 2021
1 parent 6c320d6 commit dda4411
Show file tree
Hide file tree
Showing 10 changed files with 100 additions and 79 deletions.
2 changes: 1 addition & 1 deletion browser.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ func (b *Browser) Connect() error {
}

if b.monitor != "" {
launcher.NewBrowser().Open(b.ServeMonitor(b.monitor))
launcher.MustOpen(b.ServeMonitor(b.monitor))
}

return nil
Expand Down
2 changes: 1 addition & 1 deletion examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func Example_disable_headless_to_debug() {
// ServeMonitor plays screenshots of each tab. This feature is extremely
// useful when debugging with headless mode.
// You can also enable it with env rod=monitor
launcher.NewBrowser().Open(browser.ServeMonitor(""))
launcher.MustOpen(browser.ServeMonitor(""))

defer browser.MustClose()

Expand Down
2 changes: 1 addition & 1 deletion lib/examples/remote-launch/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func main() {
browser := rod.New().Client(l.Client()).MustConnect()

// You may want to start a server to watch the screenshots inside the docker
launcher.NewBrowser().Open(browser.ServeMonitor(""))
launcher.MustOpen(browser.ServeMonitor(""))

fmt.Println(
browser.MustPage("https://www.wikipedia.org/").MustEval("() => document.title"),
Expand Down
81 changes: 51 additions & 30 deletions lib/launcher/browser.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ type Browser struct {
// Log to print output
Logger io.Writer

// ExecSearchMap is the candidate paths for broweser executable.
// Sample value:
// {
// "linux": {
// "chromium-browser",
// "/usr/bin/google-chrome",
// }
// }
ExecSearchMap map[string][]string

// Lock a tcp port to prevent race downloading. Default is 2968 .
Expand All @@ -53,33 +61,39 @@ type Browser struct {
// NewBrowser with default values
func NewBrowser() *Browser {
return &Browser{
Context: context.Background(),
Revision: DefaultRevision,
Hosts: []string{HostGoogle, HostTaobao},
Dir: filepath.Join(os.TempDir(), "rod"),
Logger: os.Stdout,
ExecSearchMap: map[string][]string{
"darwin": {
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
"/Applications/Chromium.app/Contents/MacOS/Chromium",
},
"linux": {
"chromium",
"chromium-browser",
"google-chrome",
"/usr/bin/google-chrome",
},
"windows": append([]string{"chrome", "edge"}, expandWindowsExePaths(
`Google\Chrome\Application\chrome.exe`,
`Microsoft\Edge\Application\msedge.exe`,
)...),
Context: context.Background(),
Revision: DefaultRevision,
Hosts: []string{HostGoogle, HostTaobao},
Dir: filepath.Join(os.TempDir(), "rod"),
Logger: os.Stdout,
ExecSearchMap: map[string][]string{},
Lock: defaults.Lock,
}
}

// SearchGlobal will set the ExecSearchMap to often used paths for each OS.
func (lc *Browser) SearchGlobal() *Browser {
lc.ExecSearchMap = map[string][]string{
"darwin": {
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
"/Applications/Chromium.app/Contents/MacOS/Chromium",
},
"linux": {
"chromium",
"chromium-browser",
"google-chrome",
"/usr/bin/google-chrome",
},
Lock: defaults.Lock,
"windows": append([]string{"chrome", "edge"}, expandWindowsExePaths(
`Google\Chrome\Application\chrome.exe`,
`Microsoft\Edge\Application\msedge.exe`,
)...),
}
return lc
}

// ExecPath of the chromium executable
func (lc *Browser) ExecPath() string {
// Destination of the downloaded browser executable
func (lc *Browser) Destination() string {
bin := map[string]string{
"darwin": fmt.Sprintf("chromium-%d/chrome-mac/Chromium.app/Contents/MacOS/Chromium", lc.Revision),
"linux": fmt.Sprintf("chromium-%d/chrome-linux/chrome", lc.Revision),
Expand Down Expand Up @@ -160,9 +174,9 @@ func (lc *Browser) download(u string) (err error) {
return unzip(lc.Logger, zipPath, unzipPath)
}

// Get is a smart helper to get the browser executable binary.
// It will first try to find the browser from local disk, if not exists
// it will try to download the chromium to Dir.
// Get is a smart helper to get the browser executable path.
// It will first try to find the browser from local disk via ExecSearchMap or Destination,
// if not exists it will try to download the chromium to Destination.
func (lc *Browser) Get() (string, error) {
defer leakless.LockPort(lc.Lock)()

Expand All @@ -174,9 +188,16 @@ func (lc *Browser) Get() (string, error) {
return p, lc.Download()
}

// MustGet is similar with Get
func (lc *Browser) MustGet() string {
p, err := lc.Get()
utils.E(err)
return p
}

// LookPath of the browser executable.
func (lc *Browser) LookPath() (string, bool) {
execPath := lc.ExecPath()
execPath := lc.Destination()

list := append(lc.ExecSearchMap[runtime.GOOS], execPath)

Expand All @@ -190,12 +211,12 @@ func (lc *Browser) LookPath() (string, bool) {
return execPath, false
}

// Open url via a browser
func (lc *Browser) Open(url string) {
// MustOpen url via a browser
func MustOpen(url string) {
// Windows doesn't support format [::]
url = strings.Replace(url, "[::]", "[::1]", 1)

bin, _ := lc.LookPath()
bin, _ := NewBrowser().SearchGlobal().LookPath()
p := exec.Command(bin, url)
utils.E(p.Start())
utils.E(p.Process.Release())
Expand Down
32 changes: 18 additions & 14 deletions lib/launcher/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,33 @@ import (
"github.com/go-rod/rod/lib/utils"
)

func Example_use_system_browser() {
path := launcher.NewBrowser().SearchGlobal().MustGet()
u := launcher.New().Bin(path).MustLaunch()
rod.New().ControlURL(u).MustConnect()
}

func Example_disable_auto_download() {
path, found := launcher.NewBrowser().LookPath()
if found {
// Check the doc for Bin to learn why
u := launcher.New().Bin(path).MustLaunch()
rod.New().ControlURL(u).MustConnect()
}
}

func Example_custom_launch() {
// get the browser executable path
bin, err := launcher.NewBrowser().Get()
utils.E(err)
path := launcher.NewBrowser().MustGet()

// use the helper to construct args, this line is optional, you can construct the args manually
args := launcher.New().Headless(false).Env("TZ=Asia/Tokyo").FormatArgs()

parser := launcher.NewURLParser()

cmd := exec.Command(bin, args...)
cmd := exec.Command(path, args...)
cmd.Stderr = parser
err = cmd.Start()
utils.E(err)
utils.E(cmd.Start())

rod.New().ControlURL(<-parser.URL).MustConnect()
}

func Example_disable_auto_download() {
path, found := launcher.NewBrowser().LookPath()
if found {
// Check the doc for Bin to learn why
u := launcher.New().Bin(path).MustLaunch()
rod.New().ControlURL(u).MustConnect()
}
}
4 changes: 4 additions & 0 deletions lib/launcher/launcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,10 @@ func (l *Launcher) Kill() {
// Browser don't have an API to tell if the children processes are ready.
utils.Sleep(1)

if l.PID() == 0 { // avoid killing the current process
return
}

killGroup(l.PID())
p, err := os.FindProcess(l.PID())
if err == nil {
Expand Down
18 changes: 16 additions & 2 deletions lib/launcher/launcher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ func (t T) Download() {
b.Dir = filepath.Join("tmp", "browser-from-mirror", t.Srand(16))
t.E(b.Download())
t.Nil(os.Stat(b.Dir))

t.Len(b.ExecSearchMap, 0)
b.SearchGlobal()
t.Len(b.ExecSearchMap, 3)
}

func (t T) DownloadErr() {
Expand All @@ -72,6 +76,10 @@ func (t T) DownloadErr() {
b.ExecSearchMap = map[string][]string{runtime.GOOS: {}}
_, err := b.Get()
t.Err(err)

t.Panic(func() {
b.MustGet()
})
}

func (t T) Launch() {
Expand Down Expand Up @@ -106,6 +114,8 @@ func (t T) LaunchUserMode() {
l := launcher.NewUserMode()
defer l.Kill()

l.Kill() // empty kill should do nothing

_, has := l.Get("not-exists")
t.False(has)

Expand All @@ -127,14 +137,13 @@ func (t T) LaunchUserMode() {
UserDataDir("test").UserDataDir(dir).
WorkingDir("").
Env("TZ=Asia/Tokyo").
XVFB().
MustLaunch()

t.Eq(url, launcher.NewUserMode().RemoteDebuggingPort(port).MustLaunch())
}

func (t T) TestOpen() {
launcher.NewBrowser().Open("about:blank")
launcher.MustOpen("about:blank")
}

func (t T) UserModeErr() {
Expand All @@ -160,6 +169,11 @@ func (t T) LaunchErr() {
t.Panic(func() {
launcher.New().Client()
})
{
l := launcher.New().XVFB()
_, _ = l.Launch()
l.Kill()
}
}

func newBrowser() (*launcher.Browser, func()) {
Expand Down
7 changes: 5 additions & 2 deletions lib/launcher/private_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package launcher
import (
"context"
"io/ioutil"
"log"
"net/url"
"os"
"testing"
Expand Down Expand Up @@ -85,7 +86,9 @@ func (t T) RemoteLaunch() {
defer cancel()

s := got.New(t).Serve()
s.Mux.Handle("/", NewRemoteLauncher())
rl := NewRemoteLauncher()
rl.Logger = log.New(os.Stdout, "&&&&&", 0)
s.Mux.Handle("/", rl)

l := MustNewRemote(s.URL()).KeepUserDataDir().Delete(flagKeepUserDataDir)
client := l.Client()
Expand All @@ -110,7 +113,7 @@ func (t T) LaunchErrs() {
_, err := l.Launch()
t.Err(err)

l = New()
l = New().Bin("")
l.browser.Dir = t.Srand(16)
l.browser.ExecSearchMap = nil
l.browser.Hosts = []string{}
Expand Down
16 changes: 2 additions & 14 deletions lib/proto/generate/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"fmt"
"net/http"
"net/url"
"os"
"regexp"
"strings"

Expand All @@ -14,19 +13,8 @@ import (
)

func getSchema() gson.JSON {
b := launcher.NewBrowser()
b.ExecSearchMap = make(map[string][]string)
bin, err := b.Get()
utils.E(err)

l := launcher.New().Bin(bin)

defer func() {
p, err := os.FindProcess(l.PID())
if err == nil {
_ = p.Kill()
}
}()
l := launcher.New().Bin(launcher.NewBrowser().MustGet())
defer l.Kill()

u := l.MustLaunch()
parsed, err := url.Parse(u)
Expand Down
15 changes: 1 addition & 14 deletions setup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import (
)

var TimeoutEach = flag.Duration("timeout-each", time.Minute, "timeout for each test")
var BrowserBin = flag.String("browser-bin", "", "browser binary to use")

var LogDir = slash(fmt.Sprintf("tmp/cdp-log/%s", time.Now().Format("2006-01-02_15-04-05")))

Expand Down Expand Up @@ -57,9 +56,6 @@ type T struct {
type TesterPool chan *T

func newTesterPool(t *testing.T) TesterPool {
// preload the browser so that each test doesn't timeout because of browser downloading
got.New(t).E(launcher.NewBrowser().Get())

parallel := got.Parallel()
if parallel == 0 {
parallel = runtime.GOMAXPROCS(0)
Expand Down Expand Up @@ -87,16 +83,7 @@ func newTesterPool(t *testing.T) TesterPool {

// new tester
func (cp TesterPool) new() *T {
bin := *BrowserBin
if bin == "" {
b := launcher.NewBrowser()
b.ExecSearchMap = make(map[string][]string)
var err error
bin, err = b.Get()
utils.E(err)
}

u := launcher.New().Bin(bin).MustLaunch()
u := launcher.New().MustLaunch()

mc := newMockClient(u)

Expand Down

0 comments on commit dda4411

Please sign in to comment.