Parallelizing unit tests

This commit is contained in:
Kenneth Shaw 2017-02-18 13:11:46 +07:00
parent b5687e625d
commit dc17e7f8cd
4 changed files with 292 additions and 266 deletions

View File

@ -8,7 +8,7 @@ import (
) )
var pool *Pool var pool *Pool
var defaultContext = context.Background() var defaultContext, defaultCancel = context.WithCancel(context.Background())
var testdataDir string var testdataDir string
func testAllocate(t *testing.T, path string) *Res { func testAllocate(t *testing.T, path string) *Res {
@ -67,6 +67,8 @@ func TestMain(m *testing.M) {
code := m.Run() code := m.Run()
defaultCancel()
err = pool.Shutdown() err = pool.Shutdown()
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)

View File

@ -6,6 +6,8 @@ import (
) )
func TestNavigate(t *testing.T) { func TestNavigate(t *testing.T) {
t.Parallel()
var err error var err error
c := testAllocate(t, "") c := testAllocate(t, "")

44
pool.go
View File

@ -66,51 +66,44 @@ func (p *Pool) Shutdown() error {
func (p *Pool) Allocate(ctxt context.Context, opts ...runner.CommandLineOption) (*Res, error) { func (p *Pool) Allocate(ctxt context.Context, opts ...runner.CommandLineOption) (*Res, error) {
var err error var err error
ctxt, cancel := context.WithCancel(ctxt) r := p.next(ctxt)
r := &Res{ p.debugf("pool allocating %d", r.port)
p: p,
ctxt: ctxt,
cancel: cancel,
port: p.next(),
}
// create runner // create runner
r.r, err = runner.New(append([]runner.CommandLineOption{ r.r, err = runner.New(append([]runner.CommandLineOption{
runner.Headless("", r.port), runner.Headless("", r.port),
}, opts...)...) }, opts...)...)
if err != nil { if err != nil {
cancel() defer r.Release()
p.errorf("pool could not allocate runner on port %d: %v", r.port, err)
return nil, err return nil, err
} }
// start runner // start runner
err = r.r.Start(ctxt) err = r.r.Start(r.ctxt)
if err != nil { if err != nil {
cancel() defer r.Release()
p.errorf("pool could not start runner on port %d: %v", r.port, err)
return nil, err return nil, err
} }
// setup cdp // setup cdp
r.c, err = New( r.c, err = New(
ctxt, WithRunner(r.r), r.ctxt, WithRunner(r.r),
WithLogf(p.logf), WithDebugf(p.debugf), WithErrorf(p.errorf), WithLogf(p.logf), WithDebugf(p.debugf), WithErrorf(p.errorf),
) )
if err != nil { if err != nil {
cancel() defer r.Release()
p.errorf("pool could not connect to %d: %v", r.port, err)
return nil, err return nil, err
} }
p.rw.Lock()
defer p.rw.Unlock()
p.res[r.port] = r
return r, nil return r, nil
} }
// next returns the next available port number. // next returns the next available res.
func (p *Pool) next() int { func (p *Pool) next(ctxt context.Context) *Res {
p.rw.Lock() p.rw.Lock()
defer p.rw.Unlock() defer p.rw.Unlock()
@ -127,7 +120,15 @@ func (p *Pool) next() int {
panic("no ports available") panic("no ports available")
} }
return i r := &Res{
p: p,
port: i,
}
r.ctxt, r.cancel = context.WithCancel(ctxt)
p.res[i] = r
return r
} }
// Res is a pool resource. // Res is a pool resource.
@ -146,9 +147,10 @@ func (r *Res) Release() error {
err := r.c.Wait() err := r.c.Wait()
defer r.p.debugf("pool released %d", r.port)
r.p.rw.Lock() r.p.rw.Lock()
defer r.p.rw.Unlock() defer r.p.rw.Unlock()
delete(r.p.res, r.port) delete(r.p.res, r.port)
return err return err

View File

@ -1,9 +1,9 @@
package chromedp package chromedp
import ( import (
"fmt"
"reflect" "reflect"
"testing" "testing"
"time"
"github.com/knq/chromedp/cdp" "github.com/knq/chromedp/cdp"
"github.com/knq/chromedp/cdp/css" "github.com/knq/chromedp/cdp/css"
@ -12,6 +12,8 @@ import (
) )
func TestNodes(t *testing.T) { func TestNodes(t *testing.T) {
t.Parallel()
c := testAllocate(t, "table.html") c := testAllocate(t, "table.html")
defer c.Release() defer c.Release()
@ -40,13 +42,15 @@ func TestNodes(t *testing.T) {
} }
func TestNodeIDs(t *testing.T) { func TestNodeIDs(t *testing.T) {
t.Parallel()
c := testAllocate(t, "table.html") c := testAllocate(t, "table.html")
defer c.Release() defer c.Release()
tests := []struct { tests := []struct {
sel string sel string
option QueryOption by QueryOption
len int len int
}{ }{
{"/html/body/table/tbody[1]/tr[2]/td", BySearch, 3}, {"/html/body/table/tbody[1]/tr[2]/td", BySearch, 3},
{"body > table > tbody:nth-child(2) > tr:nth-child(2) > td:not(:last-child)", ByQueryAll, 2}, {"body > table > tbody:nth-child(2) > tr:nth-child(2) > td:not(:last-child)", ByQueryAll, 2},
@ -57,7 +61,7 @@ func TestNodeIDs(t *testing.T) {
var err error var err error
for i, test := range tests { for i, test := range tests {
var ids []cdp.NodeID var ids []cdp.NodeID
err = c.Run(defaultContext, NodeIDs(test.sel, &ids, test.option)) err = c.Run(defaultContext, NodeIDs(test.sel, &ids, test.by))
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -68,12 +72,14 @@ func TestNodeIDs(t *testing.T) {
} }
func TestFocusBlur(t *testing.T) { func TestFocusBlur(t *testing.T) {
t.Parallel()
c := testAllocate(t, "js.html") c := testAllocate(t, "js.html")
defer c.Release() defer c.Release()
tests := []struct { tests := []struct {
sel string sel string
option QueryOption by QueryOption
}{ }{
{`//*[@id="input1"]`, BySearch}, {`//*[@id="input1"]`, BySearch},
{`body > input[type="number"]:nth-child(1)`, ByQueryAll}, {`body > input[type="number"]:nth-child(1)`, ByQueryAll},
@ -87,13 +93,13 @@ func TestFocusBlur(t *testing.T) {
} }
for i, test := range tests { for i, test := range tests {
err = c.Run(defaultContext, Focus(test.sel, test.option)) err = c.Run(defaultContext, Focus(test.sel, test.by))
if err != nil { if err != nil {
t.Fatalf("test %d got error: %v", i, err) t.Fatalf("test %d got error: %v", i, err)
} }
var value string var value string
err = c.Run(defaultContext, Value(test.sel, &value, test.option)) err = c.Run(defaultContext, Value(test.sel, &value, test.by))
if err != nil { if err != nil {
t.Fatalf("test %d got error: %v", i, err) t.Fatalf("test %d got error: %v", i, err)
} }
@ -101,12 +107,12 @@ func TestFocusBlur(t *testing.T) {
t.Errorf("test %d expected value is '9999', got: '%s'", i, value) t.Errorf("test %d expected value is '9999', got: '%s'", i, value)
} }
err = c.Run(defaultContext, Blur(test.sel, test.option)) err = c.Run(defaultContext, Blur(test.sel, test.by))
if err != nil { if err != nil {
t.Fatalf("test %d got error: %v", i, err) t.Fatalf("test %d got error: %v", i, err)
} }
err = c.Run(defaultContext, Value(test.sel, &value, test.option)) err = c.Run(defaultContext, Value(test.sel, &value, test.by))
if err != nil { if err != nil {
t.Fatalf("test %d got error: %v", i, err) t.Fatalf("test %d got error: %v", i, err)
} }
@ -117,6 +123,8 @@ func TestFocusBlur(t *testing.T) {
} }
func TestDimensions(t *testing.T) { func TestDimensions(t *testing.T) {
t.Parallel()
c := testAllocate(t, "image.html") c := testAllocate(t, "image.html")
defer c.Release() defer c.Release()
@ -146,6 +154,8 @@ func TestDimensions(t *testing.T) {
} }
func TestText(t *testing.T) { func TestText(t *testing.T) {
t.Parallel()
c := testAllocate(t, "form.html") c := testAllocate(t, "form.html")
defer c.Release() defer c.Release()
@ -195,32 +205,35 @@ func TestClear(t *testing.T) {
{`#form > input[type="text"]`, ByQueryAll}, {`#form > input[type="text"]`, ByQueryAll},
} }
var err error
for i, test := range tests { for i, test := range tests {
c := testAllocate(t, "form.html") t.Run(fmt.Sprintf("test %d", i), func(t *testing.T) {
defer c.Release() t.Parallel()
var val string c := testAllocate(t, "form.html")
err = c.Run(defaultContext, Value(test.sel, &val, test.by)) defer c.Release()
if err != nil {
t.Fatalf("test %d got error: %v", i, err)
}
if val == "" {
t.Errorf("test %d expected `%s` to have non empty value", i, test.sel)
}
err = c.Run(defaultContext, Clear(test.sel, test.by)) var val string
if err != nil { err := c.Run(defaultContext, Value(test.sel, &val, test.by))
t.Fatalf("test %d got error: %v", i, err) if err != nil {
} t.Fatalf("got error: %v", err)
}
if val == "" {
t.Errorf("expected `%s` to have non empty value", test.sel)
}
err = c.Run(defaultContext, Value(test.sel, &val, test.by)) err = c.Run(defaultContext, Clear(test.sel, test.by))
if err != nil { if err != nil {
t.Fatalf("test %d got error: %v", i, err) t.Fatalf("got error: %v", err)
} }
if val != "" {
t.Errorf("test %d expected empty value for `%s`, got: %s", i, test.sel, val) err = c.Run(defaultContext, Value(test.sel, &val, test.by))
} if err != nil {
t.Fatalf("got error: %v", err)
}
if val != "" {
t.Errorf("expected empty value for `%s`, got: %s", test.sel, val)
}
})
} }
} }
@ -237,33 +250,38 @@ func TestReset(t *testing.T) {
{"#bar", ByID, "foobar", "bar"}, {"#bar", ByID, "foobar", "bar"},
} }
var err error
for i, test := range tests { for i, test := range tests {
c := testAllocate(t, "form.html") t.Run(fmt.Sprintf("test %d", i), func(t *testing.T) {
defer c.Release() t.Parallel()
err = c.Run(defaultContext, SetValue(test.sel, test.value, test.by)) c := testAllocate(t, "form.html")
if err != nil { defer c.Release()
t.Fatalf("test %d got error: %v", i, err)
}
err = c.Run(defaultContext, Reset(test.sel, test.by)) err := c.Run(defaultContext, SetValue(test.sel, test.value, test.by))
if err != nil { if err != nil {
t.Fatalf("test %d got error: %v", i, err) t.Fatalf("got error: %v", err)
} }
var value string err = c.Run(defaultContext, Reset(test.sel, test.by))
err = c.Run(defaultContext, Value(test.sel, &value, test.by)) if err != nil {
if err != nil { t.Fatalf("got error: %v", err)
t.Fatalf("test %d got error: %v", i, err) }
}
if value != test.exp { var value string
t.Errorf("test %d expected value after reset is %s, got: '%s'", i, test.exp, value) err = c.Run(defaultContext, Value(test.sel, &value, test.by))
} if err != nil {
t.Fatalf("got error: %v", err)
}
if value != test.exp {
t.Errorf("expected value after reset is %s, got: '%s'", test.exp, value)
}
})
} }
} }
func TestValue(t *testing.T) { func TestValue(t *testing.T) {
t.Parallel()
c := testAllocate(t, "form.html") c := testAllocate(t, "form.html")
defer c.Release() defer c.Release()
@ -291,9 +309,6 @@ func TestValue(t *testing.T) {
} }
func TestSetValue(t *testing.T) { func TestSetValue(t *testing.T) {
c := testAllocate(t, "form.html")
defer c.Release()
tests := []struct { tests := []struct {
sel string sel string
by QueryOption by QueryOption
@ -304,33 +319,33 @@ func TestSetValue(t *testing.T) {
{`#bar`, ByID}, {`#bar`, ByID},
} }
var err error
for i, test := range tests { for i, test := range tests {
if i != 0 { t.Run(fmt.Sprintf("test %d", i), func(t *testing.T) {
err = c.Run(defaultContext, Reload()) t.Parallel()
c := testAllocate(t, "form.html")
defer c.Release()
err := c.Run(defaultContext, SetValue(test.sel, "FOOBAR", test.by))
if err != nil { if err != nil {
t.Fatalf("test %d got error: %v", i, err) t.Fatalf("test %d got error: %v", i, err)
} }
time.Sleep(50 * time.Millisecond)
}
err = c.Run(defaultContext, SetValue(test.sel, "FOOBAR", test.by)) var value string
if err != nil { err = c.Run(defaultContext, Value(test.sel, &value, test.by))
t.Fatalf("test %d got error: %v", i, err) if err != nil {
} t.Fatalf("test %d got error: %v", i, err)
}
var value string if value != "FOOBAR" {
err = c.Run(defaultContext, Value(test.sel, &value, test.by)) t.Errorf("test %d expected `FOOBAR`, got: %s", i, value)
if err != nil { }
t.Fatalf("test %d got error: %v", i, err) })
}
if value != "FOOBAR" {
t.Errorf("test %d expected `FOOBAR`, got: %s", i, value)
}
} }
} }
func TestAttributes(t *testing.T) { func TestAttributes(t *testing.T) {
t.Parallel()
c := testAllocate(t, "image.html") c := testAllocate(t, "image.html")
defer c.Release() defer c.Release()
@ -421,29 +436,34 @@ func TestSetAttributes(t *testing.T) {
}}, }},
} }
var err error
for i, test := range tests { for i, test := range tests {
c := testAllocate(t, "image.html") t.Run(fmt.Sprintf("test %d", i), func(t *testing.T) {
defer c.Release() t.Parallel()
err = c.Run(defaultContext, SetAttributes(test.sel, test.attrs, test.by)) c := testAllocate(t, "image.html")
if err != nil { defer c.Release()
t.Fatalf("test %d got error: %v", i, err)
}
var attrs map[string]string err := c.Run(defaultContext, SetAttributes(test.sel, test.attrs, test.by))
err = c.Run(defaultContext, Attributes(test.sel, &attrs, test.by)) if err != nil {
if err != nil { t.Fatalf("got error: %v", err)
t.Fatalf("test %d got error: %v", i, err) }
}
if !reflect.DeepEqual(test.exp, attrs) { var attrs map[string]string
t.Errorf("test %d expected %v, got: %v", i, test.exp, attrs) err = c.Run(defaultContext, Attributes(test.sel, &attrs, test.by))
} if err != nil {
t.Fatalf("got error: %v", err)
}
if !reflect.DeepEqual(test.exp, attrs) {
t.Errorf("expected %v, got: %v", test.exp, attrs)
}
})
} }
} }
func TestAttributeValue(t *testing.T) { func TestAttributeValue(t *testing.T) {
t.Parallel()
c := testAllocate(t, "image.html") c := testAllocate(t, "image.html")
defer c.Release() defer c.Release()
@ -492,35 +512,36 @@ func TestSetAttributeValue(t *testing.T) {
{"#bar", ByID, "foo", "bar"}, {"#bar", ByID, "foo", "bar"},
} }
var err error
for i, test := range tests { for i, test := range tests {
c := testAllocate(t, "form.html") t.Run(fmt.Sprintf("test %d", i), func(t *testing.T) {
defer c.Release() t.Parallel()
err = c.Run(defaultContext, SetAttributeValue(test.sel, test.attr, test.exp, test.by)) c := testAllocate(t, "form.html")
if err != nil { defer c.Release()
t.Fatalf("test %d got error: %v", i, err)
}
var value string err := c.Run(defaultContext, SetAttributeValue(test.sel, test.attr, test.exp, test.by))
var ok bool if err != nil {
err = c.Run(defaultContext, AttributeValue(test.sel, test.attr, &value, &ok, test.by)) t.Fatalf("test %d got error: %v", i, err)
if err != nil { }
t.Fatalf("test %d got error: %v", i, err)
} var value string
if !ok { var ok bool
t.Fatalf("test %d failed to get attribute %s on %s", i, test.attr, test.sel) err = c.Run(defaultContext, AttributeValue(test.sel, test.attr, &value, &ok, test.by))
} if err != nil {
if value != test.exp { t.Fatalf("test %d got error: %v", i, err)
t.Errorf("test %d expected %s to be %s, got: %s", i, test.attr, test.exp, value) }
} if !ok {
t.Fatalf("test %d failed to get attribute %s on %s", i, test.attr, test.sel)
}
if value != test.exp {
t.Errorf("test %d expected %s to be %s, got: %s", i, test.attr, test.exp, value)
}
})
} }
} }
func TestRemoveAttribute(t *testing.T) { func TestRemoveAttribute(t *testing.T) {
c := testAllocate(t, "image.html")
defer c.Release()
tests := []struct { tests := []struct {
sel string sel string
by QueryOption by QueryOption
@ -532,30 +553,28 @@ func TestRemoveAttribute(t *testing.T) {
{"#icon-github", ByID, "alt"}, {"#icon-github", ByID, "alt"},
} }
var err error
for i, test := range tests { for i, test := range tests {
if i != 0 { t.Run(fmt.Sprintf("test %d", i), func(t *testing.T) {
err = c.Run(defaultContext, Reload()) t.Parallel()
c := testAllocate(t, "image.html")
defer c.Release()
err := c.Run(defaultContext, RemoveAttribute(test.sel, test.attr))
if err != nil { if err != nil {
t.Fatalf("test %d got error: %v", i, err) t.Fatalf("got error: %v", err)
} }
time.Sleep(50 * time.Millisecond)
}
err = c.Run(defaultContext, RemoveAttribute(test.sel, test.attr)) var value string
if err != nil { var ok bool
t.Fatalf("test %d got error: %v", i, err) err = c.Run(defaultContext, AttributeValue(test.sel, test.attr, &value, &ok, test.by))
} if err != nil {
t.Fatalf("got error: %v", err)
var value string }
var ok bool if ok || value != "" {
err = c.Run(defaultContext, AttributeValue(test.sel, test.attr, &value, &ok, test.by)) t.Fatalf("expected attribute %s removed from element %s", test.attr, test.sel)
if err != nil { }
t.Fatalf("test %d got error: %v", i, err) })
}
if ok || value != "" {
t.Fatalf("test %d expected attribute %s removed from element %s", i, test.attr, test.sel)
}
} }
} }
@ -570,39 +589,39 @@ func TestClick(t *testing.T) {
{"#btn2", ByID}, {"#btn2", ByID},
} }
var err error
for i, test := range tests { for i, test := range tests {
c := testAllocate(t, "form.html") t.Run(fmt.Sprintf("test %d", i), func(t *testing.T) {
defer c.Release() t.Parallel()
err = c.Run(defaultContext, Click(test.sel, test.by)) c := testAllocate(t, "form.html")
if err != nil { defer c.Release()
t.Fatalf("test %d got error: %v", i, err)
}
err = c.Run(defaultContext, WaitVisible("#logo > img", ByQuery)) err := c.Run(defaultContext, Click(test.sel, test.by))
if err != nil { if err != nil {
t.Fatalf("test %d got error: %v", i, err) t.Fatalf("test %d got error: %v", i, err)
} }
var title string err = c.Run(defaultContext, WaitVisible("#logo > img", ByQuery))
err = c.Run(defaultContext, Title(&title)) if err != nil {
if err != nil { t.Fatalf("test %d got error: %v", i, err)
t.Fatalf("test %d got error: %v", i, err) }
}
if title != "chromedp - Google Search" { var title string
t.Errorf("test %d expected title to be 'chromedp - Google Search', got: '%s'", i, title) err = c.Run(defaultContext, Title(&title))
} if err != nil {
t.Fatalf("test %d got error: %v", i, err)
}
if title != "chromedp - Google Search" {
t.Errorf("test %d expected title to be 'chromedp - Google Search', got: '%s'", i, title)
}
})
} }
} }
func TestDoubleClick(t *testing.T) { func TestDoubleClick(t *testing.T) {
c := testAllocate(t, "js.html")
defer c.Release()
tests := []struct { tests := []struct {
sel string sel string
option QueryOption by QueryOption
}{ }{
{`/html/body/input[2]`, BySearch}, {`/html/body/input[2]`, BySearch},
{`body > input[type="button"]:nth-child(2)`, ByQueryAll}, {`body > input[type="button"]:nth-child(2)`, ByQueryAll},
@ -610,29 +629,27 @@ func TestDoubleClick(t *testing.T) {
{`#button1`, ByID}, {`#button1`, ByID},
} }
var err error
for i, test := range tests { for i, test := range tests {
if i != 0 { t.Run(fmt.Sprintf("test %d", i), func(t *testing.T) {
err = c.Run(defaultContext, Reload()) t.Parallel()
c := testAllocate(t, "js.html")
defer c.Release()
err := c.Run(defaultContext, DoubleClick(test.sel, test.by))
if err != nil { if err != nil {
t.Fatalf("test %d got error: %v", i, err) t.Fatalf("got error: %v", err)
} }
time.Sleep(50 * time.Millisecond)
}
err = c.Run(defaultContext, DoubleClick(test.sel, test.option)) var value string
if err != nil { err = c.Run(defaultContext, Value("#input1", &value, ByID))
t.Fatalf("test %d got error: %v", i, err) if err != nil {
} t.Fatalf("got error: %v", err)
}
var value string if value != "1" {
err = c.Run(defaultContext, Value("#input1", &value, ByID)) t.Errorf("expected value to be '1', got: '%s'", value)
if err != nil { }
t.Fatalf("test %d got error: %v", i, err) })
}
if value != "1" {
t.Errorf("test %d expected value to be '1', got: '%s'", i, value)
}
} }
} }
@ -651,34 +668,39 @@ func TestSendKeys(t *testing.T) {
{"#select1", ByID, kb.ArrowDown + kb.ArrowDown, "three"}, {"#select1", ByID, kb.ArrowDown + kb.ArrowDown, "three"},
} }
var err error
for i, test := range tests { for i, test := range tests {
c := testAllocate(t, "visible.html") t.Run(fmt.Sprintf("test %d", i), func(t *testing.T) {
defer c.Release() t.Parallel()
err = c.Run(defaultContext, SendKeys(test.sel, test.keys, test.by)) c := testAllocate(t, "visible.html")
if err != nil { defer c.Release()
t.Fatalf("test %d got error: %v", i, err)
}
var val string err := c.Run(defaultContext, SendKeys(test.sel, test.keys, test.by))
err = c.Run(defaultContext, Value(test.sel, &val, test.by)) if err != nil {
if err != nil { t.Fatalf("test %d got error: %v", i, err)
t.Fatalf("test %d got error: %v", i, err) }
}
if val != test.exp { var val string
t.Errorf("test %d expected value %s, got: %s", i, test.exp, val) err = c.Run(defaultContext, Value(test.sel, &val, test.by))
} if err != nil {
t.Fatalf("test %d got error: %v", i, err)
}
if val != test.exp {
t.Errorf("test %d expected value %s, got: %s", i, test.exp, val)
}
})
} }
} }
func TestScreenshoot(t *testing.T) { func TestScreenshoot(t *testing.T) {
t.Parallel()
c := testAllocate(t, "image.html") c := testAllocate(t, "image.html")
defer c.Release() defer c.Release()
tests := []struct { tests := []struct {
sel string sel string
option QueryOption by QueryOption
}{ }{
{"/html/body/img", BySearch}, {"/html/body/img", BySearch},
{"img", ByQueryAll}, {"img", ByQueryAll},
@ -712,39 +734,39 @@ func TestSubmit(t *testing.T) {
{"#form", ByID}, {"#form", ByID},
} }
var err error
for i, test := range tests { for i, test := range tests {
c := testAllocate(t, "form.html") t.Run(fmt.Sprintf("test %d", i), func(t *testing.T) {
defer c.Release() t.Parallel()
err = c.Run(defaultContext, Submit(test.sel, test.by)) c := testAllocate(t, "form.html")
if err != nil { defer c.Release()
t.Fatalf("test %d got error: %v", i, err)
}
err = c.Run(defaultContext, WaitVisible("#logo > img", ByQuery)) err := c.Run(defaultContext, Submit(test.sel, test.by))
if err != nil { if err != nil {
t.Fatalf("test %d got error: %v", i, err) t.Fatalf("test %d got error: %v", i, err)
} }
var title string err = c.Run(defaultContext, WaitVisible("#logo > img", ByQuery))
err = c.Run(defaultContext, Title(&title)) if err != nil {
if err != nil { t.Fatalf("test %d got error: %v", i, err)
t.Fatalf("test %d got error: %v", i, err) }
}
if title != "chromedp - Google Search" { var title string
t.Errorf("test %d expected title to be 'chromedp - Google Search', got: '%s'", i, title) err = c.Run(defaultContext, Title(&title))
} if err != nil {
t.Fatalf("test %d got error: %v", i, err)
}
if title != "chromedp - Google Search" {
t.Errorf("test %d expected title to be 'chromedp - Google Search', got: '%s'", i, title)
}
})
} }
} }
func TestComputedStyle(t *testing.T) { func TestComputedStyle(t *testing.T) {
c := testAllocate(t, "js.html")
defer c.Release()
tests := []struct { tests := []struct {
sel string sel string
option QueryOption by QueryOption
}{ }{
{`//*[@id="input1"]`, BySearch}, {`//*[@id="input1"]`, BySearch},
{`body > input[type="number"]:nth-child(1)`, ByQueryAll}, {`body > input[type="number"]:nth-child(1)`, ByQueryAll},
@ -752,47 +774,45 @@ func TestComputedStyle(t *testing.T) {
{"#input1", ByID}, {"#input1", ByID},
} }
var err error
for i, test := range tests { for i, test := range tests {
if i != 0 { t.Run(fmt.Sprintf("test %d", i), func(t *testing.T) {
err = c.Run(defaultContext, Reload()) t.Parallel()
c := testAllocate(t, "js.html")
defer c.Release()
var styles []*css.ComputedProperty
err := c.Run(defaultContext, ComputedStyle(test.sel, &styles, test.by))
if err != nil { if err != nil {
t.Fatalf("test %d got error: %v", i, err) t.Fatalf("got error: %v", err)
} }
time.Sleep(50 * time.Millisecond)
}
var styles []*css.ComputedProperty for _, style := range styles {
err = c.Run(defaultContext, ComputedStyle(test.sel, &styles, test.option)) if style.Name == "background-color" {
if err != nil { if style.Value != "rgb(255, 0, 0)" {
t.Fatalf("test %d got error: %v", i, err) t.Logf("expected style 'rgb(255, 0, 0)' got: %s", style.Value)
} }
for _, style := range styles {
if style.Name == "background-color" {
if style.Value != "rgb(255, 0, 0)" {
t.Logf("test %d expected style 'rgb(255, 0, 0)' got: %s", i, style.Value)
} }
} }
}
err = c.Run(defaultContext, Click("#input1", ByID)) err = c.Run(defaultContext, Click("#input1", ByID))
if err != nil { if err != nil {
t.Fatalf("test %d got error: %v", i, err) t.Fatalf("got error: %v", err)
} }
err = c.Run(defaultContext, ComputedStyle(test.sel, &styles, test.option)) err = c.Run(defaultContext, ComputedStyle(test.sel, &styles, test.by))
if err != nil { if err != nil {
t.Fatalf("test %d got error: %v", i, err) t.Fatalf("got error: %v", err)
} }
for _, style := range styles { for _, style := range styles {
if style.Name == "background-color" { if style.Name == "background-color" {
if style.Value != "rgb(255, 255, 0)" { if style.Value != "rgb(255, 255, 0)" {
t.Fatalf("test %d expected style 'rgb(255, 255, 0)' got: %s", i, style.Value) t.Fatalf("expected style 'rgb(255, 255, 0)' got: %s", style.Value)
}
} }
} }
} })
} }
} }