Bug 1420431 - Return no such element error when on no active element. r?maja_zf draft
authorAndreas Tolfsen <ato@sny.no>
Fri, 24 Nov 2017 16:23:02 +0000
changeset 703206 1b472804e1df70257e848bd37297850f3a9bff9c
parent 703205 249b4c6672960aa75e917d657d60ba73c3fef643
child 741706 b0cdb5e24460c893827a036d0177f7d4c295a12b
push id90749
push userbmo:ato@sny.no
push dateFri, 24 Nov 2017 16:24:10 +0000
reviewersmaja_zf
bugs1420431
milestone59.0a1
Bug 1420431 - Return no such element error when on no active element. r?maja_zf document.activeElement will return null if there is no document element. This may happen if, for example, in an HTML document the <body> element is removed. The WPT test test_sucess_without_body in get_active_element.py is wrong. It expects Get Active Element to return null if there is no document element, but following a recent specification change we want it to return a no such element error. Specification change: https://github.com/w3c/webdriver/pull/1157 MozReview-Commit-ID: LQJ3slV9aty
testing/marionette/driver.js
testing/marionette/listener.js
testing/web-platform/meta/MANIFEST.json
testing/web-platform/meta/webdriver/tests/element_retrieval/get_active_element.py.ini
testing/web-platform/tests/webdriver/tests/element_retrieval/get_active_element.py
--- a/testing/marionette/driver.js
+++ b/testing/marionette/driver.js
@@ -2148,27 +2148,31 @@ GeckoDriver.prototype.findElements = asy
 
     case Context.Content:
       resp.body = await this.listener.findElementsContent(using, value, opts);
       break;
   }
 };
 
 /**
- * Return the active element on the page.
+ * Return the active element in the document.
  *
  * @return {WebElement}
- *     Active element of the current browsing context's document element.
+ *     Active element of the current browsing context's document
+ *     element, if the document element is non-null.
  *
  * @throws {UnsupportedOperationError}
  *     Not available in current context.
  * @throws {NoSuchWindowError}
  *     Top-level browsing context has been discarded.
  * @throws {UnexpectedAlertOpenError}
  *     A modal dialog is open, blocking this operation.
+ * @throws {NoSuchElementError}
+ *     If the document does not have an active element, i.e. if
+ *     its document element has been deleted.
  */
 GeckoDriver.prototype.getActiveElement = async function() {
   assert.content(this.context);
   assert.window(this.getCurrentWindow());
   this._assertAndDismissModal();
 
   return this.listener.getActiveElement();
 };
--- a/testing/marionette/listener.js
+++ b/testing/marionette/listener.js
@@ -1269,19 +1269,32 @@ async function findElementsContent(strat
   }
 
   opts.all = true;
   let els = await element.find(curContainer, strategy, selector, opts);
   let webEls = seenEls.addAll(els);
   return webEls;
 }
 
