Skip to content

Commit

Permalink
add tests for rod
Browse files Browse the repository at this point in the history
  • Loading branch information
ysmood committed Jul 28, 2020
1 parent ebec8e5 commit f1b8f0d
Show file tree
Hide file tree
Showing 22 changed files with 555 additions and 100 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
- name: test
run: |
godev --version
rod=trace godev -l -m 92
godev -l -m 92
- uses: codecov/codecov-action@v1

Expand Down
47 changes: 31 additions & 16 deletions browser.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@ type Browser struct {

monitorServer *kit.ServerContext

client *cdp.Client
event *goob.Observable // all the browser events from cdp client
client *cdp.Client
cdpCall CDPCall
event *goob.Observable // all the browser events from cdp client

// stores all the previous cdp call of same type. Browser doesn't have enough API
// for us to retrieve all its internal states. This is an workaround to map them to local.
Expand Down Expand Up @@ -124,8 +125,20 @@ func (b *Browser) Client(c *cdp.Client) *Browser {
return b
}

// CDPCall overrides the cdp.Client.Call
func (b *Browser) CDPCall(c CDPCall) *Browser {
b.cdpCall = c
return b
}

// ConnectE doc is similar to the method Connect
func (b *Browser) ConnectE() error {
func (b *Browser) ConnectE() (err error) {
defer func() {
if e := recover(); e != nil {
err = e.(error)
}
}()

if b.client == nil {
u := defaults.URL
if defaults.Remote {
Expand All @@ -135,20 +148,13 @@ func (b *Browser) ConnectE() error {
b.client = launcher.NewRemote(u).Client()
} else {
if u == "" {
var err error
u, err = launcher.New().Context(b.ctx).LaunchE()
if err != nil {
return err
}
u = launcher.New().Context(b.ctx).Launch()
}
b.client = cdp.New(u)
}
}

err := b.client.Context(b.ctx, b.ctxCancel).ConnectE()
if err != nil {
return err
}
b.client.Context(b.ctx, b.ctxCancel).Connect()

b.monitorServer = b.ServeMonitor(defaults.Monitor, !defaults.Blind)

Expand Down Expand Up @@ -312,7 +318,11 @@ func (b *Browser) waitEvent(ctx context.Context, sessionID proto.TargetSessionID

// Call raw cdp interface directly
func (b *Browser) Call(ctx context.Context, sessionID, methodName string, params json.RawMessage) (res []byte, err error) {
res, err = b.client.Call(ctx, sessionID, methodName, params)
if b.cdpCall == nil {
res, err = b.client.Call(ctx, sessionID, methodName, params)
} else {
res, err = b.cdpCall(ctx, sessionID, methodName, params)
}
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -344,12 +354,17 @@ func (b *Browser) PageFromTargetIDE(targetID proto.TargetTargetID) (*Page, error
executionIDs: map[proto.PageFrameID]proto.RuntimeExecutionContextID{},
}).Context(context.WithCancel(b.ctx))

b.storePage(page)

page.Mouse = &Mouse{lock: &sync.Mutex{}, page: page, id: kit.RandString(8)}
page.Keyboard = &Keyboard{lock: &sync.Mutex{}, page: page}

return page, page.initSession()
err := page.initSession()
if err != nil {
return nil, err
}

b.storePage(page)

return page, nil
}

func (b *Browser) initEvents() {
Expand Down
95 changes: 82 additions & 13 deletions browser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,10 @@ import (
"github.com/go-rod/rod"
"github.com/go-rod/rod/lib/launcher"
"github.com/go-rod/rod/lib/proto"
"github.com/tidwall/sjson"
"github.com/ysmood/kit"
)

func (s *S) TestBrowserContext() {
s.browser.Timeout(time.Minute).CancelTimeout()
}

func (s *S) TestIncognito() {
file := srcFile("fixtures/click.html")
k := kit.RandString(8)
Expand All @@ -41,13 +38,46 @@ func (s *S) TestBrowserPages() {
// TODO: I don't know why sometimes windows can miss one
if runtime.GOOS == "windows" {
s.GreaterOrEqual(len(pages), 2)
return
} else {
s.Len(pages, 3)

func() {
defer s.at(1, func(d []byte, err error) ([]byte, error) {
return sjson.SetBytes(d, "targetInfos.0.type", "iframe")
})()
pages := s.browser.Pages()
s.Len(pages, 2)
}()
}
s.Panics(func() {
defer s.errorAt(1, nil)()
s.browser.Page("")
})
s.Panics(func() {
defer s.errorAt(1, nil)()
s.browser.Pages()
})
s.Panics(func() {
res, err := proto.TargetCreateTarget{URL: "about:blank"}.Call(s.browser)
kit.E(err)
defer func() {
s.browser.PageFromTargetID(res.TargetID).Close()
}()
defer s.errorAt(2, nil)()
s.browser.Pages()
})
}

func (s *S) TestBrowserClearStates() {
kit.E(proto.EmulationClearGeolocationOverride{}.Call(s.page))

s.Len(pages, 3)
defer s.browser.EnableDomain(s.browser.GetContext(), "", &proto.TargetSetDiscoverTargets{Discover: true})()
s.browser.DisableDomain(s.browser.GetContext(), "", &proto.TargetSetDiscoverTargets{Discover: false})()
}

func (s *S) TestBrowserWaitEvent() {
s.NotNil(s.browser.Event())

wait := s.page.WaitEvent(&proto.PageFrameNavigated{})
s.page.Navigate(srcFile("fixtures/click.html"))
wait()
Expand Down Expand Up @@ -81,7 +111,7 @@ func (s *S) TestMonitor() {
b := rod.New().Timeout(1 * time.Minute).Connect()
defer b.Close()
p := b.Page(srcFile("fixtures/click.html")).WaitLoad()
host := b.ServeMonitor("127.0.0.1:0", false).Listener.Addr().String()
host := b.ServeMonitor("127.0.0.1:0", true).Listener.Addr().String()

page := s.page.Navigate("http://" + host)
s.Contains(page.WaitLoad().Element("#targets").HTML(), string(p.TargetID))
Expand All @@ -97,19 +127,47 @@ func (s *S) TestRemoteLaunch() {
proxy := launcher.NewProxy()
engine.NoRoute(gin.WrapH(proxy))

ctx, cancel := context.WithCancel(context.Background())
l := launcher.NewRemote(strings.ReplaceAll(url, "http", "ws"))
b := rod.New().Timeout(1 * time.Minute).Client(l.Client()).Connect()
defer b.CancelTimeout()
c := l.Client().Context(ctx, cancel)
b := rod.New().Context(ctx, cancel).Client(c).Connect()
defer b.Close()

p := b.Page(srcFile("fixtures/click.html"))
p.Element("button").Click()
s.True(p.Has("[a=ok]"))
}

b.Close()
func (s *S) TestTrace() {
msg := ""
var errs []error
s.browser.TraceLog(
func(s string) {
msg = s
},
func(string, rod.Array) {},
func(e error) {
errs = append(errs, e)
},
)
s.browser.Trace(true).Slowmotion(time.Microsecond)
defer func() {
s.browser.TraceLog(nil, nil, nil)
s.browser.Trace(false).Slowmotion(0)
}()

kit.Sleep(0.3)
dir, _ := l.Get("user-data-dir")
s.NoDirExists(dir)
p := s.page.Navigate(srcFile("fixtures/click.html"))
el := p.Element("button")
el.Click()
s.Equal("left click", msg)

ctx, cancel := context.WithCancel(context.Background())
cancel()
p.Context(ctx, cancel).Overlay(0, 0, 100, 100, "msg")
s.Error(errs[0])

el.Context(ctx, cancel).Trace("ok")
s.Error(errs[1])
}

func (s *S) TestConcurrentOperations() {
Expand Down Expand Up @@ -231,6 +289,17 @@ func (s *S) TestTry() {
s.Equal(1, errVal.Details)
}

func (s *S) TestBrowserOthers() {
s.browser.Timeout(time.Minute).CancelTimeout()

ctx, cancel := context.WithCancel(context.Background())
cancel()

s.Panics(func() {
s.browser.Context(ctx, cancel).Incognito()
})
}

// It's obvious that, the v8 will take more time to parse long function.
// For BenchmarkCache and BenchmarkNoCache, the difference is nearly 12% which is too much to ignore.
func BenchmarkCacheOff(b *testing.B) {
Expand Down
8 changes: 1 addition & 7 deletions dev_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"html"
"log"
"net/http"
"os/exec"
"regexp"
"strings"
"time"
Expand Down Expand Up @@ -73,12 +72,7 @@ func (b *Browser) ServeMonitor(host string, openBrowser bool) *kit.ServerContext
}()

if openBrowser {
url := "http://" + strings.Replace(srv.Listener.Addr().String(), "[::]", "[::1]", 1)
bin, err := launcher.NewBrowser().Get()
kit.E(err)
p := exec.Command(bin, url)
kit.E(p.Start())
kit.E(p.Process.Release())
launcher.NewBrowser().Open("http://" + srv.Listener.Addr().String())
}

return srv
Expand Down
27 changes: 4 additions & 23 deletions element.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,9 +265,7 @@ func (el *Element) SetFilesE(paths []string) error {
absPaths := []string{}
for _, p := range paths {
absPath, err := filepath.Abs(p)
if err != nil {
return err
}
kit.E(err)
absPaths = append(absPaths, absPath)
}

Expand All @@ -294,8 +292,7 @@ func (el *Element) DescribeE(depth int, pierce bool) (*proto.DOMNode, error) {

// NodeIDE of the node
func (el *Element) NodeIDE() (proto.DOMNodeID, error) {
defer el.page.enableNodeQuery()()

el.page.enableNodeQuery()
node, err := proto.DOMRequestNode{ObjectID: el.ObjectID}.Call(el)
if err != nil {
return 0, err
Expand Down Expand Up @@ -389,7 +386,7 @@ func (el *Element) WaitStableE(interval time.Duration) error {
t := time.NewTicker(interval)
defer t.Stop()

for range t.C {
for {
select {
case <-t.C:
case <-el.ctx.Done():
Expand Down Expand Up @@ -445,10 +442,6 @@ func (el *Element) CanvasToImageE(format string, quality float64) ([]byte, error
}

_, bin := parseDataURI(res.Value.Str)
if err != nil {
return nil, err
}

return bin, nil
}

Expand Down Expand Up @@ -480,9 +473,7 @@ func (el *Element) ResourceE() ([]byte, error) {
var bin []byte
if res.Base64Encoded {
bin, err = base64.StdEncoding.DecodeString(data)
if err != nil {
return nil, err
}
kit.E(err)
} else {
bin = []byte(data)
}
Expand Down Expand Up @@ -518,10 +509,6 @@ func (el *Element) ScreenshotE(format proto.PageCaptureScreenshotFormat, quality
},
}

if quality > -1 {
opts.Quality = int64(quality)
}

return el.page.Root().ScreenshotE(false, opts)
}

Expand Down Expand Up @@ -577,12 +564,6 @@ func (el *Element) ensureParentPage(nodeID proto.DOMNodeID, objID proto.RuntimeR
}

err = walk(p)

err = f.ReleaseE()
if err != nil {
return err
}

if err != nil {
return err
}
Expand Down
Loading

0 comments on commit f1b8f0d

Please sign in to comment.