mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
webdriver: Move navigation commands to servoshell (#37665)
- Move webdriver `GetViewportSize`, `LoadURL` and `Refresh` to servoshell. - Add `GoBack` and `GoFoward` commands. Testing: Need to finish moving webdriver to servoshell then evaluate again Fixes: https://github.com/servo/servo/issues/37370 Signed-off-by: batu_hoang <longvatrong111@gmail.com>
This commit is contained in:
parent
0346a62214
commit
62a009399f
5 changed files with 61 additions and 98 deletions
|
@ -4558,53 +4558,17 @@ where
|
||||||
WebDriverCommandMsg::GetWindowSize(..) => {
|
WebDriverCommandMsg::GetWindowSize(..) => {
|
||||||
unreachable!("This command should be send directly to the embedder.");
|
unreachable!("This command should be send directly to the embedder.");
|
||||||
},
|
},
|
||||||
WebDriverCommandMsg::GetViewportSize(webview_id, response_sender) => {
|
WebDriverCommandMsg::GetViewportSize(..) => {
|
||||||
let browsing_context_id = BrowsingContextId::from(webview_id);
|
unreachable!("This command should be send directly to the embedder.");
|
||||||
let size = self
|
|
||||||
.browsing_contexts
|
|
||||||
.get(&browsing_context_id)
|
|
||||||
.map(|browsing_context| browsing_context.viewport_details.size)
|
|
||||||
.unwrap_or_default();
|
|
||||||
let _ = response_sender.send(size);
|
|
||||||
},
|
},
|
||||||
WebDriverCommandMsg::SetWindowSize(..) => {
|
WebDriverCommandMsg::SetWindowSize(..) => {
|
||||||
unreachable!("This command should be send directly to the embedder.");
|
unreachable!("This command should be send directly to the embedder.");
|
||||||
},
|
},
|
||||||
WebDriverCommandMsg::LoadUrl(webview_id, url, response_sender) => {
|
WebDriverCommandMsg::LoadUrl(..) => {
|
||||||
let load_data = LoadData::new(
|
unreachable!("This command should be send directly to the embedder.");
|
||||||
LoadOrigin::WebDriver,
|
|
||||||
url,
|
|
||||||
None,
|
|
||||||
Referrer::NoReferrer,
|
|
||||||
ReferrerPolicy::EmptyString,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
self.load_url_for_webdriver(
|
|
||||||
webview_id,
|
|
||||||
load_data,
|
|
||||||
response_sender,
|
|
||||||
NavigationHistoryBehavior::Push,
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
WebDriverCommandMsg::Refresh(webview_id, response_sender) => {
|
WebDriverCommandMsg::Refresh(..) => {
|
||||||
let browsing_context_id = BrowsingContextId::from(webview_id);
|
unreachable!("This command should be send directly to the embedder.");
|
||||||
let pipeline_id = self
|
|
||||||
.browsing_contexts
|
|
||||||
.get(&browsing_context_id)
|
|
||||||
.expect("Refresh: Browsing context must exist at this point")
|
|
||||||
.pipeline_id;
|
|
||||||
let load_data = match self.pipelines.get(&pipeline_id) {
|
|
||||||
Some(pipeline) => pipeline.load_data.clone(),
|
|
||||||
None => return warn!("{}: Refresh after closure", pipeline_id),
|
|
||||||
};
|
|
||||||
self.load_url_for_webdriver(
|
|
||||||
webview_id,
|
|
||||||
load_data,
|
|
||||||
response_sender,
|
|
||||||
NavigationHistoryBehavior::Replace,
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
// TODO: This should use the ScriptThreadMessage::EvaluateJavaScript command
|
// TODO: This should use the ScriptThreadMessage::EvaluateJavaScript command
|
||||||
WebDriverCommandMsg::ScriptCommand(browsing_context_id, cmd) => {
|
WebDriverCommandMsg::ScriptCommand(browsing_context_id, cmd) => {
|
||||||
|
@ -4873,38 +4837,6 @@ where
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[servo_tracing::instrument(skip_all)]
|
|
||||||
fn load_url_for_webdriver(
|
|
||||||
&mut self,
|
|
||||||
webview_id: WebViewId,
|
|
||||||
load_data: LoadData,
|
|
||||||
response_sender: IpcSender<WebDriverLoadStatus>,
|
|
||||||
history_handling: NavigationHistoryBehavior,
|
|
||||||
) {
|
|
||||||
let browsing_context_id = BrowsingContextId::from(webview_id);
|
|
||||||
let pipeline_id = match self.browsing_contexts.get(&browsing_context_id) {
|
|
||||||
Some(browsing_context) => browsing_context.pipeline_id,
|
|
||||||
None => {
|
|
||||||
return warn!(
|
|
||||||
"{}: Webdriver load for closed browsing context",
|
|
||||||
browsing_context_id
|
|
||||||
);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(new_pipeline_id) =
|
|
||||||
self.load_url(webview_id, pipeline_id, load_data, history_handling)
|
|
||||||
{
|
|
||||||
debug!(
|
|
||||||
"Setting up webdriver load notification for {:?}",
|
|
||||||
new_pipeline_id
|
|
||||||
);
|
|
||||||
self.webdriver.load_channel = Some((new_pipeline_id, response_sender));
|
|
||||||
} else {
|
|
||||||
let _ = response_sender.send(WebDriverLoadStatus::Canceled);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[servo_tracing::instrument(skip_all)]
|
#[servo_tracing::instrument(skip_all)]
|
||||||
fn change_session_history(&mut self, change: SessionHistoryChange) {
|
fn change_session_history(&mut self, change: SessionHistoryChange) {
|
||||||
debug!(
|
debug!(
|
||||||
|
|
|
@ -33,11 +33,15 @@ pub enum WebDriverCommandMsg {
|
||||||
/// Get the window size.
|
/// Get the window size.
|
||||||
GetWindowSize(WebViewId, IpcSender<Size2D<i32, DevicePixel>>),
|
GetWindowSize(WebViewId, IpcSender<Size2D<i32, DevicePixel>>),
|
||||||
/// Get the viewport size.
|
/// Get the viewport size.
|
||||||
GetViewportSize(WebViewId, IpcSender<Size2D<f32, CSSPixel>>),
|
GetViewportSize(WebViewId, IpcSender<Size2D<u32, DevicePixel>>),
|
||||||
/// Load a URL in the top-level browsing context with the given ID.
|
/// Load a URL in the top-level browsing context with the given ID.
|
||||||
LoadUrl(WebViewId, ServoUrl, IpcSender<WebDriverLoadStatus>),
|
LoadUrl(WebViewId, ServoUrl, IpcSender<WebDriverLoadStatus>),
|
||||||
/// Refresh the top-level browsing context with the given ID.
|
/// Refresh the top-level browsing context with the given ID.
|
||||||
Refresh(WebViewId, IpcSender<WebDriverLoadStatus>),
|
Refresh(WebViewId, IpcSender<WebDriverLoadStatus>),
|
||||||
|
/// Navigate the webview with the given ID to the previous page in the browsing context's history.
|
||||||
|
GoBack(WebViewId),
|
||||||
|
/// Navigate the webview with the given ID to the next page in the browsing context's history.
|
||||||
|
GoForward(WebViewId),
|
||||||
/// Pass a webdriver command to the script thread of the current pipeline
|
/// Pass a webdriver command to the script thread of the current pipeline
|
||||||
/// of a browsing context.
|
/// of a browsing context.
|
||||||
ScriptCommand(BrowsingContextId, WebDriverScriptCommand),
|
ScriptCommand(BrowsingContextId, WebDriverScriptCommand),
|
||||||
|
|
|
@ -743,10 +743,9 @@ impl Handler {
|
||||||
fn check_viewport_bound(&self, x: f64, y: f64) -> Result<(), ErrorStatus> {
|
fn check_viewport_bound(&self, x: f64, y: f64) -> Result<(), ErrorStatus> {
|
||||||
let (sender, receiver) = ipc::channel().unwrap();
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
let cmd_msg =
|
let cmd_msg =
|
||||||
WebDriverCommandMsg::GetWindowSize(self.session.as_ref().unwrap().webview_id, sender);
|
WebDriverCommandMsg::GetViewportSize(self.session.as_ref().unwrap().webview_id, sender);
|
||||||
self.constellation_chan
|
self.send_message_to_embedder(cmd_msg)
|
||||||
.send(EmbedderToConstellationMessage::WebDriverCommand(cmd_msg))
|
.map_err(|_| ErrorStatus::UnknownError)?;
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let viewport_size = match wait_for_script_response(receiver) {
|
let viewport_size = match wait_for_script_response(receiver) {
|
||||||
Ok(response) => response,
|
Ok(response) => response,
|
||||||
|
|
|
@ -20,7 +20,7 @@ use std::{env, fmt, process, thread};
|
||||||
use base::id::{BrowsingContextId, WebViewId};
|
use base::id::{BrowsingContextId, WebViewId};
|
||||||
use base64::Engine;
|
use base64::Engine;
|
||||||
use capabilities::ServoCapabilities;
|
use capabilities::ServoCapabilities;
|
||||||
use constellation_traits::{EmbedderToConstellationMessage, TraversalDirection};
|
use constellation_traits::EmbedderToConstellationMessage;
|
||||||
use cookie::{CookieBuilder, Expiration};
|
use cookie::{CookieBuilder, Expiration};
|
||||||
use crossbeam_channel::{Receiver, Sender, after, select, unbounded};
|
use crossbeam_channel::{Receiver, Sender, after, select, unbounded};
|
||||||
use embedder_traits::{
|
use embedder_traits::{
|
||||||
|
@ -767,9 +767,7 @@ impl Handler {
|
||||||
|
|
||||||
let cmd_msg =
|
let cmd_msg =
|
||||||
WebDriverCommandMsg::LoadUrl(webview_id, url, self.load_status_sender.clone());
|
WebDriverCommandMsg::LoadUrl(webview_id, url, self.load_status_sender.clone());
|
||||||
self.constellation_chan
|
self.send_message_to_embedder(cmd_msg)?;
|
||||||
.send(EmbedderToConstellationMessage::WebDriverCommand(cmd_msg))
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
self.wait_for_load()
|
self.wait_for_load()
|
||||||
}
|
}
|
||||||
|
@ -902,9 +900,8 @@ impl Handler {
|
||||||
// Step 1. If session's current top-level browsing context is no longer open,
|
// Step 1. If session's current top-level browsing context is no longer open,
|
||||||
// return error with error code no such window.
|
// return error with error code no such window.
|
||||||
self.verify_top_level_browsing_context_is_open(webview_id)?;
|
self.verify_top_level_browsing_context_is_open(webview_id)?;
|
||||||
let direction = TraversalDirection::Back(1);
|
|
||||||
let msg = EmbedderToConstellationMessage::TraverseHistory(webview_id, direction);
|
self.send_message_to_embedder(WebDriverCommandMsg::GoBack(webview_id))?;
|
||||||
self.constellation_chan.send(msg).unwrap();
|
|
||||||
Ok(WebDriverResponse::Void)
|
Ok(WebDriverResponse::Void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -913,9 +910,8 @@ impl Handler {
|
||||||
// Step 1. If session's current top-level browsing context is no longer open,
|
// Step 1. If session's current top-level browsing context is no longer open,
|
||||||
// return error with error code no such window.
|
// return error with error code no such window.
|
||||||
self.verify_top_level_browsing_context_is_open(webview_id)?;
|
self.verify_top_level_browsing_context_is_open(webview_id)?;
|
||||||
let direction = TraversalDirection::Forward(1);
|
|
||||||
let msg = EmbedderToConstellationMessage::TraverseHistory(webview_id, direction);
|
self.send_message_to_embedder(WebDriverCommandMsg::GoForward(webview_id))?;
|
||||||
self.constellation_chan.send(msg).unwrap();
|
|
||||||
Ok(WebDriverResponse::Void)
|
Ok(WebDriverResponse::Void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -926,9 +922,7 @@ impl Handler {
|
||||||
self.verify_top_level_browsing_context_is_open(webview_id)?;
|
self.verify_top_level_browsing_context_is_open(webview_id)?;
|
||||||
|
|
||||||
let cmd_msg = WebDriverCommandMsg::Refresh(webview_id, self.load_status_sender.clone());
|
let cmd_msg = WebDriverCommandMsg::Refresh(webview_id, self.load_status_sender.clone());
|
||||||
self.constellation_chan
|
self.send_message_to_embedder(cmd_msg)?;
|
||||||
.send(EmbedderToConstellationMessage::WebDriverCommand(cmd_msg))
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
self.wait_for_load()
|
self.wait_for_load()
|
||||||
}
|
}
|
||||||
|
@ -2354,6 +2348,8 @@ fn webdriver_value_to_js_argument(v: &Value) -> String {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: This waits for not only the script response
|
||||||
|
// need to make another name
|
||||||
fn wait_for_script_response<T>(receiver: IpcReceiver<T>) -> Result<T, WebDriverError>
|
fn wait_for_script_response<T>(receiver: IpcReceiver<T>) -> Result<T, WebDriverError>
|
||||||
where
|
where
|
||||||
T: for<'de> Deserialize<'de> + Serialize,
|
T: for<'de> Deserialize<'de> + Serialize,
|
||||||
|
|
|
@ -343,7 +343,7 @@ impl App {
|
||||||
},
|
},
|
||||||
WebDriverCommandMsg::NewWebView(response_sender, load_status_sender) => {
|
WebDriverCommandMsg::NewWebView(response_sender, load_status_sender) => {
|
||||||
let new_webview =
|
let new_webview =
|
||||||
running_state.create_toplevel_webview(Url::parse("auto:blank").unwrap());
|
running_state.create_toplevel_webview(Url::parse("about:blank").unwrap());
|
||||||
|
|
||||||
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}");
|
||||||
|
@ -389,22 +389,54 @@ impl App {
|
||||||
warn!("Failed to send window size: {error}");
|
warn!("Failed to send window size: {error}");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
WebDriverCommandMsg::GetViewportSize(_webview_id, response_sender) => {
|
||||||
|
let window = self
|
||||||
|
.windows
|
||||||
|
.values()
|
||||||
|
.next()
|
||||||
|
.expect("Should have at least one window in servoshell");
|
||||||
|
|
||||||
|
let size = window.rendering_context().size2d();
|
||||||
|
|
||||||
|
if let Err(error) = response_sender.send(size) {
|
||||||
|
warn!("Failed to send response of GetViewportSize: {error}");
|
||||||
|
}
|
||||||
|
},
|
||||||
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}");
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
WebDriverCommandMsg::GetViewportSize(..) |
|
WebDriverCommandMsg::LoadUrl(webview_id, url, load_status_sender) => {
|
||||||
WebDriverCommandMsg::LoadUrl(..) |
|
if let Some(webview) = running_state.webview_by_id(webview_id) {
|
||||||
WebDriverCommandMsg::ScriptCommand(..) |
|
webview.load(url.into_url());
|
||||||
|
running_state.set_load_status_sender(webview_id, load_status_sender);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
WebDriverCommandMsg::Refresh(webview_id, load_status_sender) => {
|
||||||
|
if let Some(webview) = running_state.webview_by_id(webview_id) {
|
||||||
|
webview.reload();
|
||||||
|
running_state.set_load_status_sender(webview_id, load_status_sender);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
WebDriverCommandMsg::GoBack(webview_id) => {
|
||||||
|
if let Some(webview) = running_state.webview_by_id(webview_id) {
|
||||||
|
webview.go_back(1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
WebDriverCommandMsg::GoForward(webview_id) => {
|
||||||
|
if let Some(webview) = running_state.webview_by_id(webview_id) {
|
||||||
|
webview.go_forward(1);
|
||||||
|
}
|
||||||
|
},
|
||||||
WebDriverCommandMsg::SendKeys(..) |
|
WebDriverCommandMsg::SendKeys(..) |
|
||||||
WebDriverCommandMsg::KeyboardAction(..) |
|
WebDriverCommandMsg::KeyboardAction(..) |
|
||||||
WebDriverCommandMsg::MouseButtonAction(..) |
|
WebDriverCommandMsg::MouseButtonAction(..) |
|
||||||
WebDriverCommandMsg::MouseMoveAction(..) |
|
WebDriverCommandMsg::MouseMoveAction(..) |
|
||||||
WebDriverCommandMsg::WheelScrollAction(..) |
|
WebDriverCommandMsg::WheelScrollAction(..) |
|
||||||
WebDriverCommandMsg::TakeScreenshot(..) |
|
WebDriverCommandMsg::ScriptCommand(..) |
|
||||||
WebDriverCommandMsg::Refresh(..) => {
|
WebDriverCommandMsg::TakeScreenshot(..) => {
|
||||||
warn!(
|
warn!(
|
||||||
"WebDriverCommand {:?} is still not moved from constellation to embedder",
|
"WebDriverCommand {:?} is still not moved from constellation to embedder",
|
||||||
msg
|
msg
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue