Bug 1448792 - [wdspec] Create global fixture and assert methods for event checks. draft
authorHenrik Skupin <mail@hskupin.info>
Fri, 01 Jun 2018 14:48:14 +0200
changeset 808622 9af3303adcdf46d9e0e881c7ec6381be2e56a56f
parent 808594 941f947558c96261046ba069c1b4ad49f3653709
child 808623 ad540da5a097bf4ecfad0d291650e4432f9693ad
push id113443
push userbmo:hskupin@gmail.com
push dateWed, 20 Jun 2018 07:16:03 +0000
bugs1448792
milestone62.0a1
Bug 1448792 - [wdspec] Create global fixture and assert methods for event checks. A lot of commands will have to check for fired events on the element under test. Having this global fixture and assert method doesn't require a redefinition of the required code. MozReview-Commit-ID: K4jaaU4uHtP
testing/web-platform/meta/MANIFEST.json
testing/web-platform/tests/webdriver/tests/conftest.py
testing/web-platform/tests/webdriver/tests/element_clear/clear.py
testing/web-platform/tests/webdriver/tests/element_send_keys/form_controls.py
testing/web-platform/tests/webdriver/tests/support/asserts.py
testing/web-platform/tests/webdriver/tests/support/fixtures.py
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -618571,17 +618571,17 @@
    "8c22860607cb0f3d610888c9816bf2384e2c5445",
    "wdspec"
   ],
   "webdriver/tests/close_window/user_prompts.py": [
    "58390344e980306233cd0daedca99fd4ec855cf8",
    "wdspec"
   ],
   "webdriver/tests/conftest.py": [
-   "c812269d034c9ca1b8c4f136dd5d0cea52f4d0f0",
+   "21143aabab3474c3786c552d22d3c79512a120c4",
    "support"
   ],
   "webdriver/tests/delete_all_cookies/__init__.py": [
    "da39a3ee5e6b4b0d3255bfef95601890afd80709",
    "support"
   ],
   "webdriver/tests/delete_all_cookies/delete.py": [
    "1248b2e14b6b690b996f8bf620a6a1f33514256a",
@@ -618615,17 +618615,17 @@
    "33b32f41d9078f7d317aed837f1fc05f443bd034",
    "wdspec"
   ],
   "webdriver/tests/element_clear/__init__.py": [
    "da39a3ee5e6b4b0d3255bfef95601890afd80709",
    "support"
   ],
   "webdriver/tests/element_clear/clear.py": [
-   "cb1a5a8cb6568becf776031bca67079b54b53dc5",
+   "aa785499dc4a68650d08c829deef8aa23d073d09",
    "wdspec"
   ],
   "webdriver/tests/element_click/__init__.py": [
    "da39a3ee5e6b4b0d3255bfef95601890afd80709",
    "support"
   ],
   "webdriver/tests/element_click/bubbling.py": [
    "492e283b686abe0743d72e31017be149726628f9",
@@ -618647,17 +618647,17 @@
    "da39a3ee5e6b4b0d3255bfef95601890afd80709",
    "support"
   ],
   "webdriver/tests/element_send_keys/content_editable.py": [
    "9c071e60e1203cf31120f20874b5f38ba41dacc3",
    "wdspec"
   ],
   "webdriver/tests/element_send_keys/form_controls.py": [
-   "7e893a0992efff7bb053ae0707c34c60402f195a",
+   "c628924d912d413c89be38d5e7098bc5aace3d67",
    "wdspec"
   ],
   "webdriver/tests/element_send_keys/interactability.py": [
    "5374827c90845ded660d540d23bb7e07ac84e445",
    "wdspec"
   ],
   "webdriver/tests/element_send_keys/scroll_into_view.py": [
    "e4a50a53a13c1ab76c6c002bbda1c103f8c32ccf",
@@ -618999,21 +618999,21 @@
    "1302349ca7d6a3dcc49e26ca0345023a5c6bbe14",
    "wdspec"
   ],
   "webdriver/tests/support/__init__.py": [
    "5a31a3917a5157516c10951a3b3d5ffb43b992d9",
    "support"
   ],
   "webdriver/tests/support/asserts.py": [
-   "1b839404daaca1d059cba98377edb91691ef7e82",
+   "fad8bdc53e5dc35e016b467b1be6435b5edeb9cb",
    "support"
   ],
   "webdriver/tests/support/fixtures.py": [
-   "2c96ed59d70421875c31757bbfe1182860437bd9",
+   "f1c704ea7b44e08dd63eaac6b5e9a3370e4c0503",
    "support"
   ],
   "webdriver/tests/support/http_request.py": [
    "cb40c781fea2280b98135522def5e6a116d7b946",
    "support"
   ],
   "webdriver/tests/support/inline.py": [
    "48399821b7abca50df824e37c41829d7a4573be1",
--- a/testing/web-platform/tests/webdriver/tests/conftest.py
+++ b/testing/web-platform/tests/webdriver/tests/conftest.py
@@ -1,14 +1,24 @@
 import pytest
 from tests.support.fixtures import (
-    add_browser_capabilites, configuration, create_dialog, create_frame,
-    create_window, http, new_session, server_config, session, url)
+    add_browser_capabilites,
+    add_event_listeners,
+    configuration,
+    create_dialog,
+    create_frame,
+    create_window,
+    http,
+    new_session,
+    server_config,
+    session,
+    url)
 
 pytest.fixture()(add_browser_capabilites)
