16 Commits
v0.1.2 ... v0.1

Author SHA1 Message Date
xinglong
5aca12cc3e send messages with select to avoid deadlocks
Fixes #287.
2019-04-01 10:35:07 +01:00
Daniel Martí
e9aa66f87e fix build breakage with newer cdproto versions
This isn't strictly necessary, as one can always build with the earlier
cdproto version specified in go.mod. However, many people still install
chromedp in GOPATH via 'go get -u', so this workaround makes life easier
for a lot of developers.

Fixes #285.
2019-03-28 21:45:27 +00:00
Killian Brackey
39bd95c850 Clarified SIGTERM in shutdown comments 2019-03-02 14:20:46 +00:00
Killian Brackey
b61de69d62 Added SIGTERM to linux systems on shutdown
Closes https://github.com/chromedp/chromedp/issues/274
2019-03-02 14:20:46 +00:00
Daniel Martí
4cc9890745 add a simple issue template
For now, all it asks for is a few versions, and the typical three
questions to understand a bug.
2019-02-22 00:13:27 +01:00
Daniel Martí
37d13f2933 update all mod dependencies 2019-02-21 23:43:53 +01:00
Daniel Martí
26c9acb5b1 avoid ctx.Done() goroutine leak in Selector.run
As spotted in #162 by a contributor, if the context is done before the
Selector.run caller has received from the channel, the spawned goroutine
may leak if blocked on a send.
2019-02-21 17:58:08 +01:00
Daniel Martí
811d6d54d3 don't run TestFileUpload subtests in parallel
Turns out that these subtests are the only pair which cannot run in
parallel with each other. Undo that change and add a TODO. This should
fix the CI failures.

While at it, remove an unnecessary testAllocate line.
2019-02-21 17:22:40 +01:00
Daniel Martí
4c16288502 skip the error log in TestAllocatePortInUse
We know we're going to see an error, so don't log it too:

	$ go test -run TestAllocatePortInUse
	2019/02/21 17:11:34 ERROR: pool could not allocate runner ...
	PASS
	ok      github.com/chromedp/chromedp    0.004s
2019-02-21 17:13:38 +01:00
Daniel Martí
da4f783362 make all tests run in parallel
The subtests were almost all marked as parallel, but that's not enough.
That only makes the subtests run in parallel with other subtests within
the same tests, not with any other test.

Since none of the tests make use of globals nor require the entire
program to themselves, properly run all the tests in parallel.

Speeds up 'go test' on my 8-core laptop from an average of ~130s to an
average of ~50s. Many tests hit timeouts and have sleeps, so we want to
avoid running those sequentially whenever possible.
2019-02-21 13:56:54 +01:00
Daniel Martí
5ca52f3e1b use runner.LookChromeNames in TestMain
It supports alternative names for Chrome such as chromium, as well as
extra names to look for like headless-shell.

Also swap the os.Getenv logic, so that we only do the exec.LookPath work
if the env var is unset.
2019-02-21 13:53:05 +01:00
zhongjiajia
5dc1e0f3af use buffered chan for h.detached 2019-02-20 13:12:41 +01:00
Bob Potter
85ecf4f31f chromedp: fix SetHandlerByID
Don't fall through and return an error if we found a handler with a
matching ID.
2019-02-20 13:01:21 +01:00
Daniel Martí
7f54f3f93c CI: test on 1.11.x instead of tip
tip is rather unstable, so we shouldn't block PRs if it happens to break
our build or tests.

While at it, run 'go mod tidy' with the latest tip version.
2019-01-14 10:38:19 +00:00
Daniel Martí
98d4b0de6e pool: error quickly if we find a port in use
Before the fix, the added test would give a Pool.Allocate error like:

	pool could not connect to 9000: timeout waiting for initial target

The actual underlying error, which can only be seen if one inspects
chrome's stderr, is that it failed to bind to the debugging protocol
port if it was already in use.

This is of course an issue with the environment that chromedp is being
run under, since it was given a port range that wasn't available.
However, the confusing error can lead to developers wasting their time
instead of spotting the error quickly.

Unfortunately, there doesn't seem to be a way to have Chrome exit
immediately if it can't bind to the given port. So, instead of relying
on it, check if the current process can bind to the port first.

Add a test too, where we grab the first port in the pool range, and
check that we get an error that's not confusing.

