mirror of
https://github.com/servo/servo.git
synced 2025-08-29 17:18:23 +01:00
webdriver: Port WebDriverLoadStatus to Generic Channel (#38915)
Ports the channel for WebDriverLoadStatus to GenericChannel. Testing: No functional changes - Covered by existing webdriver tests Part of #38912 Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
This commit is contained in:
parent
4a19f66c31
commit
ebf8a35c84
6 changed files with 37 additions and 26 deletions
|
@ -418,7 +418,7 @@ pub struct Constellation<STF, SWF> {
|
||||||
next_pipeline_namespace_id: PipelineNamespaceId,
|
next_pipeline_namespace_id: PipelineNamespaceId,
|
||||||
|
|
||||||
/// An [`IpcSender`] to notify navigation events to webdriver.
|
/// An [`IpcSender`] to notify navigation events to webdriver.
|
||||||
webdriver_load_status_sender: Option<(IpcSender<WebDriverLoadStatus>, PipelineId)>,
|
webdriver_load_status_sender: Option<(GenericSender<WebDriverLoadStatus>, PipelineId)>,
|
||||||
|
|
||||||
/// An [`IpcSender`] to forward responses from the `ScriptThread` to the WebDriver server.
|
/// An [`IpcSender`] to forward responses from the `ScriptThread` to the WebDriver server.
|
||||||
webdriver_input_command_reponse_sender: Option<IpcSender<WebDriverCommandResponse>>,
|
webdriver_input_command_reponse_sender: Option<IpcSender<WebDriverCommandResponse>>,
|
||||||
|
|
|
@ -326,7 +326,7 @@ pub(crate) struct Window {
|
||||||
|
|
||||||
/// A channel to notify webdriver if there is a navigation
|
/// A channel to notify webdriver if there is a navigation
|
||||||
#[no_trace]
|
#[no_trace]
|
||||||
webdriver_load_status_sender: RefCell<Option<IpcSender<WebDriverLoadStatus>>>,
|
webdriver_load_status_sender: RefCell<Option<GenericSender<WebDriverLoadStatus>>>,
|
||||||
|
|
||||||
/// The current state of the window object
|
/// The current state of the window object
|
||||||
current_state: Cell<WindowState>,
|
current_state: Cell<WindowState>,
|
||||||
|
@ -2863,7 +2863,7 @@ impl Window {
|
||||||
|
|
||||||
pub(crate) fn set_webdriver_load_status_sender(
|
pub(crate) fn set_webdriver_load_status_sender(
|
||||||
&self,
|
&self,
|
||||||
sender: Option<IpcSender<WebDriverLoadStatus>>,
|
sender: Option<GenericSender<WebDriverLoadStatus>>,
|
||||||
) {
|
) {
|
||||||
*self.webdriver_load_status_sender.borrow_mut() = sender;
|
*self.webdriver_load_status_sender.borrow_mut() = sender;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ use std::collections::{HashMap, HashSet};
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
|
use base::generic_channel::GenericSender;
|
||||||
use base::id::{BrowsingContextId, PipelineId};
|
use base::id::{BrowsingContextId, PipelineId};
|
||||||
use cookie::Cookie;
|
use cookie::Cookie;
|
||||||
use embedder_traits::{
|
use embedder_traits::{
|
||||||
|
@ -2066,7 +2067,7 @@ pub(crate) fn handle_is_selected(
|
||||||
pub(crate) fn handle_add_load_status_sender(
|
pub(crate) fn handle_add_load_status_sender(
|
||||||
documents: &DocumentCollection,
|
documents: &DocumentCollection,
|
||||||
pipeline: PipelineId,
|
pipeline: PipelineId,
|
||||||
reply: IpcSender<WebDriverLoadStatus>,
|
reply: GenericSender<WebDriverLoadStatus>,
|
||||||
) {
|
) {
|
||||||
if let Some(document) = documents.find_document(pipeline) {
|
if let Some(document) = documents.find_document(pipeline) {
|
||||||
let window = document.window();
|
let window = document.window();
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use base::generic_channel::GenericSender;
|
||||||
use base::id::{BrowsingContextId, WebViewId};
|
use base::id::{BrowsingContextId, WebViewId};
|
||||||
use cookie::Cookie;
|
use cookie::Cookie;
|
||||||
use euclid::default::Rect as UntypedRect;
|
use euclid::default::Rect as UntypedRect;
|
||||||
|
@ -81,13 +82,13 @@ pub enum WebDriverCommandMsg {
|
||||||
/// Get the viewport size.
|
/// Get the viewport size.
|
||||||
GetViewportSize(WebViewId, IpcSender<Size2D<u32, DevicePixel>>),
|
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, GenericSender<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, GenericSender<WebDriverLoadStatus>),
|
||||||
/// Navigate the webview with the given ID to the previous page in the browsing context's history.
|
/// Navigate the webview with the given ID to the previous page in the browsing context's history.
|
||||||
GoBack(WebViewId, IpcSender<WebDriverLoadStatus>),
|
GoBack(WebViewId, GenericSender<WebDriverLoadStatus>),
|
||||||
/// Navigate the webview with the given ID to the next page in the browsing context's history.
|
/// Navigate the webview with the given ID to the next page in the browsing context's history.
|
||||||
GoForward(WebViewId, IpcSender<WebDriverLoadStatus>),
|
GoForward(WebViewId, GenericSender<WebDriverLoadStatus>),
|
||||||
/// 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),
|
||||||
|
@ -147,7 +148,10 @@ pub enum WebDriverCommandMsg {
|
||||||
/// Create a new webview that loads about:blank. The embedder 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 sets a "load status sender" if provided.
|
/// associated with the new webview, and sets a "load status sender" if provided.
|
||||||
NewWebView(IpcSender<WebViewId>, Option<IpcSender<WebDriverLoadStatus>>),
|
NewWebView(
|
||||||
|
IpcSender<WebViewId>,
|
||||||
|
Option<GenericSender<WebDriverLoadStatus>>,
|
||||||
|
),
|
||||||
/// Close the webview associated with the provided id.
|
/// Close the webview associated with the provided id.
|
||||||
CloseWebView(WebViewId, IpcSender<()>),
|
CloseWebView(WebViewId, IpcSender<()>),
|
||||||
/// Focus the webview associated with the provided id.
|
/// Focus the webview associated with the provided id.
|
||||||
|
@ -243,7 +247,7 @@ pub enum WebDriverScriptCommand {
|
||||||
GetTitle(IpcSender<String>),
|
GetTitle(IpcSender<String>),
|
||||||
/// Deal with the case of input element for Element Send Keys, which does not send keys.
|
/// Deal with the case of input element for Element Send Keys, which does not send keys.
|
||||||
WillSendKeys(String, String, bool, IpcSender<Result<bool, ErrorStatus>>),
|
WillSendKeys(String, String, bool, IpcSender<Result<bool, ErrorStatus>>),
|
||||||
AddLoadStatusSender(WebViewId, IpcSender<WebDriverLoadStatus>),
|
AddLoadStatusSender(WebViewId, GenericSender<WebDriverLoadStatus>),
|
||||||
RemoveLoadStatusSender(WebViewId),
|
RemoveLoadStatusSender(WebViewId),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,8 +293,8 @@ pub enum WebDriverLoadStatus {
|
||||||
/// to a WebDriver server with information about application state.
|
/// to a WebDriver server with information about application state.
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub struct WebDriverSenders {
|
pub struct WebDriverSenders {
|
||||||
pub load_status_senders: HashMap<WebViewId, IpcSender<WebDriverLoadStatus>>,
|
pub load_status_senders: HashMap<WebViewId, GenericSender<WebDriverLoadStatus>>,
|
||||||
pub script_evaluation_interrupt_sender: Option<IpcSender<WebDriverJSResult>>,
|
pub script_evaluation_interrupt_sender: Option<IpcSender<WebDriverJSResult>>,
|
||||||
pub pending_traversals: HashMap<TraversalId, IpcSender<WebDriverLoadStatus>>,
|
pub pending_traversals: HashMap<TraversalId, GenericSender<WebDriverLoadStatus>>,
|
||||||
pub pending_focus: HashMap<FocusId, IpcSender<bool>>,
|
pub pending_focus: HashMap<FocusId, IpcSender<bool>>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,11 +21,12 @@ use std::net::{SocketAddr, SocketAddrV4};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::{env, fmt, process, thread};
|
use std::{env, fmt, process, thread};
|
||||||
|
|
||||||
|
use base::generic_channel::{self, GenericSender, RoutedReceiver};
|
||||||
use base::id::{BrowsingContextId, WebViewId};
|
use base::id::{BrowsingContextId, WebViewId};
|
||||||
use base64::Engine;
|
use base64::Engine;
|
||||||
use capabilities::ServoCapabilities;
|
use capabilities::ServoCapabilities;
|
||||||
use cookie::{CookieBuilder, Expiration, SameSite};
|
use cookie::{CookieBuilder, Expiration, SameSite};
|
||||||
use crossbeam_channel::{Receiver, Sender, after, select, unbounded};
|
use crossbeam_channel::{Sender, after, select};
|
||||||
use embedder_traits::{
|
use embedder_traits::{
|
||||||
EventLoopWaker, JSValue, MouseButton, WebDriverCommandMsg, WebDriverCommandResponse,
|
EventLoopWaker, JSValue, MouseButton, WebDriverCommandMsg, WebDriverCommandResponse,
|
||||||
WebDriverFrameId, WebDriverJSError, WebDriverJSResult, WebDriverLoadStatus, WebDriverMessageId,
|
WebDriverFrameId, WebDriverJSError, WebDriverJSResult, WebDriverLoadStatus, WebDriverMessageId,
|
||||||
|
@ -34,8 +35,7 @@ use embedder_traits::{
|
||||||
use euclid::{Point2D, Rect, Size2D};
|
use euclid::{Point2D, Rect, Size2D};
|
||||||
use http::method::Method;
|
use http::method::Method;
|
||||||
use image::{DynamicImage, ImageFormat, RgbaImage};
|
use image::{DynamicImage, ImageFormat, RgbaImage};
|
||||||
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
|
use ipc_channel::ipc::{self, IpcReceiver};
|
||||||
use ipc_channel::router::ROUTER;
|
|
||||||
use keyboard_types::webdriver::{Event as DispatchStringEvent, KeyInputState, send_keys};
|
use keyboard_types::webdriver::{Event as DispatchStringEvent, KeyInputState, send_keys};
|
||||||
use keyboard_types::{Code, Key, KeyState, KeyboardEvent, Location, NamedKey};
|
use keyboard_types::{Code, Key, KeyState, KeyboardEvent, Location, NamedKey};
|
||||||
use log::{debug, error, info};
|
use log::{debug, error, info};
|
||||||
|
@ -166,11 +166,11 @@ struct Handler {
|
||||||
/// The threaded receiver on which we can block for a load-status.
|
/// The threaded receiver on which we can block for a load-status.
|
||||||
/// It will receive messages sent on the load_status_sender,
|
/// It will receive messages sent on the load_status_sender,
|
||||||
/// and forwarded by the IPC router.
|
/// and forwarded by the IPC router.
|
||||||
load_status_receiver: Receiver<WebDriverLoadStatus>,
|
load_status_receiver: RoutedReceiver<WebDriverLoadStatus>,
|
||||||
/// The IPC sender which we can clone and pass along to the constellation,
|
/// The IPC sender which we can clone and pass along to the constellation,
|
||||||
/// for it to send us a load-status. Messages sent on it
|
/// for it to send us a load-status. Messages sent on it
|
||||||
/// will be forwarded to the load_status_receiver.
|
/// will be forwarded to the load_status_receiver.
|
||||||
load_status_sender: IpcSender<WebDriverLoadStatus>,
|
load_status_sender: GenericSender<WebDriverLoadStatus>,
|
||||||
|
|
||||||
session: Option<WebDriverSession>,
|
session: Option<WebDriverSession>,
|
||||||
|
|
||||||
|
@ -415,9 +415,8 @@ impl Handler {
|
||||||
// and keep a threaded receiver to block on an incoming load-status.
|
// and keep a threaded receiver to block on an incoming load-status.
|
||||||
// Pass the others to the IPC router so that IPC messages are forwarded to the threaded receiver.
|
// Pass the others to the IPC router so that IPC messages are forwarded to the threaded receiver.
|
||||||
// We need to use the router because IPC does not come with a timeout on receive/select.
|
// We need to use the router because IPC does not come with a timeout on receive/select.
|
||||||
let (load_status_sender, receiver) = ipc::channel().unwrap();
|
let (load_status_sender, receiver) = generic_channel::channel().unwrap();
|
||||||
let (sender, load_status_receiver) = unbounded();
|
let load_status_receiver = receiver.route_preserving_errors();
|
||||||
ROUTER.route_ipc_receiver_to_crossbeam_sender(receiver, sender);
|
|
||||||
|
|
||||||
Handler {
|
Handler {
|
||||||
load_status_sender,
|
load_status_sender,
|
||||||
|
@ -708,7 +707,7 @@ impl Handler {
|
||||||
recv(self.load_status_receiver) -> res => {
|
recv(self.load_status_receiver) -> res => {
|
||||||
match res {
|
match res {
|
||||||
// If the navigation is navigation to IFrame, no document state event is fired.
|
// If the navigation is navigation to IFrame, no document state event is fired.
|
||||||
Ok(WebDriverLoadStatus::Blocked) => {
|
Ok(Ok(WebDriverLoadStatus::Blocked)) => {
|
||||||
// TODO: evaluate the correctness later
|
// TODO: evaluate the correctness later
|
||||||
// Load status is block means an user prompt is shown.
|
// Load status is block means an user prompt is shown.
|
||||||
// Alot of tests expect this to return success
|
// Alot of tests expect this to return success
|
||||||
|
@ -717,8 +716,8 @@ impl Handler {
|
||||||
// an error anyway.
|
// an error anyway.
|
||||||
Ok(WebDriverResponse::Void)
|
Ok(WebDriverResponse::Void)
|
||||||
},
|
},
|
||||||
Ok(WebDriverLoadStatus::Complete) |
|
Ok(Ok(WebDriverLoadStatus::Complete)) |
|
||||||
Ok(WebDriverLoadStatus::NavigationStop) =>
|
Ok(Ok(WebDriverLoadStatus::NavigationStop)) =>
|
||||||
Ok(WebDriverResponse::Void)
|
Ok(WebDriverResponse::Void)
|
||||||
,
|
,
|
||||||
_ => Err(WebDriverError::new(
|
_ => Err(WebDriverError::new(
|
||||||
|
@ -738,7 +737,7 @@ impl Handler {
|
||||||
/// <https://w3c.github.io/webdriver/#dfn-wait-for-navigation-to-complete>
|
/// <https://w3c.github.io/webdriver/#dfn-wait-for-navigation-to-complete>
|
||||||
fn wait_for_navigation(&self) -> WebDriverResult<WebDriverResponse> {
|
fn wait_for_navigation(&self) -> WebDriverResult<WebDriverResponse> {
|
||||||
let navigation_status = match self.load_status_receiver.try_recv() {
|
let navigation_status = match self.load_status_receiver.try_recv() {
|
||||||
Ok(status) => status,
|
Ok(Ok(status)) => status,
|
||||||
// Empty channel means no navigation started. Nothing to wait for.
|
// Empty channel means no navigation started. Nothing to wait for.
|
||||||
Err(crossbeam_channel::TryRecvError::Empty) => {
|
Err(crossbeam_channel::TryRecvError::Empty) => {
|
||||||
return Ok(WebDriverResponse::Void);
|
return Ok(WebDriverResponse::Void);
|
||||||
|
@ -749,6 +748,12 @@ impl Handler {
|
||||||
"Load status channel disconnected",
|
"Load status channel disconnected",
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
|
Ok(Err(ipc_error)) => {
|
||||||
|
return Err(WebDriverError::new(
|
||||||
|
ErrorStatus::UnknownError,
|
||||||
|
format!("Load status channel ipc error: {ipc_error}"),
|
||||||
|
));
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
match navigation_status {
|
match navigation_status {
|
||||||
|
|
|
@ -13,6 +13,7 @@ use embedder_traits::webdriver::WebDriverSenders;
|
||||||
use euclid::Vector2D;
|
use euclid::Vector2D;
|
||||||
use keyboard_types::{Key, Modifiers, NamedKey, ShortcutMatcher};
|
use keyboard_types::{Key, Modifiers, NamedKey, ShortcutMatcher};
|
||||||
use log::{error, info};
|
use log::{error, info};
|
||||||
|
use servo::base::generic_channel::GenericSender;
|
||||||
use servo::base::id::WebViewId;
|
use servo::base::id::WebViewId;
|
||||||
use servo::config::pref;
|
use servo::config::pref;
|
||||||
use servo::ipc_channel::ipc::IpcSender;
|
use servo::ipc_channel::ipc::IpcSender;
|
||||||
|
@ -456,7 +457,7 @@ impl RunningAppState {
|
||||||
pub(crate) fn set_pending_traversal(
|
pub(crate) fn set_pending_traversal(
|
||||||
&self,
|
&self,
|
||||||
traversal_id: TraversalId,
|
traversal_id: TraversalId,
|
||||||
sender: IpcSender<WebDriverLoadStatus>,
|
sender: GenericSender<WebDriverLoadStatus>,
|
||||||
) {
|
) {
|
||||||
self.webdriver_senders
|
self.webdriver_senders
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
|
@ -467,7 +468,7 @@ impl RunningAppState {
|
||||||
pub(crate) fn set_load_status_sender(
|
pub(crate) fn set_load_status_sender(
|
||||||
&self,
|
&self,
|
||||||
webview_id: WebViewId,
|
webview_id: WebViewId,
|
||||||
sender: IpcSender<WebDriverLoadStatus>,
|
sender: GenericSender<WebDriverLoadStatus>,
|
||||||
) {
|
) {
|
||||||
self.webdriver_senders
|
self.webdriver_senders
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue