diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 05ae67f9d4d..45247b40cc3 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -1740,6 +1740,15 @@ impl Element { } } + /// + pub(crate) fn is_document_element(&self) -> bool { + if let Some(ref document_element) = self.owner_document().GetDocumentElement() { + **document_element == *self + } else { + false + } + } + pub(crate) fn is_focusable_area(&self) -> bool { if self.is_actually_disabled() { return false; diff --git a/components/script/webdriver_handlers.rs b/components/script/webdriver_handlers.rs index 6e69c65f0a3..2471d3db471 100644 --- a/components/script/webdriver_handlers.rs +++ b/components/script/webdriver_handlers.rs @@ -61,6 +61,7 @@ use crate::dom::domrect::DOMRect; use crate::dom::element::Element; use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; +use crate::dom::htmlbodyelement::HTMLBodyElement; use crate::dom::htmldatalistelement::HTMLDataListElement; use crate::dom::htmlelement::HTMLElement; use crate::dom::htmliframeelement::HTMLIFrameElement; @@ -1069,6 +1070,11 @@ pub(crate) fn handle_get_element_shadow_root( .unwrap(); } +/// +fn is_keyboard_interactable(element: &Element) -> bool { + element.is_focusable_area() || element.is::() || element.is_document_element() +} + fn handle_send_keys_file( file_input: &HTMLInputElement, text: &str, @@ -1169,10 +1175,15 @@ pub(crate) fn handle_will_send_keys( // Step 7. If file is false or the session's strict file interactability if file_input.is_none() || strict_file_interactability { - // TODO: Step 7.1. Scroll Into View - // TODO: Step 7.2 - 7.6 - // Wait until element become Keyboard-interactable - // or return error with error code element not interactable. + // TODO(24059): Step 7.1. Scroll Into View + // TODO: Step 7.2 - 7.5 + // Wait until element become keyboard-interactable + + // Step 7.6. If element is not keyboard-interactable, + // return ErrorStatus::ElementNotInteractable. + if !is_keyboard_interactable(&element) { + return Err(ErrorStatus::ElementNotInteractable); + } match element.downcast::() { Some(element) => { diff --git a/tests/wpt/meta/webdriver/tests/classic/element_send_keys/interactability.py.ini b/tests/wpt/meta/webdriver/tests/classic/element_send_keys/interactability.py.ini index fc287e23c3d..0db71872183 100644 --- a/tests/wpt/meta/webdriver/tests/classic/element_send_keys/interactability.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/element_send_keys/interactability.py.ini @@ -5,9 +5,6 @@ [test_readonly_element] expected: FAIL - [test_not_a_focusable_element] - expected: FAIL - [test_display_none] expected: FAIL @@ -16,6 +13,3 @@ [test_hidden] expected: FAIL - - [test_disabled] - expected: FAIL