Fixes #253.
2018-12-01 11:54:16 +00:00
Kenneth Shaw
bf52fed0d3 Fixing windows build issue 2018-07-18 06:19:22 +07:00
14 changed files with 173 additions and 73 deletions

15
.github/ISSUE_TEMPLATE vendored Normal file
View File

@@ -0,0 +1,15 @@
#### What versions are you running?
<pre>
$ go list -m github.com/chromedp/chromedp
$ chromium --version
$ go version
</pre>
#### What did you do?
#### What did you expect to see?
#### What did you see instead?

View File

@@ -1,7 +1,7 @@
language: go language: go
go: go:
- 1.10.x - 1.10.x
- tip - 1.11.x
addons: addons:
apt: apt:
chrome: stable chrome: stable

View File

@@ -239,6 +239,7 @@ func (c *CDP) SetHandlerByID(id string) error {
if i, ok := c.handlerMap[id]; ok { if i, ok := c.handlerMap[id]; ok {
c.cur = c.handlers[i] c.cur = c.handlers[i]
return nil
} }
return fmt.Errorf("no handler associated with target id %s", id) return fmt.Errorf("no handler associated with target id %s", id)

View File

@@ -4,7 +4,6 @@ import (
"context" "context"
"log" "log"
"os" "os"
"os/exec"
"path" "path"
"testing" "testing"
"time" "time"
@@ -78,16 +77,9 @@ func TestMain(m *testing.M) {
// its worth noting that newer versions of chrome (64+) run much faster // its worth noting that newer versions of chrome (64+) run much faster
// than older ones -- same for headless_shell ... // than older ones -- same for headless_shell ...
execPath := runner.DefaultChromePath execPath := os.Getenv("CHROMEDP_TEST_RUNNER")
if testRunner := os.Getenv("CHROMEDP_TEST_RUNNER"); testRunner != "" { if execPath == "" {
execPath = testRunner execPath = runner.LookChromeNames("headless_shell")
} else {
// use headless_shell, if on path
var hsPath string
hsPath, err = exec.LookPath("headless_shell")
if err == nil {
execPath = hsPath
}
} }
cliOpts = append(cliOpts, runner.ExecPath(execPath)) cliOpts = append(cliOpts, runner.ExecPath(execPath))

11
go.mod
View File

@@ -1,10 +1,9 @@
module github.com/chromedp/chromedp module github.com/chromedp/chromedp
require ( require (
github.com/chromedp/cdproto v0.0.0-20180713053126-e314dc107013 github.com/chromedp/cdproto v0.0.0-20190327003620-8d5e1d04ce19
github.com/disintegration/imaging v1.4.2 github.com/disintegration/imaging v1.6.0
github.com/gorilla/websocket v1.2.0 github.com/gorilla/websocket v1.4.0
github.com/knq/sysutil v0.0.0-20180306023629-0218e141a794 github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe
github.com/mailru/easyjson v0.0.0-20180606163543-3fdea8d05856 golang.org/x/image v0.0.0-20190220214146-31aff87c08e9 // indirect
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81
) )

31
go.sum
View File

@@ -1,19 +1,16 @@
github.com/chromedp/cdproto v0.0.0-20180522032958-55db67b53f25/go.mod h1:C2GPAraqdt1KfZU7aSmx1XUgarNq/3JmxevQkmCjOVs= github.com/chromedp/cdproto v0.0.0-20190327003620-8d5e1d04ce19 h1:KOdZXVcB8L3zR4ZsMAnviYJFIgfRP/iYSEzXl7rYXhc=
github.com/chromedp/cdproto v0.0.0-20180703215205-c125a34ea3b3 h1:4b4LwyHW4sf6zXZqWsKMYoICFLWGhaqwpEHlnQMN5SE= github.com/chromedp/cdproto v0.0.0-20190327003620-8d5e1d04ce19/go.mod h1:xquOK9dIGFlLaIGI4c6IyfLI/Gz0LiYYuJtzhsUODgI=
github.com/chromedp/cdproto v0.0.0-20180703215205-c125a34ea3b3/go.mod h1:C2GPAraqdt1KfZU7aSmx1XUgarNq/3JmxevQkmCjOVs= github.com/disintegration/imaging v1.6.0 h1:nVPXRUUQ36Z7MNf0O77UzgnOb1mkMMor7lmJMJXc/mA=
github.com/chromedp/cdproto v0.0.0-20180713053126-e314dc107013 h1:8nmuTwCseJcww39MvVHI59223+PxSzn6g3cl8ChF0/4= github.com/disintegration/imaging v1.6.0/go.mod h1:xuIt+sRxDFrHS0drzXUlCJthkJ8k7lkkUojDSR247MQ=
github.com/chromedp/cdproto v0.0.0-20180713053126-e314dc107013/go.mod h1:C2GPAraqdt1KfZU7aSmx1XUgarNq/3JmxevQkmCjOVs= github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
github.com/disintegration/imaging v1.4.2 h1:BSVxoYQ2NfLdvIGCDD8GHgBV5K0FCEsc0d/6FxQII3I= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/disintegration/imaging v1.4.2/go.mod h1:9B/deIUIrliYkyMTuXJd6OUFLcrZ2tf+3Qlwnaf/CjU= github.com/knq/sysutil v0.0.0-20181215143952-f05b59f0f307 h1:vl4eIlySbjertFaNwiMjXsGrFVK25aOWLq7n+3gh2ls=
github.com/gorilla/websocket v1.2.0 h1:VJtLvh6VQym50czpZzx07z/kw9EgAxI3x1ZB8taTMQQ= github.com/knq/sysutil v0.0.0-20181215143952-f05b59f0f307/go.mod h1:BjPj+aVjl9FW/cCGiF3nGh5v+9Gd3VCgBQbod/GlMaQ=
github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/knq/sysutil v0.0.0-20180306023629-0218e141a794 h1:hgWKTlyruPI7k8W+0FmTMLf+8d2KPxyzTxsfDDQhNp8= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe h1:W/GaMY0y69G4cFlmsC6B9sbuo2fP8OFP1ABjt4kPz+w=
github.com/knq/sysutil v0.0.0-20180306023629-0218e141a794/go.mod h1:BjPj+aVjl9FW/cCGiF3nGh5v+9Gd3VCgBQbod/GlMaQ= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20180323154445-8b799c424f57/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20180606163543-3fdea8d05856 h1:hOnidOuIWNsFRPcxxStGeN3NNm4n4+w6KJ9cVJIh70o=
github.com/mailru/easyjson v0.0.0-20180606163543-3fdea8d05856/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
golang.org/x/image v0.0.0-20180403161127-f315e4403028/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
golang.org/x/image v0.0.0-20180628062038-cc896f830ced h1:2QsAEqOy4Mp+V4HL2Wr1iBNpZWaL72EvTO4oj5bmr5w=
golang.org/x/image v0.0.0-20180628062038-cc896f830ced/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81 h1:00VmoueYNlNz/aHIilyyQz/MHSqGoWJzpFv/HW8xpzI= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81 h1:00VmoueYNlNz/aHIilyyQz/MHSqGoWJzpFv/HW8xpzI=
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
golang.org/x/image v0.0.0-20190220214146-31aff87c08e9 h1:+vH8qNweCrORN49012OX3h0oWEXO3p+rRnpAGQinddk=
golang.org/x/image v0.0.0-20190220214146-31aff87c08e9/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

View File

@@ -89,7 +89,7 @@ func (h *TargetHandler) Run(ctxt context.Context) error {
h.qres = make(chan *cdproto.Message) h.qres = make(chan *cdproto.Message)
h.qevents = make(chan *cdproto.Message) h.qevents = make(chan *cdproto.Message)
h.res = make(map[int64]chan *cdproto.Message) h.res = make(map[int64]chan *cdproto.Message)
h.detached = make(chan *inspector.EventDetached) h.detached = make(chan *inspector.EventDetached, 1)
h.pageWaitGroup = new(sync.WaitGroup) h.pageWaitGroup = new(sync.WaitGroup)
h.domWaitGroup = new(sync.WaitGroup) h.domWaitGroup = new(sync.WaitGroup)
h.Unlock() h.Unlock()
@@ -155,10 +155,18 @@ func (h *TargetHandler) run(ctxt context.Context) {
switch { switch {
case msg.Method != "": case msg.Method != "":
h.qevents <- msg select {
case h.qevents <- msg:
case <-ctxt.Done():
return
}
case msg.ID != 0: case msg.ID != 0:
h.qres <- msg select {
case h.qres <- msg:
case <-ctxt.Done():
return
}
default: default:
h.errf("ignoring malformed incoming message (missing id or method): %#v", msg) h.errf("ignoring malformed incoming message (missing id or method): %#v", msg)
@@ -226,6 +234,15 @@ func (h *TargetHandler) processEvent(ctxt context.Context, msg *cdproto.Message)
if msg == nil { if msg == nil {
return ErrChannelClosed return ErrChannelClosed
} }
switch msg.Method {
case "Page.frameClearedScheduledNavigation",
"Page.frameScheduledNavigation":
// These events are now deprecated, and UnmarshalMessage panics
// when they are received from Chrome. For now, to avoid panics
// and compile errors, and to fix chromedp v0 when installed via
// 'go get -u', skip the events here.
return nil
}
// unmarshal // unmarshal
ev, err := cdproto.UnmarshalMessage(msg) ev, err := cdproto.UnmarshalMessage(msg)
@@ -346,10 +363,14 @@ func (h *TargetHandler) Execute(ctxt context.Context, methodType string, params
h.resrw.Unlock() h.resrw.Unlock()
// queue message // queue message
h.qcmd <- &cdproto.Message{ select {
case h.qcmd <- &cdproto.Message{
ID: id, ID: id,
Method: cdproto.MethodType(methodType), Method: cdproto.MethodType(methodType),
Params: paramsBuf, Params: paramsBuf,
}:
case <- ctxt.Done():
return ctxt.Err()
} }
errch := make(chan error, 1) errch := make(chan error, 1)
@@ -530,13 +551,9 @@ func (h *TargetHandler) pageEvent(ctxt context.Context, ev interface{}) {
case *page.EventFrameStoppedLoading: case *page.EventFrameStoppedLoading:
id, op = e.FrameID, frameStoppedLoading id, op = e.FrameID, frameStoppedLoading
case *page.EventFrameScheduledNavigation:
id, op = e.FrameID, frameScheduledNavigation
case *page.EventFrameClearedScheduledNavigation:
id, op = e.FrameID, frameClearedScheduledNavigation
// ignored events // ignored events
case *page.EventFrameRequestedNavigation:
return
case *page.EventDomContentEventFired: case *page.EventDomContentEventFired:
return return
case *page.EventLoadEventFired: case *page.EventLoadEventFired:

View File

@@ -21,10 +21,10 @@ const (
) )
func TestMouseClickXY(t *testing.T) { func TestMouseClickXY(t *testing.T) {
var err error
t.Parallel() t.Parallel()
var err error
c := testAllocate(t, "input.html") c := testAllocate(t, "input.html")
defer c.Release() defer c.Release()
@@ -78,6 +78,8 @@ func TestMouseClickXY(t *testing.T) {
} }
func TestMouseClickNode(t *testing.T) { func TestMouseClickNode(t *testing.T) {
t.Parallel()
tests := []struct { tests := []struct {
sel, exp string sel, exp string
opt MouseOption opt MouseOption
@@ -128,6 +130,8 @@ func TestMouseClickNode(t *testing.T) {
} }
func TestMouseClickOffscreenNode(t *testing.T) { func TestMouseClickOffscreenNode(t *testing.T) {
t.Parallel()
tests := []struct { tests := []struct {
sel string sel string
exp int exp int
@@ -186,6 +190,8 @@ func TestMouseClickOffscreenNode(t *testing.T) {
} }
func TestKeyAction(t *testing.T) { func TestKeyAction(t *testing.T) {
t.Parallel()
tests := []struct { tests := []struct {
sel, exp string sel, exp string
by QueryOption by QueryOption
@@ -238,6 +244,8 @@ func TestKeyAction(t *testing.T) {
} }
func TestKeyActionNode(t *testing.T) { func TestKeyActionNode(t *testing.T) {
t.Parallel()
tests := []struct { tests := []struct {
sel, exp string sel, exp string
by QueryOption by QueryOption

13
pool.go
View File

@@ -4,6 +4,7 @@ import (
"context" "context"
"fmt" "fmt"
"log" "log"
"net"
"sync" "sync"
"github.com/chromedp/chromedp/runner" "github.com/chromedp/chromedp/runner"
@@ -70,6 +71,18 @@ func (p *Pool) Allocate(ctxt context.Context, opts ...runner.CommandLineOption)
r := p.next(ctxt) r := p.next(ctxt)
// Check if the port is available first. If it's not, Chrome will print
// an "address already in use" error, but it will otherwise keep
// running. This can lead to Allocate succeeding, while the chrome
// process isn't actually listening on the port we need.
l, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", r.port))
if err != nil {
// we can't use this port, e.g. address already in use
p.errf("pool could not allocate runner on port %d: %v", r.port, err)
return nil, err
}
l.Close()
p.debugf("pool allocating %d", r.port) p.debugf("pool allocating %d", r.port)
// create runner // create runner

47
pool_test.go Normal file
View File

@@ -0,0 +1,47 @@
package chromedp
import (
"context"
"net"
"strconv"
"strings"
"testing"
)
func TestAllocatePortInUse(t *testing.T) {
t.Parallel()
// take a random available port
l, err := net.Listen("tcp4", "localhost:0")
if err != nil {
t.Fatal(err)
}
defer l.Close()
ctxt, cancel := context.WithCancel(context.Background())
defer cancel()
// make the pool use the port already in use via a port range
_, portStr, _ := net.SplitHostPort(l.Addr().String())
port, _ := strconv.Atoi(portStr)
pool, err := NewPool(
PortRange(port, port+1),
// skip the error log from the used port
PoolLog(nil, nil, func(string, ...interface{}) {}),
)
if err != nil {
t.Fatal(err)
}
c, err := pool.Allocate(ctxt)
if err != nil {
want := "address already in use"
got := err.Error()
if !strings.Contains(got, want) {
t.Fatalf("wanted error to contain %q, but got %q", want, got)
}
} else {
t.Fatal("wanted Allocate to error if port is in use")
c.Release()
}
}

View File

@@ -190,6 +190,8 @@ func TestText(t *testing.T) {
} }
func TestClear(t *testing.T) { func TestClear(t *testing.T) {
t.Parallel()
tests := []struct { tests := []struct {
sel string sel string
by QueryOption by QueryOption
@@ -244,6 +246,8 @@ func TestClear(t *testing.T) {
} }
func TestReset(t *testing.T) { func TestReset(t *testing.T) {
t.Parallel()
tests := []struct { tests := []struct {
sel string sel string
by QueryOption by QueryOption
@@ -315,6 +319,8 @@ func TestValue(t *testing.T) {
} }
func TestSetValue(t *testing.T) { func TestSetValue(t *testing.T) {
t.Parallel()
tests := []struct { tests := []struct {
sel string sel string
by QueryOption by QueryOption
@@ -442,6 +448,8 @@ func TestAttributesAll(t *testing.T) {
} }
func TestSetAttributes(t *testing.T) { func TestSetAttributes(t *testing.T) {
t.Parallel()
tests := []struct { tests := []struct {
sel string sel string
by QueryOption by QueryOption
@@ -547,6 +555,8 @@ func TestAttributeValue(t *testing.T) {
} }
func TestSetAttributeValue(t *testing.T) { func TestSetAttributeValue(t *testing.T) {
t.Parallel()
tests := []struct { tests := []struct {
sel string sel string
by QueryOption by QueryOption
@@ -589,6 +599,8 @@ func TestSetAttributeValue(t *testing.T) {
} }
func TestRemoveAttribute(t *testing.T) { func TestRemoveAttribute(t *testing.T) {
t.Parallel()
tests := []struct { tests := []struct {
sel string sel string
by QueryOption by QueryOption
@@ -626,6 +638,8 @@ func TestRemoveAttribute(t *testing.T) {
} }
func TestClick(t *testing.T) { func TestClick(t *testing.T) {
t.Parallel()
tests := []struct { tests := []struct {
sel string sel string
by QueryOption by QueryOption
@@ -666,6 +680,8 @@ func TestClick(t *testing.T) {
} }
func TestDoubleClick(t *testing.T) { func TestDoubleClick(t *testing.T) {
t.Parallel()
tests := []struct { tests := []struct {
sel string sel string
by QueryOption by QueryOption
@@ -703,6 +719,8 @@ func TestDoubleClick(t *testing.T) {
} }
func TestSendKeys(t *testing.T) { func TestSendKeys(t *testing.T) {
t.Parallel()
tests := []struct { tests := []struct {
sel string sel string
by QueryOption by QueryOption
@@ -773,6 +791,8 @@ func TestScreenshot(t *testing.T) {
} }
func TestSubmit(t *testing.T) { func TestSubmit(t *testing.T) {
t.Parallel()
tests := []struct { tests := []struct {
sel string sel string
by QueryOption by QueryOption
@@ -813,6 +833,8 @@ func TestSubmit(t *testing.T) {
} }
func TestComputedStyle(t *testing.T) { func TestComputedStyle(t *testing.T) {
t.Parallel()
tests := []struct { tests := []struct {
sel string sel string
by QueryOption by QueryOption
@@ -870,6 +892,8 @@ func TestComputedStyle(t *testing.T) {
} }
func TestMatchedStyle(t *testing.T) { func TestMatchedStyle(t *testing.T) {
t.Parallel()
tests := []struct { tests := []struct {
sel string sel string
by QueryOption by QueryOption
@@ -940,9 +964,6 @@ func TestFileUpload(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
c := testAllocate(t, "")
defer c.Release()
tests := []struct { tests := []struct {
a Action a Action
}{ }{
@@ -952,6 +973,10 @@ func TestFileUpload(t *testing.T) {
for i, test := range tests { for i, test := range tests {
t.Run(fmt.Sprintf("test %d", i), func(t *testing.T) { t.Run(fmt.Sprintf("test %d", i), func(t *testing.T) {
// TODO: refactor the test so the subtests can run in
// parallel
//t.Parallel()
c := testAllocate(t, "") c := testAllocate(t, "")
defer c.Release() defer c.Release()

View File

@@ -213,7 +213,8 @@ func (r *Runner) Start(ctxt context.Context, opts ...string) error {
return nil return nil
} }
// Shutdown shuts down the Chrome process. // Shutdown shuts down the Chrome process. Currently only has support for
// SIGTERM in darwin and linux systems
func (r *Runner) Shutdown(ctxt context.Context, opts ...client.Option) error { func (r *Runner) Shutdown(ctxt context.Context, opts ...client.Option) error {
var err error var err error
@@ -241,12 +242,15 @@ func (r *Runner) Shutdown(ctxt context.Context, opts ...client.Option) error {
} }
} }
// osx applications do not automatically exit when all windows (ie, tabs) // osx and linux applications do not automatically exit when all windows (ie, tabs)
// closed, so send SIGTERM. // closed, so send SIGTERM.
// //
// TODO: add other behavior here for more process options on shutdown? // TODO: add other behavior here for more process options on shutdown?
if runtime.GOOS == "darwin" && r.cmd != nil && r.cmd.Process != nil { if r.cmd != nil && r.cmd.Process != nil {
return r.cmd.Process.Signal(syscall.SIGTERM) switch runtime.GOOS {
case "darwin", "linux":
return r.cmd.Process.Signal(syscall.SIGTERM)
}
} }
return nil return nil

View File

@@ -24,21 +24,3 @@ func KillProcessGroup(m map[string]interface{}) error {
func ForceKill(m map[string]interface{}) error { func ForceKill(m map[string]interface{}) error {
return nil return nil
} }
// EdgeDiagnosticsAdapterWithPath is a command line option to specify using the
// Microsoft Edge Diagnostics adapter at the specified path.
func EdgeDiagnosticsAdapterWithPathAndPort(path string, port int) CommandLineOption {
return func(m map[string]interface{}) error {
m["exec-path"] = path
m["port"] = port
return nil
}
}
// EdgeDiagnosticsAdapter is a command line option to specify using the
// Microsoft Edge Diagnostics adapter found on the path.
//
// If the
func EdgeDiagnosticsAdapter() CommandLineOption {
return EdgeDiagnosticsAdapterWithPathAndPort(findEdgePath(), 9222)
}

2
sel.go
View File

@@ -80,7 +80,7 @@ func (s *Selector) Do(ctxt context.Context, h cdp.Executor) error {
// are invalidated prior to finishing the selector's by, wait, check, and after // are invalidated prior to finishing the selector's by, wait, check, and after
// funcs. // funcs.
func (s *Selector) run(ctxt context.Context, h *TargetHandler) chan error { func (s *Selector) run(ctxt context.Context, h *TargetHandler) chan error {
ch := make(chan error) ch := make(chan error, 1)
go func() { go func() {
defer close(ch) defer close(ch)