From d3ef975bdb93712fc152b4719300e19a84c6769f Mon Sep 17 00:00:00 2001 From: Zeke Lu Date: Sun, 16 May 2021 09:24:00 +0800 Subject: [PATCH] dispatch input and change events at the SetValue() target (#819) chromedp.SetValue is supposed to be called against input, textarea and select. For these kind of elements, dispatching input and change events after their values are changed is required. The document says chromedp.SetValue supports other elements with a .value field. The input and change events will be fired for those elements too. But I'm not ware of such an element, so there is not unit test to cover this case. --- js.go | 7 ++++++- query_test.go | 16 ++++++++++++++++ testdata/form.html | 14 ++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/js.go b/js.go index 05e26a73..9d106221 100644 --- a/js.go +++ b/js.go @@ -78,7 +78,12 @@ const ( // setAttributeJS is a javascript snippet that sets the value of the specified // node, and returns the value. setAttributeJS = `(function(a, n, v) { - return a[n] = v; + a[n] = v; + if (n === 'value') { + a.dispatchEvent(new Event('input', { bubbles: true })); + a.dispatchEvent(new Event('change', { bubbles: true })); + } + return a[n]; })(%s, %q, %q)` // visibleJS is a javascript snippet that returns true or false depending on if diff --git a/query_test.go b/query_test.go index 0a30873a..4495ecd0 100644 --- a/query_test.go +++ b/query_test.go @@ -2,6 +2,8 @@ package chromedp import ( "bytes" + "context" + "errors" "fmt" "image/png" "io/ioutil" @@ -557,6 +559,7 @@ func TestSetValue(t *testing.T) { {`#form > input[type="text"]`, ByQueryAll}, {`#bar`, ByID}, {`document.querySelector("#bar")`, ByJSPath}, + {`#select`, ByQuery}, } for i, test := range tests { @@ -578,6 +581,19 @@ func TestSetValue(t *testing.T) { if value != "FOOBAR" { t.Errorf("expected `FOOBAR`, got: %s", value) } + + ctx, cancel = context.WithTimeout(ctx, 2*time.Second) + defer cancel() + if err := Run(ctx, + WaitVisible("#event-input", ByQuery), + WaitVisible("#event-change", ByQuery), + ); err != nil { + if errors.Is(err, context.DeadlineExceeded) { + t.Fatal("input and/or change events not fired") + } else { + t.Fatalf("got error: %v", err) + } + } }) } } diff --git a/testdata/form.html b/testdata/form.html index fc1e5ce7..694cb5e3 100644 --- a/testdata/form.html +++ b/testdata/form.html @@ -16,8 +16,22 @@
+

this is hidden

+ + +