From 7d37ad0b95514bba57ab6820f3f2c9b07bb9213d Mon Sep 17 00:00:00 2001 From: Can Stand <70889873+canstand@users.noreply.github.com> Date: Wed, 13 Mar 2024 19:36:35 +0800 Subject: [PATCH] feat: RunOptions can specifying output/error streams (#426) --- binding_call.go | 8 ++--- browser_context.go | 3 +- channel.go | 3 +- har_router.go | 7 ++-- page.go | 3 +- run.go | 79 ++++++++++++++++++++++++++-------------------- transport.go | 9 +++--- websocket.go | 5 ++- 8 files changed, 59 insertions(+), 58 deletions(-) diff --git a/binding_call.go b/binding_call.go index 80a13153..394eb2d1 100644 --- a/binding_call.go +++ b/binding_call.go @@ -1,9 +1,5 @@ package playwright -import ( - "log" -) - type BindingCall interface { Call(f BindingCallFunction) } @@ -31,7 +27,7 @@ func (b *bindingCallImpl) Call(f BindingCallFunction) { if _, err := b.channel.Send("reject", map[string]interface{}{ "error": serializeError(r.(error)), }); err != nil { - log.Printf("could not reject BindingCall: %v", err) + logger.Printf("could not reject BindingCall: %v\n", err) } } }() @@ -57,7 +53,7 @@ func (b *bindingCallImpl) Call(f BindingCallFunction) { "result": serializeArgument(result), }) if err != nil { - log.Printf("could not resolve BindingCall: %v", err) + logger.Printf("could not resolve BindingCall: %v\n", err) } } diff --git a/browser_context.go b/browser_context.go index cbdfa7fe..2692237a 100644 --- a/browser_context.go +++ b/browser_context.go @@ -4,7 +4,6 @@ import ( "encoding/json" "errors" "fmt" - "log" "os" "strings" "sync" @@ -528,7 +527,7 @@ func (b *browserContextImpl) onRoute(route *routeImpl) { return nil, err }, true) if err != nil { - log.Printf("could not update interception patterns: %v", err) + logger.Printf("could not update interception patterns: %v\n", err) } } } diff --git a/channel.go b/channel.go index 6a0115f3..620b0135 100644 --- a/channel.go +++ b/channel.go @@ -1,7 +1,6 @@ package playwright import ( - "log" "reflect" ) @@ -59,7 +58,7 @@ func (c *channel) SendNoReply(method string, options ...interface{}) { return c.connection.sendMessageToServer(c.owner, method, params, true) }, false) if err != nil { - log.Printf("SendNoReply failed: %v", err) + logger.Printf("SendNoReply failed: %v\n", err) } } diff --git a/har_router.go b/har_router.go index 1bdb4c3d..2a92d6d4 100644 --- a/har_router.go +++ b/har_router.go @@ -2,7 +2,6 @@ package playwright import ( "errors" - "log" ) type harRouter struct { @@ -20,7 +19,7 @@ func (r *harRouter) addContextRoute(context BrowserContext) error { err := context.Route(r.urlOrPredicate, func(route Route) { err := r.handle(route) if err != nil { - log.Println(err) + logger.Println(err) } }) if err != nil { @@ -36,7 +35,7 @@ func (r *harRouter) addPageRoute(page Page) error { err := page.Route(r.urlOrPredicate, func(route Route) { err := r.handle(route) if err != nil { - log.Println(err) + logger.Println(err) } }) if err != nil { @@ -87,7 +86,7 @@ func (r *harRouter) handle(route Route) error { Headers: deserializeNameAndValueToMap(response.Headers), }) case "error": - log.Printf("har action error: %v", *response.Message) + logger.Printf("har action error: %v\n", *response.Message) fallthrough case "noentry": } diff --git a/page.go b/page.go index 256a5404..f35b458d 100644 --- a/page.go +++ b/page.go @@ -4,7 +4,6 @@ import ( "encoding/base64" "errors" "fmt" - "log" "os" "sync" "time" @@ -926,7 +925,7 @@ func (p *pageImpl) onRoute(route *routeImpl) { return nil, err }, true) if err != nil { - log.Printf("could not update interception patterns: %v", err) + logger.Printf("could not update interception patterns: %v\n", err) } } } diff --git a/run.go b/run.go index b201cd29..85ace742 100644 --- a/run.go +++ b/run.go @@ -21,11 +21,14 @@ const ( playwrightCliVersion = "1.42.1" ) -var playwrightCDNMirrors = []string{ - "https://playwright.azureedge.net", - "https://playwright-akamai.azureedge.net", - "https://playwright-verizon.azureedge.net", -} +var ( + logger = log.Default() + playwrightCDNMirrors = []string{ + "https://playwright.azureedge.net", + "https://playwright-akamai.azureedge.net", + "https://playwright-verizon.azureedge.net", + } +) type PlaywrightDriver struct { DriverDirectory, DriverBinaryLocation, Version string @@ -96,35 +99,29 @@ func (d *PlaywrightDriver) Install() error { if d.options.SkipInstallBrowsers { return nil } - if d.options.Verbose { - log.Println("Downloading browsers...") - } + + d.log("Downloading browsers...") if err := d.installBrowsers(d.DriverBinaryLocation); err != nil { return fmt.Errorf("could not install browsers: %w", err) } - if d.options.Verbose { - log.Println("Downloaded browsers successfully") - } + d.log("Downloaded browsers successfully") + return nil } // Uninstall removes the driver and the browsers. func (d *PlaywrightDriver) Uninstall() error { - if d.options.Verbose { - log.Println("Removing browsers...") - } + d.log("Removing browsers...") if err := d.uninstallBrowsers(d.DriverBinaryLocation); err != nil { return fmt.Errorf("could not uninstall browsers: %w", err) } - if d.options.Verbose { - log.Println("Removing driver...") - } + + d.log("Removing driver...") if err := os.RemoveAll(d.DriverDirectory); err != nil { return fmt.Errorf("could not remove driver directory: %w", err) } - if d.options.Verbose { - log.Println("Uninstall driver successfully") - } + + d.log("Uninstall driver successfully") return nil } @@ -138,9 +135,7 @@ func (d *PlaywrightDriver) DownloadDriver() error { return nil } - if d.options.Verbose { - log.Printf("Downloading driver to %s", d.DriverDirectory) - } + d.log(fmt.Sprintf("Downloading driver to %s", d.DriverDirectory)) body, err := downloadDriver(d.getDriverURLs()) if err != nil { @@ -184,14 +179,19 @@ func (d *PlaywrightDriver) DownloadDriver() error { } } + d.log("Downloaded driver successfully") + + return nil +} + +func (d *PlaywrightDriver) log(s string) { if d.options.Verbose { - log.Println("Downloaded driver successfully") + logger.Println(s) } - return nil } func (d *PlaywrightDriver) run() (*connection, error) { - transport, err := newPipeTransport(d.DriverBinaryLocation) + transport, err := newPipeTransport(d.DriverBinaryLocation, d.options.Stderr) if err != nil { return nil, err } @@ -206,16 +206,16 @@ func (d *PlaywrightDriver) installBrowsers(driverPath string) error { } cmd := exec.Command(driverPath, additionalArgs...) cmd.SysProcAttr = defaultSysProcAttr - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr + cmd.Stdout = d.options.Stdout + cmd.Stderr = d.options.Stderr return cmd.Run() } func (d *PlaywrightDriver) uninstallBrowsers(driverPath string) error { cmd := exec.Command(driverPath, "uninstall") cmd.SysProcAttr = defaultSysProcAttr - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr + cmd.Stdout = d.options.Stdout + cmd.Stderr = d.options.Stderr return cmd.Run() } @@ -224,7 +224,9 @@ type RunOptions struct { DriverDirectory string SkipInstallBrowsers bool Browsers []string - Verbose bool + Verbose bool // default true + Stdout io.Writer + Stderr io.Writer } // Install does download the driver and the browsers. If not called manually @@ -256,12 +258,21 @@ func Run(options ...*RunOptions) (*Playwright, error) { } func transformRunOptions(options []*RunOptions) *RunOptions { + option := &RunOptions{ + Verbose: true, + } if len(options) == 1 { - return options[0] + option = options[0] } - return &RunOptions{ - Verbose: true, + if option.Stdout == nil { + option.Stdout = os.Stdout + } + if option.Stderr == nil { + option.Stderr = os.Stderr + } else { + logger.SetOutput(option.Stderr) } + return option } func getDriverName() string { diff --git a/transport.go b/transport.go index 50875189..f9fba069 100644 --- a/transport.go +++ b/transport.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "io" - "log" "os" "os/exec" @@ -46,7 +45,7 @@ func (t *pipeTransport) Poll() (*message, error) { if os.Getenv("DEBUGP") != "" { fmt.Fprint(os.Stdout, "\x1b[33mRECV>\x1b[0m\n") if err := json.NewEncoder(os.Stdout).Encode(msg); err != nil { - log.Printf("could not encode json: %v", err) + logger.Printf("could not encode json: %v\n", err) } } return msg, nil @@ -74,7 +73,7 @@ func (t *pipeTransport) Send(msg map[string]interface{}) error { if os.Getenv("DEBUGP") != "" { fmt.Fprint(os.Stdout, "\x1b[32mSEND>\x1b[0m\n") if err := json.NewEncoder(os.Stdout).Encode(msg); err != nil { - log.Printf("could not encode json: %v", err) + logger.Printf("could not encode json: %v\n", err) } } lengthPadding := make([]byte, 4) @@ -103,14 +102,14 @@ func (t *pipeTransport) isClosed() bool { } } -func newPipeTransport(driverCli string) (transport, error) { +func newPipeTransport(driverCli string, stderr io.Writer) (transport, error) { t := &pipeTransport{ closed: make(chan struct{}, 1), } cmd := exec.Command(driverCli, "run-driver") cmd.SysProcAttr = defaultSysProcAttr - cmd.Stderr = os.Stderr + cmd.Stderr = stderr stdin, err := cmd.StdinPipe() if err != nil { return nil, fmt.Errorf("could not create stdin pipe: %w", err) diff --git a/websocket.go b/websocket.go index 6035514c..f28601d2 100644 --- a/websocket.go +++ b/websocket.go @@ -3,7 +3,6 @@ package playwright import ( "encoding/base64" "errors" - "log" ) type webSocketImpl struct { @@ -51,7 +50,7 @@ func (ws *webSocketImpl) onFrameSent(opcode float64, data string) { if opcode == 2 { payload, err := base64.StdEncoding.DecodeString(data) if err != nil { - log.Printf("could not decode WebSocket.onFrameSent payload: %v", err) + logger.Printf("could not decode WebSocket.onFrameSent payload: %v\n", err) return } ws.Emit("framesent", payload) @@ -64,7 +63,7 @@ func (ws *webSocketImpl) onFrameReceived(opcode float64, data string) { if opcode == 2 { payload, err := base64.StdEncoding.DecodeString(data) if err != nil { - log.Printf("could not decode WebSocket.onFrameReceived payload: %v", err) + logger.Printf("could not decode WebSocket.onFrameReceived payload: %v\n", err) return } ws.Emit("framereceived", payload)