mirror of
https://github.com/servo/servo.git
synced 2025-08-04 21:20:23 +01:00
Implement webdriver release action (#37484)
- Implement webdriver release action. - Improve `Input Cancel List`. Testing: `./mach test-wpt -r --product servodriver ./tests/wpt/tests/webdriver/tests/classic/release_actions/sequence.py` cc: @xiaochengh --------- Signed-off-by: batu_hoang <longvatrong111@gmail.com>
This commit is contained in:
parent
212ce933e5
commit
49be5ca05a
3 changed files with 57 additions and 23 deletions
|
@ -31,7 +31,7 @@ static WHEELSCROLL_INTERVAL: u64 = 17;
|
||||||
// In the spec, `action item` refers to a plain JSON object.
|
// In the spec, `action item` refers to a plain JSON object.
|
||||||
// However, we use the name ActionItem here
|
// However, we use the name ActionItem here
|
||||||
// to be consistent with type names from webdriver crate.
|
// to be consistent with type names from webdriver crate.
|
||||||
#[derive(Debug)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub(crate) enum ActionItem {
|
pub(crate) enum ActionItem {
|
||||||
Null(NullActionItem),
|
Null(NullActionItem),
|
||||||
Key(KeyActionItem),
|
Key(KeyActionItem),
|
||||||
|
@ -222,7 +222,6 @@ impl Handler {
|
||||||
},
|
},
|
||||||
ActionItem::Key(KeyActionItem::Key(KeyAction::Down(keydown_action))) => {
|
ActionItem::Key(KeyActionItem::Key(KeyAction::Down(keydown_action))) => {
|
||||||
self.dispatch_keydown_action(input_id, keydown_action);
|
self.dispatch_keydown_action(input_id, keydown_action);
|
||||||
|
|
||||||
// Step 9. If subtype is "keyDown", append a copy of action
|
// Step 9. If subtype is "keyDown", append a copy of action
|
||||||
// object with the subtype property changed to "keyUp" to
|
// object with the subtype property changed to "keyUp" to
|
||||||
// input state's input cancel list.
|
// input state's input cancel list.
|
||||||
|
@ -230,11 +229,12 @@ impl Handler {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.input_cancel_list
|
.input_cancel_list
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.push(ActionItem::Key(KeyActionItem::Key(KeyAction::Up(
|
.push((
|
||||||
KeyUpAction {
|
input_id.clone(),
|
||||||
|
ActionItem::Key(KeyActionItem::Key(KeyAction::Up(KeyUpAction {
|
||||||
value: keydown_action.value.clone(),
|
value: keydown_action.value.clone(),
|
||||||
},
|
}))),
|
||||||
))));
|
));
|
||||||
},
|
},
|
||||||
ActionItem::Key(KeyActionItem::Key(KeyAction::Up(keyup_action))) => {
|
ActionItem::Key(KeyActionItem::Key(KeyAction::Up(keyup_action))) => {
|
||||||
self.dispatch_keyup_action(input_id, keyup_action);
|
self.dispatch_keyup_action(input_id, keyup_action);
|
||||||
|
@ -246,18 +246,22 @@ impl Handler {
|
||||||
pointer_down_action,
|
pointer_down_action,
|
||||||
))) => {
|
))) => {
|
||||||
self.dispatch_pointerdown_action(input_id, pointer_down_action);
|
self.dispatch_pointerdown_action(input_id, pointer_down_action);
|
||||||
|
|
||||||
// Step 10. If subtype is "pointerDown", append a copy of action
|
// Step 10. If subtype is "pointerDown", append a copy of action
|
||||||
// object with the subtype property changed to "pointerUp" to
|
// object with the subtype property changed to "pointerUp" to
|
||||||
// input state's input cancel list.
|
// input state's input cancel list.
|
||||||
self.session().unwrap().input_cancel_list.borrow_mut().push(
|
self.session()
|
||||||
ActionItem::Pointer(PointerActionItem::Pointer(PointerAction::Up(
|
.unwrap()
|
||||||
PointerUpAction {
|
.input_cancel_list
|
||||||
button: pointer_down_action.button,
|
.borrow_mut()
|
||||||
..Default::default()
|
.push((
|
||||||
},
|
input_id.clone(),
|
||||||
))),
|
ActionItem::Pointer(PointerActionItem::Pointer(PointerAction::Up(
|
||||||
);
|
PointerUpAction {
|
||||||
|
button: pointer_down_action.button,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
))),
|
||||||
|
));
|
||||||
},
|
},
|
||||||
ActionItem::Pointer(PointerActionItem::Pointer(PointerAction::Move(
|
ActionItem::Pointer(PointerActionItem::Pointer(PointerAction::Move(
|
||||||
pointer_move_action,
|
pointer_move_action,
|
||||||
|
|
|
@ -64,7 +64,7 @@ use webdriver::response::{
|
||||||
};
|
};
|
||||||
use webdriver::server::{self, Session, SessionTeardownKind, WebDriverHandler};
|
use webdriver::server::{self, Session, SessionTeardownKind, WebDriverHandler};
|
||||||
|
|
||||||
use crate::actions::{ActionItem, InputSourceState, PointerInputState};
|
use crate::actions::{ActionItem, ActionsByTick, InputSourceState, PointerInputState};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct WebDriverMessageIdGenerator {
|
pub struct WebDriverMessageIdGenerator {
|
||||||
|
@ -143,11 +143,19 @@ pub fn start_server(port: u16, constellation_chan: Sender<EmbedderToConstellatio
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents the current WebDriver session and holds relevant session state.
|
/// Represents the current WebDriver session and holds relevant session state.
|
||||||
|
/// Currently, only 1 webview is supported per session.
|
||||||
|
/// So only there is only 1 InputState.
|
||||||
pub struct WebDriverSession {
|
pub struct WebDriverSession {
|
||||||
|
/// <https://www.w3.org/TR/webdriver2/#dfn-session-id>
|
||||||
id: Uuid,
|
id: Uuid,
|
||||||
browsing_context_id: BrowsingContextId,
|
|
||||||
|
/// <https://www.w3.org/TR/webdriver2/#dfn-current-top-level-browsing-context>
|
||||||
webview_id: WebViewId,
|
webview_id: WebViewId,
|
||||||
|
|
||||||
|
/// <https://www.w3.org/TR/webdriver2/#dfn-current-browsing-context>
|
||||||
|
browsing_context_id: BrowsingContextId,
|
||||||
|
|
||||||
|
/// <https://www.w3.org/TR/webdriver2/#dfn-window-handles>
|
||||||
window_handles: HashMap<WebViewId, String>,
|
window_handles: HashMap<WebViewId, String>,
|
||||||
|
|
||||||
/// Time to wait for injected scripts to run before interrupting them. A [`None`] value
|
/// Time to wait for injected scripts to run before interrupting them. A [`None`] value
|
||||||
|
@ -171,7 +179,7 @@ pub struct WebDriverSession {
|
||||||
input_state_table: RefCell<HashMap<String, InputSourceState>>,
|
input_state_table: RefCell<HashMap<String, InputSourceState>>,
|
||||||
|
|
||||||
/// <https://w3c.github.io/webdriver/#dfn-input-cancel-list>
|
/// <https://w3c.github.io/webdriver/#dfn-input-cancel-list>
|
||||||
input_cancel_list: RefCell<Vec<ActionItem>>,
|
input_cancel_list: RefCell<Vec<(String, ActionItem)>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WebDriverSession {
|
impl WebDriverSession {
|
||||||
|
@ -201,6 +209,8 @@ impl WebDriverSession {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The `Handler` for the WebDriver server.
|
||||||
|
/// Currently, only 1 session is supported.
|
||||||
struct Handler {
|
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,
|
||||||
|
@ -1614,12 +1624,35 @@ impl Handler {
|
||||||
|
|
||||||
/// <https://w3c.github.io/webdriver/#dfn-release-actions>
|
/// <https://w3c.github.io/webdriver/#dfn-release-actions>
|
||||||
fn handle_release_actions(&mut self) -> WebDriverResult<WebDriverResponse> {
|
fn handle_release_actions(&mut self) -> WebDriverResult<WebDriverResponse> {
|
||||||
// TODO: The previous implementation of this function was different from the spec.
|
|
||||||
// Need to re-implement this to match the spec.
|
|
||||||
let session = self.session()?;
|
let session = self.session()?;
|
||||||
|
|
||||||
// Step 1. If session's current browsing context is no longer open,
|
// Step 1. If session's current browsing context is no longer open,
|
||||||
// return error with error code no such window.
|
// return error with error code no such window.
|
||||||
self.verify_browsing_context_is_open(session.browsing_context_id)?;
|
self.verify_browsing_context_is_open(session.browsing_context_id)?;
|
||||||
|
|
||||||
|
// TODO: Step 2. User prompts. No user prompt implemented yet.
|
||||||
|
// TODO: Step 3. Skip for now because webdriver holds only one session.
|
||||||
|
// TODO: Step 4. Actions options are not used yet.
|
||||||
|
// TODO: Step 5. Skip for now because webdriver holds only one session.
|
||||||
|
|
||||||
|
// Step 6. Let undo actions be input cancel list in reverse order.
|
||||||
|
let mut input_cancel_list = session.input_cancel_list.borrow_mut();
|
||||||
|
let undo_actions: ActionsByTick = input_cancel_list
|
||||||
|
.drain(..)
|
||||||
|
.rev()
|
||||||
|
.map(|action| {
|
||||||
|
let mut map = HashMap::new();
|
||||||
|
map.insert(action.0, action.1);
|
||||||
|
map
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
// Step 7. Dispatch undo actions with current browsing context.
|
||||||
|
if let Err(err) = self.dispatch_actions(undo_actions, session.browsing_context_id) {
|
||||||
|
return Err(WebDriverError::new(err, "Failed to dispatch undo actions"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 8. Reset the input state of session's current top-level browsing context.
|
||||||
session.input_state_table.borrow_mut().clear();
|
session.input_state_table.borrow_mut().clear();
|
||||||
|
|
||||||
Ok(WebDriverResponse::Void)
|
Ok(WebDriverResponse::Void)
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
[sequence.py]
|
|
||||||
[test_release_char_sequence_sends_keyup_events_in_reverse]
|
|
||||||
expected: FAIL
|
|
Loading…
Add table
Add a link
Reference in a new issue