Skip to content
Permalink
Browse files

Implement pointerMove webdriver action

  • Loading branch information...
georgeroman committed Jul 30, 2019
1 parent 2a9b2fe commit f064883e07e7ad27a44d93d03a46a05bb3b6a24a
@@ -522,19 +522,21 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
Msg::WebDriverMouseButtonEvent(mouse_event_type, mouse_button, x, y),
ShutdownState::NotShuttingDown,
) => {
let dppx = self.device_pixels_per_page_px();
let point = dppx.transform_point(Point2D::new(x, y));
self.on_mouse_window_event_class(match mouse_event_type {
MouseEventType::Click => {
MouseWindowEvent::Click(mouse_button, DevicePoint::new(x, y))
},
MouseEventType::MouseDown => {
MouseWindowEvent::MouseDown(mouse_button, DevicePoint::new(x, y))
},
MouseEventType::MouseUp => {
MouseWindowEvent::MouseUp(mouse_button, DevicePoint::new(x, y))
},
MouseEventType::Click => MouseWindowEvent::Click(mouse_button, point),
MouseEventType::MouseDown => MouseWindowEvent::MouseDown(mouse_button, point),
MouseEventType::MouseUp => MouseWindowEvent::MouseUp(mouse_button, point),
});
},

(Msg::WebDriverMouseMoveEvent(x, y), ShutdownState::NotShuttingDown) => {
let dppx = self.device_pixels_per_page_px();
let point = dppx.transform_point(Point2D::new(x, y));
self.on_mouse_window_move_event_class(DevicePoint::new(point.x, point.y));
},

(Msg::PendingPaintMetric(pipeline_id, epoch), _) => {
self.pending_paint_metrics.insert(pipeline_id, epoch);
},
@@ -110,6 +110,8 @@ pub enum Msg {
LoadComplete(TopLevelBrowsingContextId),
/// WebDriver mouse button event
WebDriverMouseButtonEvent(MouseEventType, MouseButton, f32, f32),
/// WebDriver mouse move event
WebDriverMouseMoveEvent(f32, f32),

/// Get Window Informations size and position.
GetClientWindow(IpcSender<(DeviceIntSize, DeviceIntPoint)>),
@@ -137,6 +139,7 @@ impl Debug for Msg {
Msg::PendingPaintMetric(..) => write!(f, "PendingPaintMetric"),
Msg::LoadComplete(..) => write!(f, "LoadComplete"),
Msg::WebDriverMouseButtonEvent(..) => write!(f, "WebDriverMouseButtonEvent"),
Msg::WebDriverMouseMoveEvent(..) => write!(f, "WebDriverMouseMoveEvent"),
Msg::GetClientWindow(..) => write!(f, "GetClientWindow"),
Msg::GetScreenSize(..) => write!(f, "GetScreenSize"),
Msg::GetScreenAvailSize(..) => write!(f, "GetScreenAvailSize"),
@@ -3528,6 +3528,10 @@ where
y,
));
},
WebDriverCommandMsg::MouseMoveAction(x, y) => {
self.compositor_proxy
.send(ToCompositorMsg::WebDriverMouseMoveEvent(x, y));
},
WebDriverCommandMsg::TakeScreenshot(_, rect, reply) => {
self.compositor_proxy
.send(ToCompositorMsg::CreatePng(rect, reply));
@@ -2209,6 +2209,14 @@ impl ScriptThread {
WebDriverScriptCommand::GetElementText(node_id, reply) => {
webdriver_handlers::handle_get_text(&*documents, pipeline_id, node_id, reply)
},
WebDriverScriptCommand::GetElementInViewCenterPoint(node_id, reply) => {
webdriver_handlers::handle_get_element_in_view_center_point(
&*documents,
pipeline_id,
node_id,
reply,
)
},
WebDriverScriptCommand::GetBrowsingContextId(webdriver_frame_id, reply) => {
webdriver_handlers::handle_get_browsing_context_id(
&*documents,
@@ -53,6 +53,7 @@ use script_traits::webdriver_msg::{
WebDriverFrameId, WebDriverJSError, WebDriverJSResult, WebDriverJSValue,
};
use servo_url::ServoUrl;
use std::cmp;
use std::collections::HashMap;
use std::ffi::CString;
use webdriver::common::{WebElement, WebFrame, WebWindow};
@@ -360,6 +361,56 @@ pub fn handle_get_browsing_context_id(
.unwrap();
}

// https://w3c.github.io/webdriver/#dfn-center-point
fn get_element_in_view_center_point(element: &Element) -> Option<Point2D<i64>> {
element
.GetClientRects()
.iter()
// Step 1
.next()
.map(|rectangle| {
let x = rectangle.X().round() as i64;
let y = rectangle.Y().round() as i64;
let width = rectangle.Width().round() as i64;
let height = rectangle.Height().round() as i64;

let window = window_from_node(element.upcast::<Node>());
let document = window.Document();
let document_element = document.upcast::<Node>().downcast::<Element>().unwrap();
let clientWidth = document_element.ClientWidth() as i64;
let clientHeight = document_element.ClientHeight() as i64;

// Steps 2 - 5
let left = cmp::max(0, cmp::min(x, x + width));
let right = cmp::min(clientWidth, cmp::max(x, x + width));
let top = cmp::max(0, cmp::min(y, y + height));
let bottom = cmp::min(clientHeight, cmp::max(y, y + height));

// Steps 6 - 7
let x = (left + right) / 2;
let y = (top + bottom) / 2;

// Step 8
Point2D::new(x, y)
})
}

pub fn handle_get_element_in_view_center_point(
documents: &Documents,
pipeline: PipelineId,
element_id: String,
reply: IpcSender<Result<Option<(i64, i64)>, ErrorStatus>>,
) {
reply
.send(
find_node_by_unique_id(documents, pipeline, element_id).map(|node| {
get_element_in_view_center_point(node.downcast::<Element>().unwrap())
.map(|point| (point.x, point.y))
}),
)
.unwrap();
}

pub fn handle_find_element_css(
documents: &Documents,
pipeline: PipelineId,
@@ -797,6 +797,8 @@ pub enum WebDriverCommandMsg {
KeyboardAction(BrowsingContextId, KeyboardEvent),
/// Act as if the mouse was clicked in the browsing context with the given ID.
MouseButtonAction(MouseEventType, MouseButton, f32, f32),
/// Act as if the mouse was moved in the browsing context with the given ID.
MouseMoveAction(f32, f32),
/// Set the window size.
SetWindowSize(
TopLevelBrowsingContextId,
@@ -75,6 +75,7 @@ pub enum WebDriverScriptCommand {
GetElementRect(String, IpcSender<Result<Rect<f64>, ErrorStatus>>),
GetElementTagName(String, IpcSender<Result<String, ErrorStatus>>),
GetElementText(String, IpcSender<Result<String, ErrorStatus>>),
GetElementInViewCenterPoint(String, IpcSender<Result<Option<(i64, i64)>, ErrorStatus>>),
GetBoundingClientRect(String, IpcSender<Result<Rect<f32>, ErrorStatus>>),
GetBrowsingContextId(
WebDriverFrameId,

0 comments on commit f064883

Please sign in to comment.
You can’t perform that action at this time.