-/** Find and return the active element on the page. */
+/**
+ * Return the active element in the document.
+ *
+ * @return {WebElement}
+ *     Active element of the current browsing context's document
+ *     element, if the document element is non-null.
+ *
+ * @throws {NoSuchElementError}
+ *     If the document does not have an active element, i.e. if
+ *     its document element has been deleted.
+ */
 function getActiveElement() {
   let el = curContainer.frame.document.activeElement;
+  if (!el) {
+    throw new NoSuchElementError();
+  }
   return evaluate.toJSON(el, seenEls);
 }
 
 /**
  * Send click event to element.
  *
  * @param {number} commandID
  *     ID of the currently handled message between the driver and
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -575978,17 +575978,17 @@
    "5ba51b660c7203bba3ada597c2f56fe094358e1f",
    "wdspec"
   ],
   "webdriver/tests/element_click/stale.py": [
    "37af63203540dfe11d36fe05d74694f05c6505f2",
    "wdspec"
   ],
   "webdriver/tests/element_retrieval/get_active_element.py": [
-   "74bb0beec41ab857f6814d47191f29065a536802",
+   "918c6e48047f31a088ec44e9b0d070b0ae3d6077",
    "wdspec"
   ],
   "webdriver/tests/fullscreen_window.py": [
    "817011a8cdff7cfd7e445fb8ecb84e5d91f03993",
    "wdspec"
   ],
   "webdriver/tests/get_window_rect.py": [
    "5d907b2a16b9ff7dba8e39bba19ea7f85f29f71e",
@@ -576118,33 +576118,33 @@
    "5a31a3917a5157516c10951a3b3d5ffb43b992d9",
    "support"
   ],
   "webdriver/tests/support/asserts.py": [
    "ae2037918aeb450a86f3615f963fe4a4032324cb",
    "support"
   ],
   "webdriver/tests/support/fixtures.py": [
-   "765dd3821da0724024cdd61523f3d2fd79e8be28",
+   "2331c38e8de48de41b982dee01b14cfe1092cad0",
    "support"
   ],
   "webdriver/tests/support/http_request.py": [
    "cb40c781fea2280b98135522def5e6a116d7b946",
    "support"
   ],
   "webdriver/tests/support/inline.py": [
    "ffabd6a12d6e7928176fa00702214e0c8e0a25d7",
    "support"
   ],
   "webdriver/tests/support/merge_dictionaries.py": [
    "84a6d3c6f8f4afded0f21264bbaeebec38a7f827",
    "support"
   ],
   "webdriver/tests/support/wait.py": [
-   "a4b0c9c340ea7055139d9fcab3246ee836d6a441",
+   "1f6340b5819124bb31831efa532592e9e1696b06",
    "support"
   ],
   "webdriver/tests/switch_to_parent_frame.py": [
    "487a0588e9c017640017b775c06c21f919d16fa9",
    "wdspec"
   ],
   "webdriver/tests/user_prompts/accept_alert.py": [
    "30aa726664c6228dd5901bef862d3d55b3474e41",
--- a/testing/web-platform/meta/webdriver/tests/element_retrieval/get_active_element.py.ini
+++ b/testing/web-platform/meta/webdriver/tests/element_retrieval/get_active_element.py.ini
@@ -1,11 +1,8 @@
 [get_active_element.py]
   type: wdspec
+
   [get_active_element.py::test_handle_prompt_dismiss]
     expected: FAIL
 
   [get_active_element.py::test_handle_prompt_accept]
     expected: FAIL
-
-  [get_active_element.py::test_sucess_without_body]
-    expected: FAIL
-
--- a/testing/web-platform/tests/webdriver/tests/element_retrieval/get_active_element.py
+++ b/testing/web-platform/tests/webdriver/tests/element_retrieval/get_active_element.py
@@ -1,15 +1,17 @@
 from tests.support.asserts import assert_error, assert_dialog_handled, assert_same_element
 from tests.support.fixtures import create_dialog
 from tests.support.inline import inline
 
+
 def read_global(session, name):
     return session.execute_script("return %s;" % name)
 
+
 def get_active_element(session):
     return session.transport.send("GET", "session/%s/element/active" % session.session_id)
 
 
 def assert_is_active_element(session, response):
     """Ensure that the provided object is a successful WebDriver
     response describing an element reference and that the referenced
     element matches the element returned by the `activeElement`
@@ -239,19 +241,19 @@ def test_success_iframe_content(session)
         iframe.contentDocument.body.appendChild(input);
         input.focus();
         """)
 
     response = get_active_element(session)
     assert_is_active_element(session, response)
 
 
-def test_sucess_without_body(session):
+def test_missing_document_element(session):
     session.url = inline("<body></body>")
     session.execute_script("""
         if (document.body.remove) {
           document.body.remove();
         } else {
           document.body.removeNode(true);
         }""")
 
     response = get_active_element(session)
-    assert_is_active_element(session, response)
+    assert_error(response, "no such element")