Webdriver GoBack and GoForward commands wait for navigation complete (#37950)

After sending `GoBack` or `GoForward` command, webdriver wait for the
navigation complete.
It can be achieved by waiting for
`WebViewDelegate::notify_history_changed`

Testing: 
`tests/wpt/meta/webdriver/tests/classic/back/back.py`
`tests/wpt/meta/webdriver/tests/classic/forward/forward.py`

---------

Signed-off-by: batu_hoang <longvatrong111@gmail.com>
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
Signed-off-by: batu_hoang <hoang.binh.trong@huawei.com>
Co-authored-by: Josh Matthews <josh@joshmatthews.net>
This commit is contained in:
batu_hoang 2025-07-15 18:41:50 +08:00 committed by GitHub
parent c817d7b9ce
commit 8e2d2bde6f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 114 additions and 40 deletions

View file

@ -4,6 +4,7 @@
use std::cell::{Ref, RefCell, RefMut};
use std::collections::HashMap;
use std::collections::hash_map::Entry;
use std::path::PathBuf;
use std::rc::Rc;
@ -19,8 +20,8 @@ use servo::webrender_api::units::{DeviceIntPoint, DeviceIntSize};
use servo::{
AllowOrDenyRequest, AuthenticationRequest, FilterPattern, FormControl, GamepadHapticEffectType,
KeyboardEvent, LoadStatus, PermissionRequest, Servo, ServoDelegate, ServoError, SimpleDialog,
WebDriverCommandMsg, WebDriverJSResult, WebDriverJSValue, WebDriverLoadStatus, WebView,
WebViewBuilder, WebViewDelegate,
TraversalId, WebDriverCommandMsg, WebDriverJSResult, WebDriverJSValue, WebDriverLoadStatus,
WebView, WebViewBuilder, WebViewDelegate,
};
use url::Url;
@ -44,6 +45,7 @@ pub(crate) enum AppState {
struct WebDriverSenders {
pub load_status_senders: HashMap<WebViewId, IpcSender<WebDriverLoadStatus>>,
pub script_evaluation_interrupt_sender: Option<IpcSender<WebDriverJSResult>>,
pub pending_traversals: HashMap<WebViewId, (TraversalId, IpcSender<WebDriverLoadStatus>)>,
}
pub(crate) struct RunningAppState {
@ -430,6 +432,18 @@ impl RunningAppState {
});
}
pub(crate) fn set_pending_traversal(
&self,
webview_id: WebViewId,
traversal_id: TraversalId,
sender: IpcSender<WebDriverLoadStatus>,
) {
self.webdriver_senders
.borrow_mut()
.pending_traversals
.insert(webview_id, (traversal_id, sender));
}
pub(crate) fn set_load_status_sender(
&self,
webview_id: WebViewId,
@ -511,6 +525,16 @@ impl WebViewDelegate for RunningAppState {
}
}
fn notify_traversal_complete(&self, webview: servo::WebView, traversal_id: TraversalId) {
let mut webdriver_state = self.webdriver_senders.borrow_mut();
if let Entry::Occupied(entry) = webdriver_state.pending_traversals.entry(webview.id()) {
if entry.get().0 == traversal_id {
let (_, sender) = entry.remove();
let _ = sender.send(WebDriverLoadStatus::Complete);
}
}
}
fn request_move_to(&self, _: servo::WebView, new_position: DeviceIntPoint) {
self.inner().window.set_position(new_position);
}