chromedp/input_test.go
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

294 lines
6.7 KiB
Go

package chromedp
import (
"fmt"
"strconv"
"testing"
"time"
"github.com/chromedp/cdproto/cdp"
"github.com/chromedp/cdproto/input"
)
const (
// inViewportJS is a javascript snippet that will get the specified node
// position relative to the viewport and returns true if the specified node
// is within the window's viewport.
inViewportJS = `(function(a) {
var r = a[0].getBoundingClientRect();
return r.top >= 0 && r.left >= 0 && r.bottom <= window.innerHeight && r.right <= window.innerWidth;
})($x('%s'))`
)
func TestMouseClickXY(t *testing.T) {
t.Parallel()
var err error
c := testAllocate(t, "input.html")
defer c.Release()
err = c.Run(defaultContext, Sleep(100*time.Millisecond))
if err != nil {
t.Fatal(err)
}
tests := []struct {
x, y int64
}{
{100, 100},
{0, 0},
{9999, 100},
{100, 9999},
}
for i, test := range tests {
err = c.Run(defaultContext, MouseClickXY(test.x, test.y))
if err != nil {
t.Fatalf("test %d got error: %v", i, err)
}
time.Sleep(50 * time.Millisecond)
var xstr, ystr string
err = c.Run(defaultContext, Value("#input1", &xstr, ByID))
if err != nil {
t.Fatalf("test %d got error: %v", i, err)
}
x, err := strconv.ParseInt(xstr, 10, 64)
if err != nil {
t.Fatalf("test %d got error: %v", i, err)
}
if x != test.x {
t.Fatalf("test %d expected x to be: %d, got: %d", i, test.x, x)
}
err = c.Run(defaultContext, Value("#input2", &ystr, ByID))
if err != nil {
t.Fatalf("test %d got error: %v", i, err)
}
y, err := strconv.ParseInt(ystr, 10, 64)
if err != nil {
t.Fatalf("test %d got error: %v", i, err)
}
if y != test.y {
t.Fatalf("test %d expected y to be: %d, got: %d", i, test.y, y)
}
}
}
func TestMouseClickNode(t *testing.T) {
t.Parallel()
tests := []struct {
sel, exp string
opt MouseOption
by QueryOption
}{
{"button2", "foo", ButtonType(input.ButtonNone), ByID},
{"button2", "bar", ButtonType(input.ButtonLeft), ByID},
{"button2", "bar-middle", ButtonType(input.ButtonMiddle), ByID},
{"input3", "bar-right", ButtonType(input.ButtonRight), ByID},
{"input3", "bar-right", ButtonModifiers(input.ModifierNone), ByID},
{"input3", "bar-right", Button("right"), ByID},
}
for i, test := range tests {
t.Run(fmt.Sprintf("test %d", i), func(t *testing.T) {
t.Parallel()
c := testAllocate(t, "input.html")
defer c.Release()
var err error
var nodes []*cdp.Node
err = c.Run(defaultContext, Nodes(test.sel, &nodes, test.by))
if err != nil {
t.Fatalf("got error: %v", err)
}
if len(nodes) != 1 {
t.Fatalf("expected nodes to have exactly 1 element, got: %d", len(nodes))
}
err = c.Run(defaultContext, MouseClickNode(nodes[0], test.opt))
if err != nil {
t.Fatalf("got error: %v", err)
}
time.Sleep(50 * time.Millisecond)
var value string
err = c.Run(defaultContext, Value("#input3", &value, ByID))
if err != nil {
t.Fatalf("got error: %v", err)
}
if value != test.exp {
t.Fatalf("expected to have value %s, got: %s", test.exp, value)
}
})
}
}
func TestMouseClickOffscreenNode(t *testing.T) {
t.Parallel()
tests := []struct {
sel string
exp int
by QueryOption
}{
{"#button3", 0, ByID},
{"#button3", 2, ByID},
{"#button3", 10, ByID},
}
for i, test := range tests {
t.Run(fmt.Sprintf("test %d", i), func(t *testing.T) {
t.Parallel()
c := testAllocate(t, "input.html")
defer c.Release()
var err error
var nodes []*cdp.Node
err = c.Run(defaultContext, Nodes(test.sel, &nodes, test.by))
if err != nil {
t.Fatalf("got error: %v", err)
}
if len(nodes) != 1 {
t.Fatalf("expected nodes to have exactly 1 element, got: %d", len(nodes))
}
var ok bool
err = c.Run(defaultContext, EvaluateAsDevTools(fmt.Sprintf(inViewportJS, nodes[0].FullXPath()), &ok))
if err != nil {
t.Fatalf("got error: %v", err)
}
if ok {
t.Fatal("expected node to be offscreen")
}
for i := test.exp; i > 0; i-- {
err = c.Run(defaultContext, MouseClickNode(nodes[0]))
if err != nil {
t.Fatalf("got error: %v", err)
}
}
time.Sleep(100 * time.Millisecond)
var value int
err = c.Run(defaultContext, Evaluate("window.document.test_i", &value))
if err != nil {
t.Fatalf("got error: %v", err)
}
if value != test.exp {
t.Fatalf("expected to have value %d, got: %d", test.exp, value)
}
})
}
}
func TestKeyAction(t *testing.T) {
t.Parallel()
tests := []struct {
sel, exp string
by QueryOption
}{
{"#input4", "foo", ByID},
{"#input4", "foo and bar", ByID},
{"#input4", "1234567890", ByID},
{"#input4", "~!@#$%^&*()_+=[];'", ByID},
{"#input4", "你", ByID},
{"#input4", "\n\nfoo\n\nbar\n\n", ByID},
}
for i, test := range tests {
t.Run(fmt.Sprintf("test %d", i), func(t *testing.T) {
t.Parallel()
c := testAllocate(t, "input.html")
defer c.Release()
var err error
var nodes []*cdp.Node
err = c.Run(defaultContext, Nodes(test.sel, &nodes, test.by))
if err != nil {
t.Fatalf("got error: %v", err)
}
if len(nodes) != 1 {
t.Fatalf("expected nodes to have exactly 1 element, got: %d", len(nodes))
}
err = c.Run(defaultContext, Focus(test.sel, test.by))
if err != nil {
t.Fatalf("got error: %v", err)
}
err = c.Run(defaultContext, KeyAction(test.exp))
if err != nil {
t.Fatalf("got error: %v", err)
}
var value string
err = c.Run(defaultContext, Value(test.sel, &value, test.by))
if err != nil {
t.Fatalf("got error: %v", err)
}
if value != test.exp {
t.Fatalf("expected to have value %s, got: %s", test.exp, value)
}
})
}
}
func TestKeyActionNode(t *testing.T) {
t.Parallel()
tests := []struct {
sel, exp string
by QueryOption
}{
{"#input4", "foo", ByID},
{"#input4", "foo and bar", ByID},
{"#input4", "1234567890", ByID},
{"#input4", "~!@#$%^&*()_+=[];'", ByID},
{"#input4", "你", ByID},
{"#input4", "\n\nfoo\n\nbar\n\n", ByID},
}
for i, test := range tests {
t.Run(fmt.Sprintf("test %d", i), func(t *testing.T) {
t.Parallel()
c := testAllocate(t, "input.html")
defer c.Release()
var err error
var nodes []*cdp.Node
err = c.Run(defaultContext, Nodes(test.sel, &nodes, test.by))
if err != nil {
t.Fatalf("got error: %v", err)
}
if len(nodes) != 1 {
t.Fatalf("expected nodes to have exactly 1 element, got: %d", len(nodes))
}
err = c.Run(defaultContext, KeyActionNode(nodes[0], test.exp))
if err != nil {
t.Fatalf("got error: %v", err)
}
var value string
err = c.Run(defaultContext, Value(test.sel, &value, test.by))
if err != nil {
t.Fatalf("got error: %v", err)
}
if value != test.exp {
t.Fatalf("expected to have value %s, got: %s", test.exp, value)
}
})
}
}