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
--- 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")