script(webdriver): Check if element is keyboard interactable in element send keys (#38235)

Step 7.6 of remote end steps of [Element Send
Keys](https://w3c.github.io/webdriver/#element-send-keys)
> If element is not
[keyboard-interactable](https://w3c.github.io/webdriver/#dfn-keyboard-interactable),
return [error](https://w3c.github.io/webdriver/#dfn-error) with [error
code](https://w3c.github.io/webdriver/#dfn-error-code) [element not
interactable](https://w3c.github.io/webdriver/#dfn-element-not-interactable).

---------

Signed-off-by: PotatoCP <Kenzie.Raditya.Tirtarahardja@huawei.com>
This commit is contained in:
Kenzie Raditya Tirtarahardja 2025-07-24 12:32:46 +08:00 committed by GitHub
parent f726737f24
commit d95dd69e3c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 24 additions and 10 deletions

View file

@ -1740,6 +1740,15 @@ impl Element {
} }
} }
/// <https://dom.spec.whatwg.org/#document-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 { pub(crate) fn is_focusable_area(&self) -> bool {
if self.is_actually_disabled() { if self.is_actually_disabled() {
return false; return false;

View file

@ -61,6 +61,7 @@ use crate::dom::domrect::DOMRect;
use crate::dom::element::Element; use crate::dom::element::Element;
use crate::dom::eventtarget::EventTarget; use crate::dom::eventtarget::EventTarget;
use crate::dom::globalscope::GlobalScope; use crate::dom::globalscope::GlobalScope;
use crate::dom::htmlbodyelement::HTMLBodyElement;
use crate::dom::htmldatalistelement::HTMLDataListElement; use crate::dom::htmldatalistelement::HTMLDataListElement;
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::htmliframeelement::HTMLIFrameElement; use crate::dom::htmliframeelement::HTMLIFrameElement;
@ -1069,6 +1070,11 @@ pub(crate) fn handle_get_element_shadow_root(
.unwrap(); .unwrap();
} }
/// <https://w3c.github.io/webdriver/#dfn-keyboard-interactable>
fn is_keyboard_interactable(element: &Element) -> bool {
element.is_focusable_area() || element.is::<HTMLBodyElement>() || element.is_document_element()
}
fn handle_send_keys_file( fn handle_send_keys_file(
file_input: &HTMLInputElement, file_input: &HTMLInputElement,
text: &str, 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 // Step 7. If file is false or the session's strict file interactability
if file_input.is_none() || strict_file_interactability { if file_input.is_none() || strict_file_interactability {
// TODO: Step 7.1. Scroll Into View // TODO(24059): Step 7.1. Scroll Into View
// TODO: Step 7.2 - 7.6 // TODO: Step 7.2 - 7.5
// Wait until element become Keyboard-interactable // Wait until element become keyboard-interactable
// or return error with error code element not 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::<HTMLElement>() { match element.downcast::<HTMLElement>() {
Some(element) => { Some(element) => {

View file

@ -5,9 +5,6 @@
[test_readonly_element] [test_readonly_element]
expected: FAIL expected: FAIL
[test_not_a_focusable_element]
expected: FAIL
[test_display_none] [test_display_none]
expected: FAIL expected: FAIL
@ -16,6 +13,3 @@
[test_hidden] [test_hidden]
expected: FAIL expected: FAIL
[test_disabled]
expected: FAIL