mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
[webdriver] Move Webdriver to ServoShell (#36714)
Moving `webdriver` to `servoshell`: - Let `servoshell` manage lifecycle of `webdriver` - One by one, move the handling of webdriver commands from `constellation` to `embedder` Partially fix: https://github.com/servo/servo/issues/37370 Partially fix webdriver test timeout with `no_top_browsing_context` cc: @xiaochengh --------- Signed-off-by: batu_hoang <longvatrong111@gmail.com>
This commit is contained in:
parent
d55e2c4c90
commit
d0100797e8
9 changed files with 156 additions and 35 deletions
|
@ -24,8 +24,8 @@ use constellation_traits::{EmbedderToConstellationMessage, TraversalDirection};
|
|||
use cookie::{CookieBuilder, Expiration};
|
||||
use crossbeam_channel::{Receiver, Sender, after, select, unbounded};
|
||||
use embedder_traits::{
|
||||
MouseButton, WebDriverCommandMsg, WebDriverCommandResponse, WebDriverFrameId, WebDriverJSError,
|
||||
WebDriverJSResult, WebDriverJSValue, WebDriverLoadStatus, WebDriverMessageId,
|
||||
EventLoopWaker, MouseButton, WebDriverCommandMsg, WebDriverCommandResponse, WebDriverFrameId,
|
||||
WebDriverJSError, WebDriverJSResult, WebDriverJSValue, WebDriverLoadStatus, WebDriverMessageId,
|
||||
WebDriverScriptCommand,
|
||||
};
|
||||
use euclid::{Rect, Size2D};
|
||||
|
@ -122,8 +122,17 @@ fn cookie_msg_to_cookie(cookie: cookie::Cookie) -> Cookie {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn start_server(port: u16, constellation_chan: Sender<EmbedderToConstellationMessage>) {
|
||||
let handler = Handler::new(constellation_chan);
|
||||
pub fn start_server(
|
||||
port: u16,
|
||||
constellation_chan_deprecated: Sender<EmbedderToConstellationMessage>,
|
||||
embedder_sender: Sender<WebDriverCommandMsg>,
|
||||
event_loop_waker: Box<dyn EventLoopWaker>,
|
||||
) {
|
||||
let handler = Handler::new(
|
||||
constellation_chan_deprecated,
|
||||
embedder_sender,
|
||||
event_loop_waker,
|
||||
);
|
||||
thread::Builder::new()
|
||||
.name("WebDriverHttpServer".to_owned())
|
||||
.spawn(move || {
|
||||
|
@ -223,10 +232,20 @@ struct Handler {
|
|||
|
||||
session: Option<WebDriverSession>,
|
||||
|
||||
/// A [`Sender`] that sends messages to the embedder that this `WebDriver instance controls.
|
||||
/// In addition to sending a message, we must always wake up the embedder's event loop so it
|
||||
/// knows that more messages are available for processing.
|
||||
embedder_sender: Sender<WebDriverCommandMsg>,
|
||||
|
||||
/// An [`EventLoopWaker`] which is used to wake up the embedder event loop.
|
||||
event_loop_waker: Box<dyn EventLoopWaker>,
|
||||
|
||||
/// The channel for sending Webdriver messages to the constellation.
|
||||
/// TODO: change name to constellation_sender
|
||||
constellation_chan: Sender<EmbedderToConstellationMessage>,
|
||||
|
||||
/// The IPC sender which we can clone and pass along to the constellation
|
||||
/// TODO: change name to webdriver_response_sender
|
||||
constellation_sender: IpcSender<WebDriverCommandResponse>,
|
||||
|
||||
/// Receiver notification from the constellation when a command is completed
|
||||
|
@ -450,7 +469,11 @@ impl<'de> Visitor<'de> for TupleVecMapVisitor {
|
|||
}
|
||||
|
||||
impl Handler {
|
||||
pub fn new(constellation_chan: Sender<EmbedderToConstellationMessage>) -> Handler {
|
||||
pub fn new(
|
||||
constellation_chan: Sender<EmbedderToConstellationMessage>,
|
||||
embedder_sender: Sender<WebDriverCommandMsg>,
|
||||
event_loop_waker: Box<dyn EventLoopWaker>,
|
||||
) -> Handler {
|
||||
// Create a pair of both an IPC and a threaded channel,
|
||||
// keep the IPC sender to clone and pass to the constellation for each load,
|
||||
// and keep a threaded receiver to block on an incoming load-status.
|
||||
|
@ -466,6 +489,8 @@ impl Handler {
|
|||
load_status_sender,
|
||||
load_status_receiver,
|
||||
session: None,
|
||||
embedder_sender,
|
||||
event_loop_waker,
|
||||
constellation_chan,
|
||||
constellation_sender,
|
||||
constellation_receiver,
|
||||
|
@ -482,6 +507,17 @@ impl Handler {
|
|||
.set(self.num_pending_actions.get() + 1);
|
||||
}
|
||||
|
||||
fn send_message_to_embedder(&self, msg: WebDriverCommandMsg) -> WebDriverResult<()> {
|
||||
self.embedder_sender.send(msg).map_err(|_| {
|
||||
WebDriverError::new(
|
||||
ErrorStatus::UnknownError,
|
||||
"Failed to send message to embedder",
|
||||
)
|
||||
})?;
|
||||
self.event_loop_waker.wake();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn focus_webview_id(&self) -> WebDriverResult<WebViewId> {
|
||||
debug!("Getting focused context.");
|
||||
let (sender, receiver) = ipc::channel().unwrap();
|
||||
|
@ -1001,9 +1037,7 @@ impl Handler {
|
|||
// Step 3. Close session's current top-level browsing context.
|
||||
session.window_handles.remove(&webview_id);
|
||||
let cmd_msg = WebDriverCommandMsg::CloseWebView(session.webview_id);
|
||||
self.constellation_chan
|
||||
.send(EmbedderToConstellationMessage::WebDriverCommand(cmd_msg))
|
||||
.unwrap();
|
||||
self.send_message_to_embedder(cmd_msg)?;
|
||||
let window_handles: Vec<String> = self
|
||||
.session()
|
||||
.unwrap()
|
||||
|
@ -1015,6 +1049,7 @@ impl Handler {
|
|||
if window_handles.is_empty() {
|
||||
self.session = None;
|
||||
}
|
||||
|
||||
// Step 5. Return the result of running the remote end steps for the Get Window Handles command
|
||||
Ok(WebDriverResponse::CloseWindow(CloseWindowResponse(
|
||||
window_handles,
|
||||
|
@ -2052,11 +2087,7 @@ impl Handler {
|
|||
webview_id: WebViewId,
|
||||
) -> Result<(), WebDriverError> {
|
||||
let (sender, receiver) = ipc::channel().unwrap();
|
||||
self.constellation_chan
|
||||
.send(EmbedderToConstellationMessage::WebDriverCommand(
|
||||
WebDriverCommandMsg::IsWebViewOpen(webview_id, sender),
|
||||
))
|
||||
.unwrap();
|
||||
self.send_message_to_embedder(WebDriverCommandMsg::IsWebViewOpen(webview_id, sender))?;
|
||||
if !receiver.recv().unwrap_or(false) {
|
||||
Err(WebDriverError::new(
|
||||
ErrorStatus::NoSuchWindow,
|
||||
|
@ -2072,11 +2103,10 @@ impl Handler {
|
|||
browsing_context_id: BrowsingContextId,
|
||||
) -> Result<(), WebDriverError> {
|
||||
let (sender, receiver) = ipc::channel().unwrap();
|
||||
self.constellation_chan
|
||||
.send(EmbedderToConstellationMessage::WebDriverCommand(
|
||||
WebDriverCommandMsg::IsBrowsingContextOpen(browsing_context_id, sender),
|
||||
))
|
||||
.unwrap();
|
||||
self.send_message_to_embedder(WebDriverCommandMsg::IsBrowsingContextOpen(
|
||||
browsing_context_id,
|
||||
sender,
|
||||
))?;
|
||||
if !receiver.recv().unwrap_or(false) {
|
||||
Err(WebDriverError::new(
|
||||
ErrorStatus::NoSuchWindow,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue