webdriver: Simplify webview related steps that are guaranteed to succeed (#38855)

Testing: Semantically it is the same. But still run the test locally and
in [try](https://github.com/yezhizhen/servo/actions/runs/17159323926) as
I was worried about some unexpected side effect from
176e42d36d. But seems everything is good.

---------

Signed-off-by: Euclid Ye <euclid.ye@huawei.com>
This commit is contained in:
Euclid Ye 2025-08-23 01:19:12 +08:00 committed by GitHub
parent 4082f57003
commit f323e67024
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 31 additions and 38 deletions

View file

@ -574,9 +574,9 @@ impl Handler {
webview_id webview_id
}, },
}; };
self.session_mut()?.set_webview_id(Some(webview_id)); self.session_mut()?.set_webview_id(webview_id);
self.session_mut()? self.session_mut()?
.set_browsing_context_id(Some(BrowsingContextId::from(webview_id))); .set_browsing_context_id(BrowsingContextId::from(webview_id));
// Step 9. Set the request queue to a new queue. // Step 9. Set the request queue to a new queue.
// Skip here because the requests are handled in the external crate. // Skip here because the requests are handled in the external crate.
@ -674,7 +674,7 @@ impl Handler {
// Step 8.3. Set current browsing context with session and current top browsing context // Step 8.3. Set current browsing context with session and current top browsing context
self.session_mut()? self.session_mut()?
.set_browsing_context_id(Some(BrowsingContextId::from(webview_id))); .set_browsing_context_id(BrowsingContextId::from(webview_id));
Ok(WebDriverResponse::Void) Ok(WebDriverResponse::Void)
} }
@ -1016,7 +1016,7 @@ impl Handler {
// Step 5. Set current browsing context with session and current top browsing context. // Step 5. Set current browsing context with session and current top browsing context.
self.session_mut()? self.session_mut()?
.set_browsing_context_id(Some(BrowsingContextId::from(webview_id))); .set_browsing_context_id(BrowsingContextId::from(webview_id));
Ok(WebDriverResponse::Void) Ok(WebDriverResponse::Void)
} }
@ -1066,7 +1066,7 @@ impl Handler {
/// <https://w3c.github.io/webdriver/#get-window-handles> /// <https://w3c.github.io/webdriver/#get-window-handles>
fn handle_window_handles(&mut self) -> WebDriverResult<WebDriverResponse> { fn handle_window_handles(&mut self) -> WebDriverResult<WebDriverResponse> {
let mut handles = self.get_window_handles()?; let mut handles = self.get_window_handles();
handles.sort(); handles.sort();
Ok(WebDriverResponse::Generic(ValueResponse( Ok(WebDriverResponse::Generic(ValueResponse(
@ -1074,35 +1074,25 @@ impl Handler {
))) )))
} }
fn get_window_handle(&mut self, webview_id: WebViewId) -> WebDriverResult<String> { fn get_window_handle(&mut self, webview_id: WebViewId) -> Option<String> {
self.get_window_handles()? self.get_window_handles()
.iter() .iter()
.find(|id| id == &&webview_id.to_string()) .find(|id| id == &&webview_id.to_string())
.cloned() .cloned()
.ok_or_else(|| {
WebDriverError::new(
ErrorStatus::UnknownError,
"No such window while getting window handle",
)
})
} }
fn get_window_handles(&self) -> WebDriverResult<Vec<String>> { fn get_window_handles(&self) -> Vec<String> {
let handles = self self.get_all_webview_ids()
.get_all_webview_ids()?
.into_iter() .into_iter()
.map(|id| id.to_string()) .map(|id| id.to_string())
.collect::<Vec<_>>(); .collect()
Ok(handles)
} }
fn get_all_webview_ids(&self) -> WebDriverResult<Vec<WebViewId>> { fn get_all_webview_ids(&self) -> Vec<WebViewId> {
let (sender, receiver) = ipc::channel().unwrap(); let (sender, receiver) = ipc::channel().unwrap();
self.send_message_to_embedder(WebDriverCommandMsg::GetAllWebViews(sender))?; self.send_message_to_embedder(WebDriverCommandMsg::GetAllWebViews(sender))
let webviews = wait_for_ipc_response(receiver)?; .unwrap();
wait_for_ipc_response(receiver).unwrap_or_default()
Ok(webviews)
} }
/// <https://w3c.github.io/webdriver/#find-element> /// <https://w3c.github.io/webdriver/#find-element>
@ -1136,7 +1126,7 @@ impl Handler {
wait_for_ipc_response(receiver)?; wait_for_ipc_response(receiver)?;
// Step 4. If there are no more open top-level browsing contexts, try to close the session. // Step 4. If there are no more open top-level browsing contexts, try to close the session.
let window_handles = self.get_window_handles()?; let window_handles = self.get_window_handles();
if window_handles.is_empty() { if window_handles.is_empty() {
self.session = None; self.session = None;
@ -1172,7 +1162,9 @@ impl Handler {
if let Ok(webview_id) = receiver.recv() { if let Ok(webview_id) = receiver.recv() {
let _ = self.wait_for_document_ready_state(); let _ = self.wait_for_document_ready_state();
let handle = self.get_window_handle(webview_id)?; let handle = self
.get_window_handle(webview_id)
.expect("Failed to get window handle of an existing webview");
Ok(WebDriverResponse::NewWindow(NewWindowResponse { Ok(WebDriverResponse::NewWindow(NewWindowResponse {
handle, handle,
@ -1204,7 +1196,7 @@ impl Handler {
// Step 3. Set the current browsing context with session and // Step 3. Set the current browsing context with session and
// session's current top-level browsing context. // session's current top-level browsing context.
self.session_mut()? self.session_mut()?
.set_browsing_context_id(Some(BrowsingContextId::from(webview_id))); .set_browsing_context_id(BrowsingContextId::from(webview_id));
return Ok(WebDriverResponse::Void); return Ok(WebDriverResponse::Void);
}, },
// id is a Number object // id is a Number object
@ -1248,7 +1240,7 @@ impl Handler {
match wait_for_ipc_response(receiver)? { match wait_for_ipc_response(receiver)? {
Ok(browsing_context_id) => { Ok(browsing_context_id) => {
self.session_mut()? self.session_mut()?
.set_browsing_context_id(Some(browsing_context_id)); .set_browsing_context_id(browsing_context_id);
Ok(WebDriverResponse::Void) Ok(WebDriverResponse::Void)
}, },
Err(error) => Err(WebDriverError::new(error, "")), Err(error) => Err(WebDriverError::new(error, "")),
@ -1260,9 +1252,9 @@ impl Handler {
&mut self, &mut self,
parameters: &SwitchToWindowParameters, parameters: &SwitchToWindowParameters,
) -> WebDriverResult<WebDriverResponse> { ) -> WebDriverResult<WebDriverResponse> {
let window_handles = self.get_all_webview_ids()?; let Some(webview_id) = self
let Some(webview_id) = window_handles .get_all_webview_ids()
.iter() .into_iter()
.find(|id| id.to_string() == parameters.handle) .find(|id| id.to_string() == parameters.handle)
else { else {
return Err(WebDriverError::new( return Err(WebDriverError::new(
@ -1272,8 +1264,8 @@ impl Handler {
}; };
let session = self.session_mut()?; let session = self.session_mut()?;
session.set_webview_id(Some(*webview_id)); session.set_webview_id(webview_id);
session.set_browsing_context_id(Some(BrowsingContextId::from(*webview_id))); session.set_browsing_context_id(BrowsingContextId::from(webview_id));
Ok(WebDriverResponse::Void) Ok(WebDriverResponse::Void)
} }
@ -1289,7 +1281,7 @@ impl Handler {
match wait_for_ipc_response(receiver)? { match wait_for_ipc_response(receiver)? {
Ok(browsing_context_id) => { Ok(browsing_context_id) => {
self.session_mut()? self.session_mut()?
.set_browsing_context_id(Some(browsing_context_id)); .set_browsing_context_id(browsing_context_id);
Ok(WebDriverResponse::Void) Ok(WebDriverResponse::Void)
}, },
Err(error) => Err(WebDriverError::new(error, "")), Err(error) => Err(WebDriverError::new(error, "")),

View file

@ -60,6 +60,7 @@ pub struct WebDriverSession {
strict_file_interactability: bool, strict_file_interactability: bool,
/// <https://w3c.github.io/webdriver/#dfn-user-prompt-handler>
user_prompt_handler: UserPromptHandler, user_prompt_handler: UserPromptHandler,
/// <https://w3c.github.io/webdriver/#dfn-input-state-map> /// <https://w3c.github.io/webdriver/#dfn-input-state-map>
@ -84,12 +85,12 @@ impl WebDriverSession {
} }
} }
pub fn set_webview_id(&mut self, webview_id: Option<WebViewId>) { pub fn set_webview_id(&mut self, webview_id: WebViewId) {
self.webview_id = webview_id; self.webview_id = Some(webview_id);
} }
pub fn set_browsing_context_id(&mut self, browsing_context_id: Option<BrowsingContextId>) { pub fn set_browsing_context_id(&mut self, browsing_context_id: BrowsingContextId) {
self.browsing_context_id = browsing_context_id; self.browsing_context_id = Some(browsing_context_id);
} }
pub fn current_webview_id(&self) -> Option<WebViewId> { pub fn current_webview_id(&self) -> Option<WebViewId> {