2017-02-23 08:23:37 +00:00
|
|
|
package chromedp
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"strconv"
|
|
|
|
"testing"
|
|
|
|
|
2017-12-27 02:30:28 +00:00
|
|
|
"github.com/chromedp/cdproto/cdp"
|
|
|
|
"github.com/chromedp/cdproto/input"
|
2017-02-23 08:23:37 +00:00
|
|
|
)
|
|
|
|
|
2019-04-06 19:58:54 +00:00
|
|
|
// 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.
|
|
|
|
const inViewportJS = `(function(a) {
|
2017-02-28 01:35:00 +00:00
|
|
|
var r = a[0].getBoundingClientRect();
|
|
|
|
return r.top >= 0 && r.left >= 0 && r.bottom <= window.innerHeight && r.right <= window.innerWidth;
|
|
|
|
})($x('%s'))`
|
|
|
|
|
2017-02-23 08:23:37 +00:00
|
|
|
func TestMouseClickXY(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
2019-03-05 13:14:50 +00:00
|
|
|
ctx, cancel := testAllocate(t, "input.html")
|
|
|
|
defer cancel()
|
2019-03-20 17:27:57 +00:00
|
|
|
|
|
|
|
if err := Run(ctx, WaitVisible(`#input1`, ByID)); err != nil {
|
2017-02-23 08:23:37 +00:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
tests := []struct {
|
|
|
|
x, y int64
|
|
|
|
}{
|
|
|
|
{100, 100},
|
|
|
|
{0, 0},
|
|
|
|
{9999, 100},
|
|
|
|
{100, 9999},
|
|
|
|
}
|
|
|
|
|
|
|
|
for i, test := range tests {
|
2017-02-25 07:34:53 +00:00
|
|
|
var xstr, ystr string
|
2019-04-01 18:46:47 +00:00
|
|
|
if err := Run(ctx,
|
|
|
|
MouseClickXY(test.x, test.y),
|
|
|
|
Value("#input1", &xstr, ByID),
|
|
|
|
); err != nil {
|
2017-02-23 08:23:37 +00:00
|
|
|
t.Fatalf("test %d got error: %v", i, err)
|
|
|
|
}
|
2019-03-05 13:14:50 +00:00
|
|
|
|
2017-02-25 07:34:53 +00:00
|
|
|
x, err := strconv.ParseInt(xstr, 10, 64)
|
2017-02-23 08:23:37 +00:00
|
|
|
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)
|
|
|
|
}
|
2019-03-05 13:14:50 +00:00
|
|
|
if err := Run(ctx, Value("#input2", &ystr, ByID)); err != nil {
|
2017-02-23 08:23:37 +00:00
|
|
|
t.Fatalf("test %d got error: %v", i, err)
|
|
|
|
}
|
2019-03-05 13:14:50 +00:00
|
|
|
|
2017-02-25 07:34:53 +00:00
|
|
|
y, err := strconv.ParseInt(ystr, 10, 64)
|
2017-02-23 08:23:37 +00:00
|
|
|
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) {
|
2019-02-21 12:55:21 +00:00
|
|
|
t.Parallel()
|
|
|
|
|
2017-02-23 08:23:37 +00:00
|
|
|
tests := []struct {
|
2017-02-25 07:34:53 +00:00
|
|
|
sel, exp string
|
|
|
|
opt MouseOption
|
|
|
|
by QueryOption
|
2017-02-23 08:23:37 +00:00
|
|
|
}{
|
2017-02-25 07:34:53 +00:00
|
|
|
{"button2", "foo", ButtonType(input.ButtonNone), ByID},
|
|
|
|
{"button2", "bar", ButtonType(input.ButtonLeft), ByID},
|
|
|
|
{"button2", "bar-middle", ButtonType(input.ButtonMiddle), ByID},
|
2019-04-01 15:48:49 +00:00
|
|
|
{"input3", "foo", ButtonModifiers(input.ModifierNone), ByID},
|
2017-02-25 07:34:53 +00:00
|
|
|
{"input3", "bar-right", ButtonType(input.ButtonRight), ByID},
|
|
|
|
{"input3", "bar-right", Button("right"), ByID},
|
2017-02-23 08:23:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for i, test := range tests {
|
2019-04-01 18:58:01 +00:00
|
|
|
t.Run(fmt.Sprintf("%02d", i), func(t *testing.T) {
|
2019-04-01 15:48:49 +00:00
|
|
|
test := test
|
2017-02-23 08:23:37 +00:00
|
|
|
t.Parallel()
|
|
|
|
|
2019-03-05 13:14:50 +00:00
|
|
|
ctx, cancel := testAllocate(t, "input.html")
|
|
|
|
defer cancel()
|
2017-02-23 08:23:37 +00:00
|
|
|
|
|
|
|
var nodes []*cdp.Node
|
2019-03-05 13:14:50 +00:00
|
|
|
if err := Run(ctx, Nodes(test.sel, &nodes, test.by)); err != nil {
|
2017-02-23 08:23:37 +00:00
|
|
|
t.Fatalf("got error: %v", err)
|
|
|
|
}
|
|
|
|
if len(nodes) != 1 {
|
|
|
|
t.Fatalf("expected nodes to have exactly 1 element, got: %d", len(nodes))
|
|
|
|
}
|
|
|
|
var value string
|
2019-04-01 18:46:47 +00:00
|
|
|
if err := Run(ctx,
|
|
|
|
MouseClickNode(nodes[0], test.opt),
|
|
|
|
Value("#input3", &value, ByID),
|
|
|
|
); err != nil {
|
2017-02-23 08:23:37 +00:00
|
|
|
t.Fatalf("got error: %v", err)
|
|
|
|
}
|
2019-03-05 13:14:50 +00:00
|
|
|
|
2017-02-23 08:23:37 +00:00
|
|
|
if value != test.exp {
|
|
|
|
t.Fatalf("expected to have value %s, got: %s", test.exp, value)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestMouseClickOffscreenNode(t *testing.T) {
|
2019-02-21 12:55:21 +00:00
|
|
|
t.Parallel()
|
|
|
|
|
2017-02-23 08:23:37 +00:00
|
|
|
tests := []struct {
|
|
|
|
sel string
|
|
|
|
exp int
|
|
|
|
by QueryOption
|
|
|
|
}{
|
|
|
|
{"#button3", 0, ByID},
|
|
|
|
{"#button3", 2, ByID},
|
|
|
|
{"#button3", 10, ByID},
|
|
|
|
}
|
|
|
|
|
|
|
|
for i, test := range tests {
|
2019-04-01 18:58:01 +00:00
|
|
|
t.Run(fmt.Sprintf("%02d", i), func(t *testing.T) {
|
2019-04-01 15:48:49 +00:00
|
|
|
test := test
|
2017-02-23 08:23:37 +00:00
|
|
|
t.Parallel()
|
|
|
|
|
2019-03-05 13:14:50 +00:00
|
|
|
ctx, cancel := testAllocate(t, "input.html")
|
|
|
|
defer cancel()
|
2017-02-23 08:23:37 +00:00
|
|
|
|
|
|
|
var nodes []*cdp.Node
|
2019-03-05 13:14:50 +00:00
|
|
|
if err := Run(ctx, Nodes(test.sel, &nodes, test.by)); err != nil {
|
2017-02-23 08:23:37 +00:00
|
|
|
t.Fatalf("got error: %v", err)
|
|
|
|
}
|
2019-03-05 13:14:50 +00:00
|
|
|
|
2017-02-23 08:23:37 +00:00
|
|
|
if len(nodes) != 1 {
|
|
|
|
t.Fatalf("expected nodes to have exactly 1 element, got: %d", len(nodes))
|
|
|
|
}
|
|
|
|
|
2017-02-25 07:34:53 +00:00
|
|
|
var ok bool
|
2019-03-05 13:14:50 +00:00
|
|
|
if err := Run(ctx, EvaluateAsDevTools(fmt.Sprintf(inViewportJS, nodes[0].FullXPath()), &ok)); err != nil {
|
2017-02-25 07:34:53 +00:00
|
|
|
t.Fatalf("got error: %v", err)
|
|
|
|
}
|
2019-03-05 13:14:50 +00:00
|
|
|
|
2017-02-25 07:34:53 +00:00
|
|
|
if ok {
|
|
|
|
t.Fatal("expected node to be offscreen")
|
|
|
|
}
|
|
|
|
|
2017-02-23 08:23:37 +00:00
|
|
|
for i := test.exp; i > 0; i-- {
|
2019-03-05 13:14:50 +00:00
|
|
|
if err := Run(ctx, MouseClickNode(nodes[0])); err != nil {
|
2017-02-23 08:23:37 +00:00
|
|
|
t.Fatalf("got error: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var value int
|
2019-03-05 13:14:50 +00:00
|
|
|
if err := Run(ctx, Evaluate("window.document.test_i", &value)); err != nil {
|
2017-02-23 08:23:37 +00:00
|
|
|
t.Fatalf("got error: %v", err)
|
|
|
|
}
|
2019-03-05 13:14:50 +00:00
|
|
|
|
2017-02-23 08:23:37 +00:00
|
|
|
if value != test.exp {
|
|
|
|
t.Fatalf("expected to have value %d, got: %d", test.exp, value)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestKeyAction(t *testing.T) {
|
2019-02-21 12:55:21 +00:00
|
|
|
t.Parallel()
|
|
|
|
|
2017-02-23 08:23:37 +00:00
|
|
|
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 {
|
2019-04-01 18:58:01 +00:00
|
|
|
t.Run(fmt.Sprintf("%02d", i), func(t *testing.T) {
|
2019-04-01 15:48:49 +00:00
|
|
|
test := test
|
2017-02-23 08:23:37 +00:00
|
|
|
t.Parallel()
|
|
|
|
|
2019-03-05 13:14:50 +00:00
|
|
|
ctx, cancel := testAllocate(t, "input.html")
|
|
|
|
defer cancel()
|
2017-02-23 08:23:37 +00:00
|
|
|
|
|
|
|
var nodes []*cdp.Node
|
2019-03-05 13:14:50 +00:00
|
|
|
if err := Run(ctx, Nodes(test.sel, &nodes, test.by)); err != nil {
|
2017-02-23 08:23:37 +00:00
|
|
|
t.Fatalf("got error: %v", err)
|
|
|
|
}
|
2019-03-05 13:14:50 +00:00
|
|
|
|
2017-02-23 08:23:37 +00:00
|
|
|
if len(nodes) != 1 {
|
|
|
|
t.Fatalf("expected nodes to have exactly 1 element, got: %d", len(nodes))
|
|
|
|
}
|
2019-04-01 18:46:47 +00:00
|
|
|
if err := Run(ctx,
|
|
|
|
Focus(test.sel, test.by),
|
|
|
|
KeyAction(test.exp),
|
|
|
|
); err != nil {
|
2017-02-23 08:23:37 +00:00
|
|
|
t.Fatalf("got error: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
var value string
|
2019-03-05 13:14:50 +00:00
|
|
|
if err := Run(ctx, Value(test.sel, &value, test.by)); err != nil {
|
2017-02-23 08:23:37 +00:00
|
|
|
t.Fatalf("got error: %v", err)
|
|
|
|
}
|
2019-03-05 13:14:50 +00:00
|
|
|
|
2017-02-23 08:23:37 +00:00
|
|
|
if value != test.exp {
|
|
|
|
t.Fatalf("expected to have value %s, got: %s", test.exp, value)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestKeyActionNode(t *testing.T) {
|
2019-02-21 12:55:21 +00:00
|
|
|
t.Parallel()
|
|
|
|
|
2017-02-23 08:23:37 +00:00
|
|
|
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 {
|
2019-04-01 18:58:01 +00:00
|
|
|
t.Run(fmt.Sprintf("%02d", i), func(t *testing.T) {
|
2019-04-01 15:48:49 +00:00
|
|
|
test := test
|
2017-02-23 08:23:37 +00:00
|
|
|
t.Parallel()
|
|
|
|
|
2019-03-05 13:14:50 +00:00
|
|
|
ctx, cancel := testAllocate(t, "input.html")
|
|
|
|
defer cancel()
|
2017-02-23 08:23:37 +00:00
|
|
|
|
|
|
|
var nodes []*cdp.Node
|
2019-03-05 13:14:50 +00:00
|
|
|
if err := Run(ctx, Nodes(test.sel, &nodes, test.by)); err != nil {
|
2017-02-23 08:23:37 +00:00
|
|
|
t.Fatalf("got error: %v", err)
|
|
|
|
}
|
2019-03-05 13:14:50 +00:00
|
|
|
|
2017-02-23 08:23:37 +00:00
|
|
|
if len(nodes) != 1 {
|
|
|
|
t.Fatalf("expected nodes to have exactly 1 element, got: %d", len(nodes))
|
|
|
|
}
|
|
|
|
var value string
|
2019-04-01 18:46:47 +00:00
|
|
|
if err := Run(ctx,
|
|
|
|
KeyActionNode(nodes[0], test.exp),
|
|
|
|
Value(test.sel, &value, test.by),
|
|
|
|
); err != nil {
|
2017-02-23 08:23:37 +00:00
|
|
|
t.Fatalf("got error: %v", err)
|
|
|
|
}
|
2019-03-05 13:14:50 +00:00
|
|
|
|
2017-02-23 08:23:37 +00:00
|
|
|
if value != test.exp {
|
|
|
|
t.Fatalf("expected to have value %s, got: %s", test.exp, value)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|