diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index e138e7114d3..c23315443fd 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -2266,15 +2266,20 @@ impl ScriptThread { can_gc, ) }, - WebDriverScriptCommand::FocusElement(element_id, reply) => { - webdriver_handlers::handle_focus_element( - &documents, - pipeline_id, - element_id, - reply, - can_gc, - ) - }, + WebDriverScriptCommand::FocusElement( + strict_file_interactability, + text, + element_id, + reply, + ) => webdriver_handlers::handle_focus_element( + &documents, + pipeline_id, + element_id, + text, + strict_file_interactability, + reply, + can_gc, + ), WebDriverScriptCommand::ElementClick(element_id, reply) => { webdriver_handlers::handle_element_click( &documents, diff --git a/components/script/webdriver_handlers.rs b/components/script/webdriver_handlers.rs index 6b4264d945e..20204e52162 100644 --- a/components/script/webdriver_handlers.rs +++ b/components/script/webdriver_handlers.rs @@ -838,20 +838,52 @@ pub(crate) fn handle_focus_element( documents: &DocumentCollection, pipeline: PipelineId, element_id: String, - reply: IpcSender>, + text: String, + strict_file_interactability: bool, + reply: IpcSender>, can_gc: CanGc, ) { reply .send( find_node_by_unique_id(documents, pipeline, element_id).and_then(|node| { - match node.downcast::() { - Some(element) => { - // Need a way to find if this actually succeeded - element.Focus(can_gc); - Ok(()) - }, - None => Err(ErrorStatus::UnknownError), + let file_input = { + if let Some(input_element) = node.downcast::() { + if input_element.input_type() == InputType::File { + Some(input_element) + } else { + None + } + } else { + None + } + }; + + if file_input.is_none() || strict_file_interactability { + match node.downcast::() { + Some(element) => { + // Need a way to find if this actually succeeded + element.Focus(can_gc); + }, + None => return Err(ErrorStatus::UnknownError), + } } + + if let Some(file_input) = file_input { + let files: Vec = text.split("\n").map(|s| s.into()).collect(); + if files.is_empty() { + return Err(ErrorStatus::InvalidArgument); + } + if !file_input.Multiple() && files.len() > 1 { + return Err(ErrorStatus::InvalidArgument); + } + // TODO: Should return invalid argument error if file doesn't exist + file_input.SelectFiles(files, can_gc); + return Ok(false); + } + + // TODO: Check non-typeable form control + + return Ok(true); }), ) .unwrap(); diff --git a/components/shared/embedder/webdriver.rs b/components/shared/embedder/webdriver.rs index 7b0f02bc26a..8c7c4b2fdf6 100644 --- a/components/shared/embedder/webdriver.rs +++ b/components/shared/embedder/webdriver.rs @@ -130,7 +130,7 @@ pub enum WebDriverScriptCommand { IpcSender, ErrorStatus>>, ), FindElementElementsTagName(String, String, IpcSender, ErrorStatus>>), - FocusElement(String, IpcSender>), + FocusElement(bool, String, String, IpcSender>), ElementClick(String, IpcSender, ErrorStatus>>), GetActiveElement(IpcSender>), GetComputedRole(String, IpcSender, ErrorStatus>>), diff --git a/components/webdriver_server/lib.rs b/components/webdriver_server/lib.rs index eb3e7bf17ec..c06aa90b1e5 100644 --- a/components/webdriver_server/lib.rs +++ b/components/webdriver_server/lib.rs @@ -1617,14 +1617,23 @@ impl Handler { let (sender, receiver) = ipc::channel().unwrap(); - let cmd = WebDriverScriptCommand::FocusElement(element.to_string(), sender); + let cmd = WebDriverScriptCommand::FocusElement( + self.session()?.strict_file_interactability, + keys.text.to_string(), + element.to_string(), + sender, + ); let cmd_msg = WebDriverCommandMsg::ScriptCommand(browsing_context_id, cmd); self.constellation_chan .send(EmbedderToConstellationMessage::WebDriverCommand(cmd_msg)) .unwrap(); // TODO: distinguish the not found and not focusable cases - wait_for_script_response(receiver)?.map_err(|error| WebDriverError::new(error, ""))?; + // File input and non-typeable form control should have + // been handled in `webdriver_handler.rs` + if wait_for_script_response(receiver)?.map_err(|error| WebDriverError::new(error, ""))? { + return Ok(WebDriverResponse::Void); + } let input_events = send_keys(&keys.text); diff --git a/tests/wpt/meta/webdriver/tests/classic/element_send_keys/events.py.ini b/tests/wpt/meta/webdriver/tests/classic/element_send_keys/events.py.ini index 26b3aaa641b..5e4543ef0e9 100644 --- a/tests/wpt/meta/webdriver/tests/classic/element_send_keys/events.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/element_send_keys/events.py.ini @@ -1,7 +1,4 @@ [events.py] - [test_file_upload] - expected: FAIL - [test_form_control_send_text[input\]] expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/element_send_keys/file_upload.py.ini b/tests/wpt/meta/webdriver/tests/classic/element_send_keys/file_upload.py.ini index 4fd4b29e87f..40a4a701288 100644 --- a/tests/wpt/meta/webdriver/tests/classic/element_send_keys/file_upload.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/element_send_keys/file_upload.py.ini @@ -1,50 +1,19 @@ [file_upload.py] - expected: TIMEOUT [test_empty_text] expected: FAIL - [test_multiple_files] - expected: FAIL - [test_multiple_files_last_path_not_found] expected: FAIL - [test_multiple_files_without_multiple_attribute] - expected: FAIL - [test_multiple_files_send_twice] expected: FAIL [test_multiple_files_reset_with_element_clear] expected: FAIL - [test_single_file] - expected: FAIL - - [test_single_file_replaces_without_multiple_attribute] - expected: FAIL - [test_single_file_appends_with_multiple_attribute] expected: FAIL - [test_transparent] - expected: FAIL - - [test_obscured] - expected: FAIL - - [test_outside_viewport] - expected: FAIL - - [test_hidden] - expected: FAIL - - [test_display_none] - expected: FAIL - - [test_not_focused] - expected: FAIL - [test_focused] expected: ERROR