mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
webdriver: Keep constellation alive and Open new top-level browsing context with new session request when none is open (#37410)
Keep Constellation alive even when all browsing context closed in WebDriver mode. In this case, when creating a new session, we would open a new top-level browsing context. Fixes: #37408 Testing: `./mach test-wpt -r .\tests\wpt\tests\webdriver\tests\classic\close_window\close.py --product servodriver` --------- Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com> Signed-off-by: Euclid Ye <euclid.ye@huawei.com>
This commit is contained in:
parent
0e18057863
commit
8b3e7b1c6a
8 changed files with 50 additions and 41 deletions
|
@ -146,17 +146,16 @@ pub enum WebDriverCommandMsg {
|
|||
Option<Rect<f32, CSSPixel>>,
|
||||
IpcSender<Option<RasterImage>>,
|
||||
),
|
||||
/// Create a new webview that loads about:blank. The constellation will use
|
||||
/// Create a new webview that loads about:blank. The embedder will use
|
||||
/// the provided channels to return the top level browsing context id
|
||||
/// associated with the new webview, and a notification when the initial
|
||||
/// load is complete.
|
||||
NewWebView(IpcSender<WebViewId>, IpcSender<WebDriverLoadStatus>),
|
||||
/// associated with the new webview, and sets a "load status sender" if provided.
|
||||
NewWebView(IpcSender<WebViewId>, Option<IpcSender<WebDriverLoadStatus>>),
|
||||
/// Close the webview associated with the provided id.
|
||||
CloseWebView(WebViewId),
|
||||
/// Focus the webview associated with the provided id.
|
||||
/// Sends back a bool indicating whether the focus was successfully set.
|
||||
FocusWebView(WebViewId, IpcSender<bool>),
|
||||
/// Get focused webview.
|
||||
/// Get focused webview. For now, this is only used when start new session.
|
||||
GetFocusedWebView(IpcSender<Option<WebViewId>>),
|
||||
/// Check whether top-level browsing context is open.
|
||||
IsWebViewOpen(WebViewId, IpcSender<bool>),
|
||||
|
|
|
@ -504,17 +504,11 @@ impl Handler {
|
|||
self.session().unwrap().webview_id
|
||||
}
|
||||
|
||||
fn focus_webview_id(&self) -> WebDriverResult<WebViewId> {
|
||||
fn focused_webview_id(&self) -> WebDriverResult<Option<WebViewId>> {
|
||||
let (sender, receiver) = ipc::channel().unwrap();
|
||||
self.send_message_to_embedder(WebDriverCommandMsg::GetFocusedWebView(sender.clone()))?;
|
||||
// Wait until the document is ready before returning the top-level browsing context id.
|
||||
match wait_for_script_response(receiver)? {
|
||||
Some(webview_id) => Ok(webview_id),
|
||||
None => Err(WebDriverError::new(
|
||||
ErrorStatus::NoSuchWindow,
|
||||
"No focused webview found",
|
||||
)),
|
||||
}
|
||||
wait_for_script_response(receiver)
|
||||
}
|
||||
|
||||
fn session(&self) -> WebDriverResult<&WebDriverSession> {
|
||||
|
@ -578,8 +572,22 @@ impl Handler {
|
|||
|
||||
// Step 6. Create a session
|
||||
// Step 8. Set session' current top-level browsing context
|
||||
let webview_id = self.focus_webview_id()?;
|
||||
let webview_id = match self.focused_webview_id()? {
|
||||
Some(webview_id) => webview_id,
|
||||
None => {
|
||||
// This happens when there is no open webview.
|
||||
// We need to create a new one. See https://github.com/servo/servo/issues/37408
|
||||
let (sender, receiver) = ipc::channel().unwrap();
|
||||
self.send_message_to_embedder(WebDriverCommandMsg::NewWebView(sender, None))?;
|
||||
let webview_id = receiver
|
||||
.recv()
|
||||
.expect("IPC failure when creating new webview for new session");
|
||||
self.focus_webview(webview_id)?;
|
||||
webview_id
|
||||
},
|
||||
};
|
||||
let browsing_context_id = BrowsingContextId::from(webview_id);
|
||||
|
||||
// Create and append session to the handler
|
||||
let session_id = self.create_session(
|
||||
&mut capabilities,
|
||||
|
@ -1085,7 +1093,8 @@ impl Handler {
|
|||
// Step 3. Handle any user prompt.
|
||||
self.handle_any_user_prompts(session.webview_id)?;
|
||||
|
||||
let cmd_msg = WebDriverCommandMsg::NewWebView(sender, self.load_status_sender.clone());
|
||||
let cmd_msg =
|
||||
WebDriverCommandMsg::NewWebView(sender, Some(self.load_status_sender.clone()));
|
||||
// Step 5. Create a new top-level browsing context by running the window open steps.
|
||||
// This MUST be done without invoking the focusing steps.
|
||||
self.send_message_to_embedder(cmd_msg)?;
|
||||
|
@ -1189,14 +1198,7 @@ impl Handler {
|
|||
let webview_id = *webview_id;
|
||||
session.webview_id = webview_id;
|
||||
session.browsing_context_id = BrowsingContextId::from(webview_id);
|
||||
let (sender, receiver) = ipc::channel().unwrap();
|
||||
let msg = WebDriverCommandMsg::FocusWebView(webview_id, sender);
|
||||
self.send_message_to_embedder(msg)?;
|
||||
if wait_for_script_response(receiver)? {
|
||||
debug!("Focus new webview successfully");
|
||||
} else {
|
||||
debug!("Focus new webview failed, it may not exist anymore");
|
||||
}
|
||||
self.focus_webview(webview_id)?;
|
||||
Ok(WebDriverResponse::Void)
|
||||
} else {
|
||||
Err(WebDriverError::new(
|
||||
|
@ -2387,6 +2389,17 @@ impl Handler {
|
|||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn focus_webview(&self, webview_id: WebViewId) -> Result<(), WebDriverError> {
|
||||
let (sender, receiver) = ipc::channel().unwrap();
|
||||
self.send_message_to_embedder(WebDriverCommandMsg::FocusWebView(webview_id, sender))?;
|
||||
if wait_for_script_response(receiver)? {
|
||||
debug!("Focus new webview successfully");
|
||||
} else {
|
||||
debug!("Focus new webview failed, it may not exist anymore");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl WebDriverHandler<ServoExtensionRoute> for Handler {
|
||||
|
|
|
@ -369,8 +369,9 @@ impl App {
|
|||
if let Err(error) = response_sender.send(new_webview.id()) {
|
||||
warn!("Failed to send response of NewWebview: {error}");
|
||||
}
|
||||
|
||||
running_state.set_load_status_sender(new_webview.id(), load_status_sender);
|
||||
if let Some(load_status_sender) = load_status_sender {
|
||||
running_state.set_load_status_sender(new_webview.id(), load_status_sender);
|
||||
}
|
||||
},
|
||||
WebDriverCommandMsg::CloseWebView(webview_id) => {
|
||||
running_state.close_webview(webview_id);
|
||||
|
@ -446,8 +447,10 @@ impl App {
|
|||
warn!("Failed to send response of GetViewportSize: {error}");
|
||||
}
|
||||
},
|
||||
// This is only received when start new session.
|
||||
WebDriverCommandMsg::GetFocusedWebView(sender) => {
|
||||
let focused_webview = running_state.focused_webview();
|
||||
|
||||
if let Err(error) = sender.send(focused_webview.map(|w| w.id())) {
|
||||
warn!("Failed to send response of GetFocusedWebView: {error}");
|
||||
};
|
||||
|
|
|
@ -272,7 +272,13 @@ impl RunningAppState {
|
|||
Some(last_created_webview) => {
|
||||
last_created_webview.focus();
|
||||
},
|
||||
None => self.servo.start_shutting_down(),
|
||||
None if self.servoshell_preferences.webdriver_port.is_none() => {
|
||||
self.servo.start_shutting_down()
|
||||
},
|
||||
None => {
|
||||
// For WebDriver, don't shut down when last webview closed
|
||||
// https://github.com/servo/servo/issues/37408
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
expected: FAIL
|
||||
|
||||
[test_accept_prompt]
|
||||
expected: ERROR
|
||||
expected: FAIL
|
||||
|
||||
[test_accept_in_popup_window]
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
[close.py]
|
||||
[test_close_last_browsing_context]
|
||||
expected: FAIL
|
||||
|
||||
[test_element_usage_after_closing_browsing_context]
|
||||
expected: ERROR
|
||||
|
|
|
@ -2,12 +2,6 @@
|
|||
[test_no_top_browsing_context]
|
||||
expected: ERROR
|
||||
|
||||
[test_no_browsing_context]
|
||||
expected: ERROR
|
||||
|
||||
[test_dismiss_alert]
|
||||
expected: FAIL
|
||||
|
||||
[test_dismiss_confirm]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -8,11 +8,8 @@
|
|||
[test_single_file_appends_with_multiple_attribute]
|
||||
expected: FAIL
|
||||
|
||||
[test_focused]
|
||||
expected: ERROR
|
||||
|
||||
[test_strict_hidden]
|
||||
expected: ERROR
|
||||
expected: FAIL
|
||||
|
||||
[test_strict_display_none]
|
||||
expected: ERROR
|
||||
expected: FAIL
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue