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>>,
|
Option<Rect<f32, CSSPixel>>,
|
||||||
IpcSender<Option<RasterImage>>,
|
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
|
/// the provided channels to return the top level browsing context id
|
||||||
/// associated with the new webview, and a notification when the initial
|
/// associated with the new webview, and sets a "load status sender" if provided.
|
||||||
/// load is complete.
|
NewWebView(IpcSender<WebViewId>, Option<IpcSender<WebDriverLoadStatus>>),
|
||||||
NewWebView(IpcSender<WebViewId>, IpcSender<WebDriverLoadStatus>),
|
|
||||||
/// Close the webview associated with the provided id.
|
/// Close the webview associated with the provided id.
|
||||||
CloseWebView(WebViewId),
|
CloseWebView(WebViewId),
|
||||||
/// Focus the webview associated with the provided id.
|
/// Focus the webview associated with the provided id.
|
||||||
/// Sends back a bool indicating whether the focus was successfully set.
|
/// Sends back a bool indicating whether the focus was successfully set.
|
||||||
FocusWebView(WebViewId, IpcSender<bool>),
|
FocusWebView(WebViewId, IpcSender<bool>),
|
||||||
/// Get focused webview.
|
/// Get focused webview. For now, this is only used when start new session.
|
||||||
GetFocusedWebView(IpcSender<Option<WebViewId>>),
|
GetFocusedWebView(IpcSender<Option<WebViewId>>),
|
||||||
/// Check whether top-level browsing context is open.
|
/// Check whether top-level browsing context is open.
|
||||||
IsWebViewOpen(WebViewId, IpcSender<bool>),
|
IsWebViewOpen(WebViewId, IpcSender<bool>),
|
||||||
|
|
|
@ -504,17 +504,11 @@ impl Handler {
|
||||||
self.session().unwrap().webview_id
|
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();
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
self.send_message_to_embedder(WebDriverCommandMsg::GetFocusedWebView(sender.clone()))?;
|
self.send_message_to_embedder(WebDriverCommandMsg::GetFocusedWebView(sender.clone()))?;
|
||||||
// Wait until the document is ready before returning the top-level browsing context id.
|
// Wait until the document is ready before returning the top-level browsing context id.
|
||||||
match wait_for_script_response(receiver)? {
|
wait_for_script_response(receiver)
|
||||||
Some(webview_id) => Ok(webview_id),
|
|
||||||
None => Err(WebDriverError::new(
|
|
||||||
ErrorStatus::NoSuchWindow,
|
|
||||||
"No focused webview found",
|
|
||||||
)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn session(&self) -> WebDriverResult<&WebDriverSession> {
|
fn session(&self) -> WebDriverResult<&WebDriverSession> {
|
||||||
|
@ -578,8 +572,22 @@ impl Handler {
|
||||||
|
|
||||||
// Step 6. Create a session
|
// Step 6. Create a session
|
||||||
// Step 8. Set session' current top-level browsing context
|
// 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);
|
let browsing_context_id = BrowsingContextId::from(webview_id);
|
||||||
|
|
||||||
// Create and append session to the handler
|
// Create and append session to the handler
|
||||||
let session_id = self.create_session(
|
let session_id = self.create_session(
|
||||||
&mut capabilities,
|
&mut capabilities,
|
||||||
|
@ -1085,7 +1093,8 @@ impl Handler {
|
||||||
// Step 3. Handle any user prompt.
|
// Step 3. Handle any user prompt.
|
||||||
self.handle_any_user_prompts(session.webview_id)?;
|
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.
|
// Step 5. Create a new top-level browsing context by running the window open steps.
|
||||||
// This MUST be done without invoking the focusing steps.
|
// This MUST be done without invoking the focusing steps.
|
||||||
self.send_message_to_embedder(cmd_msg)?;
|
self.send_message_to_embedder(cmd_msg)?;
|
||||||
|
@ -1189,14 +1198,7 @@ impl Handler {
|
||||||
let webview_id = *webview_id;
|
let webview_id = *webview_id;
|
||||||
session.webview_id = webview_id;
|
session.webview_id = webview_id;
|
||||||
session.browsing_context_id = BrowsingContextId::from(webview_id);
|
session.browsing_context_id = BrowsingContextId::from(webview_id);
|
||||||
let (sender, receiver) = ipc::channel().unwrap();
|
self.focus_webview(webview_id)?;
|
||||||
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");
|
|
||||||
}
|
|
||||||
Ok(WebDriverResponse::Void)
|
Ok(WebDriverResponse::Void)
|
||||||
} else {
|
} else {
|
||||||
Err(WebDriverError::new(
|
Err(WebDriverError::new(
|
||||||
|
@ -2387,6 +2389,17 @@ impl Handler {
|
||||||
Ok(())
|
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 {
|
impl WebDriverHandler<ServoExtensionRoute> for Handler {
|
||||||
|
|
|
@ -369,8 +369,9 @@ impl App {
|
||||||
if let Err(error) = response_sender.send(new_webview.id()) {
|
if let Err(error) = response_sender.send(new_webview.id()) {
|
||||||
warn!("Failed to send response of NewWebview: {error}");
|
warn!("Failed to send response of NewWebview: {error}");
|
||||||
}
|
}
|
||||||
|
if let Some(load_status_sender) = load_status_sender {
|
||||||
running_state.set_load_status_sender(new_webview.id(), load_status_sender);
|
running_state.set_load_status_sender(new_webview.id(), load_status_sender);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
WebDriverCommandMsg::CloseWebView(webview_id) => {
|
WebDriverCommandMsg::CloseWebView(webview_id) => {
|
||||||
running_state.close_webview(webview_id);
|
running_state.close_webview(webview_id);
|
||||||
|
@ -446,8 +447,10 @@ impl App {
|
||||||
warn!("Failed to send response of GetViewportSize: {error}");
|
warn!("Failed to send response of GetViewportSize: {error}");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// This is only received when start new session.
|
||||||
WebDriverCommandMsg::GetFocusedWebView(sender) => {
|
WebDriverCommandMsg::GetFocusedWebView(sender) => {
|
||||||
let focused_webview = running_state.focused_webview();
|
let focused_webview = running_state.focused_webview();
|
||||||
|
|
||||||
if let Err(error) = sender.send(focused_webview.map(|w| w.id())) {
|
if let Err(error) = sender.send(focused_webview.map(|w| w.id())) {
|
||||||
warn!("Failed to send response of GetFocusedWebView: {error}");
|
warn!("Failed to send response of GetFocusedWebView: {error}");
|
||||||
};
|
};
|
||||||
|
|
|
@ -272,7 +272,13 @@ impl RunningAppState {
|
||||||
Some(last_created_webview) => {
|
Some(last_created_webview) => {
|
||||||
last_created_webview.focus();
|
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
|
expected: FAIL
|
||||||
|
|
||||||
[test_accept_prompt]
|
[test_accept_prompt]
|
||||||
expected: ERROR
|
expected: FAIL
|
||||||
|
|
||||||
[test_accept_in_popup_window]
|
[test_accept_in_popup_window]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
[close.py]
|
[close.py]
|
||||||
[test_close_last_browsing_context]
|
[test_close_last_browsing_context]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[test_element_usage_after_closing_browsing_context]
|
|
||||||
expected: ERROR
|
|
||||||
|
|
|
@ -2,12 +2,6 @@
|
||||||
[test_no_top_browsing_context]
|
[test_no_top_browsing_context]
|
||||||
expected: ERROR
|
expected: ERROR
|
||||||
|
|
||||||
[test_no_browsing_context]
|
|
||||||
expected: ERROR
|
|
||||||
|
|
||||||
[test_dismiss_alert]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[test_dismiss_confirm]
|
[test_dismiss_confirm]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -8,11 +8,8 @@
|
||||||
[test_single_file_appends_with_multiple_attribute]
|
[test_single_file_appends_with_multiple_attribute]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[test_focused]
|
|
||||||
expected: ERROR
|
|
||||||
|
|
||||||
[test_strict_hidden]
|
[test_strict_hidden]
|
||||||
expected: ERROR
|
expected: FAIL
|
||||||
|
|
||||||
[test_strict_display_none]
|
[test_strict_display_none]
|
||||||
expected: ERROR
|
expected: FAIL
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue