From 39144bb013d7feeb12d569f420305458ef64f73d Mon Sep 17 00:00:00 2001 From: Kenzie Raditya Tirtarahardja Date: Fri, 18 Jul 2025 14:40:40 +0800 Subject: [PATCH] Webdriver: Allow error when selecting file at ElementSendKeys (#38158) Based on [spec](https://w3c.github.io/webdriver/#element-send-keys), > 5. Verify that each file given by the user exists. If any do not, return [error](https://w3c.github.io/webdriver/#dfn-error) with [error code](https://w3c.github.io/webdriver/#dfn-error-code) [invalid argument](https://w3c.github.io/webdriver/#dfn-invalid-argument). --------- Signed-off-by: PotatoCP --- components/script/dom/htmlinputelement.rs | 41 +++++++++++-------- components/script/webdriver_handlers.rs | 7 ++-- .../element_send_keys/file_upload.py.ini | 6 --- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs index c016f003295..405a79f51a2 100644 --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -27,7 +27,7 @@ use js::jsval::UndefinedValue; use js::rust::wrappers::{CheckRegExpSyntax, ExecuteRegExpNoStatics, ObjectIsRegExp}; use js::rust::{HandleObject, MutableHandleObject}; use net_traits::blob_url_store::get_blob_origin; -use net_traits::filemanager_thread::FileManagerThreadMsg; +use net_traits::filemanager_thread::{FileManagerResult, FileManagerThreadMsg}; use net_traits::{CoreResourceMsg, IpcSend}; use style::attr::AttrValue; use style::selector_parser::PseudoElement; @@ -1754,7 +1754,7 @@ impl HTMLInputElementMethods for HTMLInputElement { // check-tidy: no specs after this line fn SelectFiles(&self, paths: Vec, can_gc: CanGc) { if self.input_type() == InputType::File { - self.select_files(Some(paths), can_gc); + let _ = self.select_files(Some(paths), can_gc); } } @@ -2026,13 +2026,16 @@ impl HTMLInputElement { // https://html.spec.whatwg.org/multipage/#file-upload-state-(type=file) // Select files by invoking UI or by passed in argument - fn select_files(&self, opt_test_paths: Option>, can_gc: CanGc) { + pub(crate) fn select_files( + &self, + opt_test_paths: Option>, + can_gc: CanGc, + ) -> FileManagerResult<()> { let window = self.owner_window(); let origin = get_blob_origin(&window.get_url()); let resource_threads = window.as_global_scope().resource_threads(); let mut files: Vec> = vec![]; - let mut error = None; let webview_id = window.webview_id(); let filter = filter_from_accept(&self.Accept()); @@ -2061,13 +2064,16 @@ impl HTMLInputElement { files.push(File::new_from_selected(&window, selected, can_gc)); } }, - Err(err) => error = Some(err), + Err(err) => { + debug!("Input multiple file select error: {:?}", err); + return Err(err); + }, }; } else { let opt_test_path = match opt_test_paths { Some(paths) => { if paths.is_empty() { - return; + return Ok(()); } else { Some(PathBuf::from(paths[0].to_string())) // neglect other paths } @@ -2088,19 +2094,20 @@ impl HTMLInputElement { Ok(selected) => { files.push(File::new_from_selected(&window, selected, can_gc)); }, - Err(err) => error = Some(err), + Err(err) => { + debug!("Input file select error: {:?}", err); + return Err(err); + }, }; } - if let Some(err) = error { - debug!("Input file select error: {:?}", err); - } else { - let filelist = FileList::new(&window, files, can_gc); - self.filelist.set(Some(&filelist)); + let filelist = FileList::new(&window, files, can_gc); + self.filelist.set(Some(&filelist)); - target.fire_bubbling_event(atom!("input"), can_gc); - target.fire_bubbling_event(atom!("change"), can_gc); - } + target.fire_bubbling_event(atom!("input"), can_gc); + target.fire_bubbling_event(atom!("change"), can_gc); + + Ok(()) } // https://html.spec.whatwg.org/multipage/#value-sanitization-algorithm @@ -3202,7 +3209,9 @@ impl Activatable for HTMLInputElement { target.fire_bubbling_event(atom!("change"), can_gc); }, // https://html.spec.whatwg.org/multipage/#file-upload-state-(type=file):input-activation-behavior - InputType::File => self.select_files(None, can_gc), + InputType::File => { + let _ = self.select_files(None, can_gc); + }, // https://html.spec.whatwg.org/multipage/#color-state-(type=color):input-activation-behavior InputType::Color => { self.show_the_picker_if_applicable(can_gc); diff --git a/components/script/webdriver_handlers.rs b/components/script/webdriver_handlers.rs index 058b4d2245e..218a1a47d97 100644 --- a/components/script/webdriver_handlers.rs +++ b/components/script/webdriver_handlers.rs @@ -1114,11 +1114,12 @@ pub(crate) fn handle_will_send_keys( } // Step 8.5 - // TODO: Should return invalid argument error if file doesn't exist - + // InvalidArgument Error is returned if the files are not valid. // Step 8.6 - 8.7 // Input and change event already fired in `htmlinputelement.rs`. - file_input.SelectFiles(files, can_gc); + if file_input.select_files(Some(files), can_gc).is_err() { + return Err(ErrorStatus::InvalidArgument); + } // Step 8.8 return Ok(false); 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 40a4a701288..e1f1291f1a1 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,10 +1,4 @@ [file_upload.py] - [test_empty_text] - expected: FAIL - - [test_multiple_files_last_path_not_found] - expected: FAIL - [test_multiple_files_send_twice] expected: FAIL