+pytest.fixture()(add_event_listeners)
 pytest.fixture(scope="session")(configuration)
 pytest.fixture()(create_dialog)
 pytest.fixture()(create_frame)
 pytest.fixture()(create_window)
 pytest.fixture()(http)
 pytest.fixture(scope="function")(new_session)
 pytest.fixture()(server_config)
 pytest.fixture(scope="function")(session)
--- a/testing/web-platform/tests/webdriver/tests/element_clear/clear.py
+++ b/testing/web-platform/tests/webdriver/tests/element_clear/clear.py
@@ -1,44 +1,38 @@
 # META: timeout=long
 
 import pytest
 
 from tests.support.asserts import (
     assert_element_has_focus,
     assert_error,
+    assert_events_equal,
+    assert_in_events,
     assert_success,
 )
 from tests.support.inline import inline
 
 
+@pytest.fixture
+def tracked_events():
+    return [
+        "blur",
+        "change",
+        "focus",
+    ]
+
+
 def element_clear(session, element):
     return session.transport.send(
         "POST", "/session/{session_id}/element/{element_id}/clear".format(
             session_id=session.session_id,
             element_id=element.id))
 
 
-def add_event_listeners(element):
-    element.session.execute_script("""
-        var target = arguments[0];
-        window.events = [];
-        var expectedEvents = ["focus", "blur", "change"];
-        for (var i = 0; i < expectedEvents.length; i++) {
-          target.addEventListener(expectedEvents[i], function (eventObject) {
-            window.events.push(eventObject.type)
-          });
-        }
-        """, args=(element,))
-
-
-def get_events(session):
-    return session.execute_script("return window.events")
-
-
 @pytest.fixture(scope="session")
 def text_file(tmpdir_factory):
     fh = tmpdir_factory.mktemp("tmp").join("hello.txt")
     fh.write("hello")
     return fh
 
 
 def test_null_response_value(session):
@@ -110,29 +104,26 @@ def test_keyboard_interactable(session):
                           ("url", "https://example.com/", ""),
                           ("color", "#ff0000", "#000000"),
                           ("date", "2017-12-26", ""),
                           ("datetime", "2017-12-26T19:48", ""),
                           ("datetime-local", "2017-12-26T19:48", ""),
                           ("time", "19:48", ""),
                           ("month", "2017-11", ""),
                           ("week", "2017-W52", "")])
-def test_input(session, type, value, default):
+def test_input(session, add_event_listeners, tracked_events, type, value, default):
     session.url = inline("<input type=%s value='%s'>" % (type, value))
     element = session.find.css("input", all=False)
-    add_event_listeners(element)
+    add_event_listeners(element, tracked_events)
     assert element.property("value") == value
 
     response = element_clear(session, element)
     assert_success(response)
     assert element.property("value") == default
