Move webdriver actions commands to servoshell (#37669)

Move webdriver actions commands to servoshell.

Testing: Test with webdriver enable in the CI
[Test result
1](https://github.com/longvatrong111/servo/actions/runs/15875355256)
[Test result
2](https://github.com/longvatrong111/servo/actions/runs/15875356595)
[Test result
3](https://github.com/longvatrong111/servo/actions/runs/15875361886)

Fixes: https://github.com/servo/servo/issues/37370

Signed-off-by: batu_hoang <longvatrong111@gmail.com>
This commit is contained in:
batu_hoang 2025-07-05 00:29:38 +08:00 committed by GitHub
parent 9bd8d4f026
commit 940eff9497
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 126 additions and 208 deletions

View file

@ -62,6 +62,7 @@ euclid = { workspace = true }
getopts = { workspace = true }
hitrace = { workspace = true, optional = true }
image = { workspace = true }
ipc-channel = { workspace = true }
keyboard-types = { workspace = true }
libc = { workspace = true }
libservo = { path = "../../components/servo", features = ["background_hang_monitor", "bluetooth", "testbinding"] }
@ -78,7 +79,6 @@ webdriver_server = { path = "../../components/webdriver_server" }
[target.'cfg(target_os = "android")'.dependencies]
android_logger = "0.15"
ipc-channel = { workspace = true }
jni = "0.21.1"
[target.'cfg(not(target_os = "android"))'.dependencies]

View file

@ -12,14 +12,21 @@ use std::time::Instant;
use std::{env, fs};
use ::servo::ServoBuilder;
use constellation_traits::EmbedderToConstellationMessage;
use crossbeam_channel::unbounded;
use euclid::{Point2D, Vector2D};
use ipc_channel::ipc;
use log::{info, trace, warn};
use net::protocols::ProtocolRegistry;
use servo::config::opts::Opts;
use servo::config::prefs::Preferences;
use servo::servo_url::ServoUrl;
use servo::user_content_manager::{UserContentManager, UserScript};
use servo::{EventLoopWaker, WebDriverCommandMsg};
use servo::webrender_api::ScrollLocation;
use servo::{
EventLoopWaker, InputEvent, MouseButtonEvent, MouseMoveEvent, WebDriverCommandMsg, WheelDelta,
WheelEvent, WheelMode,
};
use url::Url;
use winit::application::ApplicationHandler;
use winit::event::WindowEvent;
@ -162,15 +169,25 @@ impl App {
// Initialize WebDriver server here before `servo` is moved.
let webdriver_receiver = self.servoshell_preferences.webdriver_port.map(|port| {
let (embedder_sender, embedder_receiver) = unbounded();
let (webdriver_response_sender, webdriver_response_receiver) = ipc::channel().unwrap();
// Set the WebDriver response sender to constellation.
// TODO: consider using Servo API to notify embedder about input events completions
servo
.constellation_sender()
.send(EmbedderToConstellationMessage::SetWebDriverResponseSender(
webdriver_response_sender,
))
.unwrap_or_else(|_| {
warn!("Failed to set WebDriver response sender in constellation");
});
// TODO: WebDriver will no longer need this channel once all WebDriver
// commands are executed via the Servo API.
let constellation_sender_deprecated = servo.constellation_sender();
webdriver_server::start_server(
port,
constellation_sender_deprecated,
servo.constellation_sender(),
embedder_sender,
self.waker.clone(),
webdriver_response_receiver,
);
embedder_receiver
@ -331,6 +348,9 @@ impl App {
while let Ok(msg) = webdriver_receiver.try_recv() {
match msg {
WebDriverCommandMsg::SetWebDriverResponseSender(..) => {
running_state.forward_webdriver_command(msg);
},
WebDriverCommandMsg::IsWebViewOpen(webview_id, sender) => {
let context = running_state.webview_by_id(webview_id);
@ -338,8 +358,8 @@ impl App {
warn!("Failed to send response of IsWebViewOpein: {error}");
}
},
webdriver_msg @ WebDriverCommandMsg::IsBrowsingContextOpen(..) => {
running_state.forward_webdriver_command(webdriver_msg);
WebDriverCommandMsg::IsBrowsingContextOpen(..) => {
running_state.forward_webdriver_command(msg);
},
WebDriverCommandMsg::NewWebView(response_sender, load_status_sender) => {
let new_webview =
@ -434,11 +454,68 @@ impl App {
webview.go_forward(1);
}
},
WebDriverCommandMsg::SendKeys(..) |
WebDriverCommandMsg::KeyboardAction(..) |
WebDriverCommandMsg::MouseButtonAction(..) |
WebDriverCommandMsg::MouseMoveAction(..) |
WebDriverCommandMsg::WheelScrollAction(..) |
// Key events don't need hit test so can be forwarded to constellation for now
WebDriverCommandMsg::SendKeys(..) => {
running_state.forward_webdriver_command(msg);
},
WebDriverCommandMsg::KeyboardAction(..) => {
running_state.forward_webdriver_command(msg);
},
WebDriverCommandMsg::MouseButtonAction(
webview_id,
mouse_event_type,
mouse_button,
x,
y,
webdriver_message_id,
) => {
if let Some(webview) = running_state.webview_by_id(webview_id) {
webview.notify_input_event(
InputEvent::MouseButton(MouseButtonEvent::new(
mouse_event_type,
mouse_button,
Point2D::new(x, y),
))
.with_webdriver_message_id(webdriver_message_id),
);
}
},
WebDriverCommandMsg::MouseMoveAction(webview_id, x, y, webdriver_message_id) => {
if let Some(webview) = running_state.webview_by_id(webview_id) {
webview.notify_input_event(
InputEvent::MouseMove(MouseMoveEvent::new(Point2D::new(x, y)))
.with_webdriver_message_id(webdriver_message_id),
);
}
},
WebDriverCommandMsg::WheelScrollAction(
webview_id,
x,
y,
dx,
dy,
webdriver_message_id,
) => {
if let Some(webview) = running_state.webview_by_id(webview_id) {
let delta = WheelDelta {
x: -dx,
y: -dy,
z: 0.0,
mode: WheelMode::DeltaPixel,
};
let point = Point2D::new(x, y);
let scroll_location =
ScrollLocation::Delta(Vector2D::new(dx as f32, dy as f32));
webview.notify_input_event(
InputEvent::Wheel(WheelEvent::new(delta, point))
.with_webdriver_message_id(webdriver_message_id),
);
webview.notify_scroll_event(scroll_location, point.to_i32());
}
},
WebDriverCommandMsg::ScriptCommand(..) |
WebDriverCommandMsg::TakeScreenshot(..) => {
warn!(