-    events = get_events(session)
-    assert "focus" in events
-    assert "change" in events
-    assert "blur" in events
+    assert_in_events(session, ["focus", "change", "blur"])
     assert_element_has_focus(session.execute_script("return document.body"))
 
 
 @pytest.mark.parametrize("type",
                          ["number",
                           "range",
                           "email",
                           "password",
@@ -176,29 +167,26 @@ def test_input_disabled(session, type):
 def test_input_readonly(session, type):
     session.url = inline("<input type=%s readonly>" % type)
     element = session.find.css("input", all=False)
 
     response = element_clear(session, element)
     assert_error(response, "invalid element state")
 
 
-def test_textarea(session):
+def test_textarea(session, add_event_listeners, tracked_events):
     session.url = inline("<textarea>foobar</textarea>")
     element = session.find.css("textarea", all=False)
-    add_event_listeners(element)
+    add_event_listeners(element, tracked_events)
     assert element.property("value") == "foobar"
 
     response = element_clear(session, element)
     assert_success(response)
     assert element.property("value") == ""
-    events = get_events(session)
-    assert "focus" in events
-    assert "change" in events
-    assert "blur" in events
+    assert_in_events(session, ["focus", "change", "blur"])
 
 
 def test_textarea_disabled(session):
     session.url = inline("<textarea disabled></textarea>")
     element = session.find.css("textarea", all=False)
 
     response = element_clear(session, element)
     assert_error(response, "invalid element state")
@@ -268,51 +256,51 @@ def test_button_with_subtree(session):
         </button>
         """)
     text_field = session.find.css("input", all=False)
 
     response = element_clear(session, text_field)
     assert_error(response, "element not interactable")
 
 
-def test_contenteditable(session):
+def test_contenteditable(session, add_event_listeners, tracked_events):
     session.url = inline("<p contenteditable>foobar</p>")
     element = session.find.css("p", all=False)
-    add_event_listeners(element)
+    add_event_listeners(element, tracked_events)
     assert element.property("innerHTML") == "foobar"
 
     response = element_clear(session, element)
     assert_success(response)
     assert element.property("innerHTML") == ""
-    assert get_events(session) == ["focus", "change", "blur"]
+    assert_events_equal(session, ["focus", "change", "blur"])
     assert_element_has_focus(session.execute_script("return document.body"))
 
 
 def test_designmode(session):
     session.url = inline("foobar")
     element = session.find.css("body", all=False)
     assert element.property("innerHTML") == "foobar"
     session.execute_script("document.designMode = 'on'")
 
     response = element_clear(session, element)
     assert_success(response)
     assert element.property("innerHTML") == "<br>"
     assert_element_has_focus(session.execute_script("return document.body"))
 
 
-def test_resettable_element_focus_when_empty(session):
+def test_resettable_element_focus_when_empty(session, add_event_listeners, tracked_events):
     session.url = inline("<input>")
     element = session.find.css("input", all=False)
-    add_event_listeners(element)
+    add_event_listeners(element, tracked_events)
     assert element.property("value") == ""
 
     response = element_clear(session, element)
     assert_success(response)
     assert element.property("value") == ""
-    assert get_events(session) == []
+    assert_events_equal(session, [])
 
 
 @pytest.mark.parametrize("type,invalid_value",
                          [("number", "foo"),
                           ("range", "foo"),
                           ("email", "foo"),
                           ("url", "foo"),
                           ("color", "foo"),
--- a/testing/web-platform/tests/webdriver/tests/element_send_keys/form_controls.py
+++ b/testing/web-platform/tests/webdriver/tests/element_send_keys/form_controls.py
@@ -1,41 +1,33 @@
 import pytest
 
-from tests.support.asserts import (
-    assert_element_has_focus,
-    assert_error,
-    assert_same_element,
-    assert_success,
-)
+from tests.support.asserts import assert_element_has_focus, assert_events_equal
 from tests.support.inline import inline
 
+@pytest.fixture
+def tracked_events():
+    return [
+            "blur",
+            "change",
+            "focus",
+            "input",
+            "keydown",
+            "keypress",
+            "keyup",
+            ]
 
 def element_send_keys(session, element, text):
     return session.transport.send(
         "POST", "/session/{session_id}/element/{element_id}/value".format(
             session_id=session.session_id,
             element_id=element.id),
         {"text": text})
 
 
-def add_event_listeners(element):
-    element.session.execute_script("""
-        window.events = [];
-        var trackedEvents = ["focus", "change", "keypress", "keydown", "keyup", "input"];
-        for (var i = 0; i < trackedEvents.length; i++) {
-          arguments[0].addEventListener(trackedEvents[i], function(eventObject) { window.events.push(eventObject.type) });
-        }
-        """, args=(element,))
-
-
-def get_events(session):
-    return session.execute_script("return window.events")
-
-
 def test_input(session):
     session.url = inline("<input>")
     element = session.find.css("input", all=False)
     assert element.property("value") == ""
 
     element_send_keys(session, element, "foo")
     assert element.property("value") == "foo"
     assert_element_has_focus(element)
@@ -71,36 +63,40 @@ def test_textarea_append(session):
     element_send_keys(session, element, "b")
     assert element.property("value") == "ab"
 
     element_send_keys(session, element, "c")
     assert element.property("value") == "abc"
 
 
 @pytest.mark.parametrize("tag", ["input", "textarea"])
-def test_events(session, tag):
+def test_events(session, add_event_listeners, tracked_events, tag):
+    expected_events = [
+        "focus",
+        "keydown",
+        "keypress",
+        "input",
+        "keyup",
+        "keydown",
+        "keypress",
+        "input",
+        "keyup",
+        "keydown",
+        "keypress",
+        "input",
+        "keyup",
+    ]
+
     session.url = inline("<%s>" % tag)
     element = session.find.css(tag, all=False)
-    add_event_listeners(element)
+    add_event_listeners(element, tracked_events)
 
     element_send_keys(session, element, "foo")
     assert element.property("value") == "foo"
-    assert get_events(session) == ["focus",
-                                   "keydown",
-                                   "keypress",
-                                   "input",
-                                   "keyup",
-                                   "keydown",
-                                   "keypress",
-                                   "input",
-                                   "keyup",
-                                   "keydown",
-                                   "keypress",
-                                   "input",
-                                   "keyup"]
+    assert_events_equal(session, expected_events)
 
 
 @pytest.mark.parametrize("tag", ["input", "textarea"])
 def test_not_blurred(session, tag):
     session.url = inline("<%s>" % tag)
     element = session.find.css(tag, all=False)
 
     element_send_keys(session, element, "")
--- a/testing/web-platform/tests/webdriver/tests/support/asserts.py
+++ b/testing/web-platform/tests/webdriver/tests/support/asserts.py
@@ -134,16 +134,27 @@ def assert_same_element(session, a, b):
         b_markup = session.execute_script("return arguments[0].outerHTML;", args=(b,))
         message += " Actual: `%s`. Expected: `%s`." % (a_markup, b_markup)
     except WebDriverException:
         pass
 
     raise AssertionError(message)
 
 
+def assert_in_events(session, expected_events):
+    actual_events = session.execute_script("return window.events")
+    for expected_event in expected_events:
+        assert expected_event in actual_events
+
+
+def assert_events_equal(session, expected_events):
+    actual_events = session.execute_script("return window.events")
+    assert actual_events == expected_events
+
+
 def assert_element_has_focus(target_element):
     session = target_element.session
 
     active_element = session.execute_script("return document.activeElement")
     active_tag = active_element.property("localName")
     target_tag = target_element.property("localName")
 
     assert active_element == target_element, (
--- a/testing/web-platform/tests/webdriver/tests/support/fixtures.py
+++ b/testing/web-platform/tests/webdriver/tests/support/fixtures.py
@@ -102,16 +102,36 @@ def _windows(session, exclude=None):
     provided.
     """
     if exclude is None:
         exclude = []
     wins = [w for w in session.handles if w not in exclude]
     return set(wins)
 
 
+def add_event_listeners(session):
+    """Register listeners for tracked events on element."""
+    def add_event_listeners(element, tracked_events):
+        element.session.execute_script("""
+            let element = arguments[0];
+            let trackedEvents = arguments[1];
+
+            if (!("events" in window)) {
+              window.events = [];
+            }
+
+            for (var i = 0; i < trackedEvents.length; i++) {
+              element.addEventListener(trackedEvents[i], function (event) {
+                window.events.push(event.type);
+              });
+            }
+            """, args=(element, tracked_events))
+    return add_event_listeners
+
+
 def create_frame(session):
     """Create an `iframe` element in the current browsing context and insert it
     into the document. Return a reference to the newly-created element."""
     def create_frame():
         append = """
             var frame = document.createElement('iframe');
             document.body.appendChild(frame);
             return frame;