Commit Graph

347 Commits

Author SHA1 Message Date
Euclid Ye
8419c5ed9f webdriver: Reduce IPC for cookie deletion (#42836)
- Update Doc for `CoreResourceMsg::DeleteCookies`
- Reduce IPC for cookie deletion

---------

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
2026-02-27 11:32:02 +00:00
Euclid Ye
8dc7b5c06b webdriver: Remove last dependency on RefCell (#42358)
`pending_input_event_receivers` is the last thing that uses `RefCell`. 
This PR improves safety as we rely on static check, and performance
slightly too.

Testing: Just refactor.

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
2026-02-05 09:33:08 +00:00
Euclid Ye
d2b4b039e7 webdriver: Remove orphan Handler::num_pending_actions (#42297)
`Handler::num_pending_actions` has been a poor orphan since
who-knows-when.
This also removes the only dependency on `Cell`.

Testing: This removes unused field. Covered by existing tests.

---------

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
2026-02-03 05:38:04 +00:00
Euclid Ye
aedbebbb35 webdriver: Support interspersed pointerMove actions via event queue (#42289)
For `pointerMove` with duration, we need to wait asynchronously and
execute in parallel for subsequent moves.
But we never did this correctly: we waited in a blocking way which broke
the whole point of tick: making sure we simultaneously perform actions
from multiple sources within a single unit time.

To avoid async borrow-checker hell, we achieve the same effect using a
event queue.

> Spec: The initial pointer movement is performed synchronously. This
ensures determinism in the sequence of the first event triggered by each
action in the tick.
> 
> Subsequent movements (if any) are performed asynchronously. This
allows events from two
[pointerMove](https://w3c.github.io/webdriver/#dfn-pointermove) actions
in the tick to be interspersed.

Testing: Existing WPT tests not affected, which is a good sign.
Fixes: #42235
This is a pre-requisite to #41923: multi-touch support.

---------

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
2026-02-03 04:08:58 +00:00
Euclid Ye
34c644d5b8 webdriver: Wait indefinitely with None timeout (#42184)
So far for `None`
[timeout](https://w3c.github.io/webdriver/#dfn-timeouts-configuration),
we've treated it effectively as no wait which is wrong:
https://github.com/web-platform-tests/wpt/pull/57332#issuecomment-3804242966.

This PR makes all `None` timeouts wait indefinitely. The funny part is,
we somehow have only done it correctly for `pageload`:
https://w3c.github.io/webdriver/#dfn-timeouts-configuration

Testing: We add test for script execution with `None` script timeout.

---------

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
2026-01-30 09:54:07 +00:00
Josh Matthews
4a2a73ad56 webdriver: Reset prefs to the values present at server start. (#42044)
The test harness attempts to reset preferences to default values when
running a test in which previously-set preferences are no longer set.
This leads to confusing interactions with any preference customizations
that are present, such as `--pref whatever` or `--prefs-file
something.json`, which are not considered when calculating the default.
This PR changes that: whatever preference values are present when the
webdriver server starts is treated as the default value.

Testing: This is a servo-specific webdriver extension, and we're fixing
an interaction with the test harness. I don't see another way to test
this besides observing the impact on our test results.
Fixes: #42043

Signed-off-by: Josh Matthews <josh@joshmatthews.net>
2026-01-21 07:52:17 +00:00
Euclid Ye
c21039257f webdriver: Dispatch embedder TouchEventType::Move (#41801)
Fixes: #41725 
Fixes: #41620 
Fixes: #39264
Fixes: #41250

Testing: Multiple new passing. Several tests that NOT RUN starts
running.
Several new CRASH are actually
```
 0:25.43 INFO Browser not responding, setting status to CRASH
 0:25.43 TEST_END: CRASH, expected OK
```
, which is no regression because these tests were FAIL, ERROR or
TIMEOUT.

---------

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
2026-01-13 22:25:40 +00:00
Euclid Ye
014fb968a8 webdriver: Consolidates synchronous and asynchrounous script execution (#41830)
Follow-up to #41823.
Now that we always execute JS with callback, we can safely remove the
obsolete sync script handler.

- Rename `ExecuteAsyncScript` to `ExecuteScriptWithCallback`
- Remove `ExecuteScript` related logic.
- Rewrite async callback wrapper to simplify things.

Testing: I expect no change in behaviour. See if WPT tests agree with
it.

---------

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
2026-01-11 09:19:09 +00:00
Euclid Ye
0266a28478 webdriver: Allow Promise for synchronous script execution (#41823)
When a promise is given, it must be honoured.

Testing: `/classic/execute_script/promise.py` fully pass.

---------

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
2026-01-10 17:59:09 +00:00
Euclid Ye
21e58f3f8c webdriver: Unify "Element Click" for touch & mouse + Improve PointerMove compliance (#41726)
Testing: This should fix the quirky behaviour where we use mousemove
 to change pointer status for touch/pen. 
You can see the new WPT passing.

Fixes: #41250
Fixes: Part of #41620
Fixes: Part of #41725

---------

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
2026-01-08 09:59:17 +00:00
Narfinger
1b0bd11e11 Use GenericSender and GenericReceiver for WebDriver (#40987)
- Use the generic channel for webdriver.
- Implement try_receive_timeout for GenericReceiver.

Testing: WPT should still work.

---------

Signed-off-by: Narfinger <Narfinger@users.noreply.github.com>
2025-12-19 03:22:02 +00:00
Narfinger
44f3f34f88 net: Implement eviction in the HTTP cache using quick_cache (#40613)
This uses quick_cache to have a proper cache for http.

Previously, the http cache would just grow over the lifetime of the
servo instance. Now we use the quick_cache crate to have a cache with
proper eviction procedures.

We currently weight the entries by the number of responses for the url.
The cache size is configurable.

Testing: Tested WPT run
(https://github.com/Narfinger/servo/actions/runs/19338794789) and
websites.

---------

Signed-off-by: Narfinger <Narfinger@users.noreply.github.com>
Signed-off-by: Taym Haddadi <haddadi.taym@gmail.com>
Signed-off-by: gterzian <2792687+gterzian@users.noreply.github.com>
Co-authored-by: gterzian <2792687+gterzian@users.noreply.github.com>
Co-authored-by: Taym Haddadi <haddadi.taym@gmail.com>
2025-12-16 12:08:15 +00:00
Martin Robinson
5b99d3c2b3 servoshell: Create new WebDriver WebViews in new toplevel windows (#41235)
This change makes it is that WebDriver can create whole new windows for
each new `WebView` in servoshell. The motivation for this is:

1. This is how the WebDriver specification is written. The command that
   create a new WebView is actually called "New Window" [^1], so this
   increases compliance with the specification and now we obey the
   type hint sent with that command.
2. This change allows testing multi-window support via the WPT.
3. This will allow adding optimizations (#39923) that are otherwise
   impossible because the WPT expects all open `WebView` to be live and
   visible.

This does not make the change yet for windows opened via `window.open()`
(popups), as that requires #41220 to fix. In order to make this possible
a few changes to the code had to take place:

1. The new `PlatformWindow` creation function has to be passed down to
   the WebDriver handler, which normally doesn't know how to make
   `PlatformWindow`s.
2. This allows moving the UI command code back to the shared part of
   servoshell, meaning that the embedded ports can use it as well
   eventually.
3. Headless windows need a real id to differeniate them now intead of
   just 0.
4. When dropping the headless `PlatformWindow` we need to make it
   current. I'm not sure why surfman doesn't do this, but this is now
   necessary as there are multiple contexts. This is also true when
   resizing the `RenderingContext`.

Finally, errors when making the context current are upgraded to
`error!`s as they typically break the entire execution of the program.

[^1]: https://w3c.github.io/webdriver/#new-window

Testing: This is tested by the entire WPT suite.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
2025-12-16 10:11:33 +00:00
Narfinger
c2f546da01 Base: Implement GenericOneshot channels (#41143)
This implements a GenericOneshot channel. The size in the crossbeam
channel is restricted while in the Ipc case we use the same
IpcChannel(for now).

We also use these channels in WebDriver to prove they work.

Testing: Unit Tests and compilation still works.
Fixes: https://github.com/servo/servo/issues/39019

Signed-off-by: Narfinger <Narfinger@users.noreply.github.com>
2025-12-09 10:36:59 +00:00
Euclid Ye
60b9a03c81 webdriver: Add touch support for all platforms (#41067)
Some mobile websites only have touch event listeners, but not any for
mouse events. We add native touch support for "element click", for
Android/OHOS. We are finally utilizing `subtype` and can remove the
`dead_code` macro for it: we dispatch action based on the subtype given,
which has impact for [Perform
Actions](https://w3c.github.io/webdriver/#dfn-actions) **on all
platforms**.

Testing: 
1. Tested on OHOS for a normal webpage, plus a special webpage that only
has touch event listener.
2. Desktop: Previously, we always ignore the requested of pointer
subtype and dispatch the mouse. All 138 stable unexpected test actually
never worked, and now crash due to "Got a touchmove event for a
non-active touch point" since we can dispatch touch now. I plan to
improve this and make it work soon!

Fixes: The step 4 of #41042. We still need to fix some bugs of spec, and
wait for resolution.

TODO later: When we have touch simulation for Desktop, "Element click"
should also dispatch pointer touch.

---------

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
2025-12-05 09:59:28 +00:00
Anonmiraj
b207be05d9 change some allows to expects (#41040)
Changed some allow to expects and removed the unfulfilled expectations.

Testing: Refactor
Part of: #40383

Signed-off-by: anonmiraj <nabilmalek48@gmail.com>
2025-12-05 07:23:32 +00:00
Euclid Ye
d7e1395abd webdriver: Refactor actions.rs (#41004)
- Remove some unnecessary loop, cloning.
- Simplify some match
- Explicitly state unused match arm: PointerCancel is not implemented.

Testing: Refactor. Covered by existing test.

---------

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
2025-12-02 12:00:40 +00:00
Josh Matthews
acbeb25f0b servodriver: Clear cookies between tests. (#40709)
To ensure that tests that modify cookies but don't finish cleanly don't
leave cookie values that interfere with subsequent tests, we need to
clear the cookie storage in between each test that's run.

Testing: Can't test the test runner, just have to watch the patterns in
our test runs.
Fixes: #40668
Fixes: #40672
Fixes: #40673
Fixes: #40674
Fixes: #40695
Fixes: #40697

Signed-off-by: Josh Matthews <josh@joshmatthews.net>
2025-11-28 06:46:52 +00:00
Euclid Ye
f9c0fc857c webdriver: Enable implicit wait on error (#40836)
... and reduce code duplication in element retrieval. Note that we are
not using the functionality of "wait on error" yet.

Testing: We added WPT tests for "Find element", "Find element from
element", "Find element from shadow root" for both successful implicit
wait and timeout case.

---------

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
2025-11-27 09:13:27 +00:00
Euclid Ye
35f9a0d3cb webdriver: Generalize implicit_wait (#40784)
I wanted to implement [implicit
wait](https://w3c.github.io/webdriver/#dfn-implicit-wait-timeout) for
other commands, such as send key/element clear/click. But the current
trait bound, parameters, and logic are way too tight and specific.

Testing: This should not change existing behaviour.

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
2025-11-22 04:12:01 +00:00
Tim van der Lippe
e1b9c02de3 webdriver: implement protocol handler automation mode (#40733)
The tests now start running rather than erroring, but they aren't
working yet as we don't currently use protocol handlers yet. That's for
follow-up PRs, as that requires more plumbing.

Part of #40615

Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
2025-11-19 11:53:17 +00:00
Euclid Ye
7c0d0486b6 webdriver: Do not remove id from input_state_table if it still in input_cancel_list (#40483)
There ~was~ has been a
[bug](https://github.com/servo/servo/issues/37579#issuecomment-2990762713)
in spec. Our workaround has been: for every keyup/pointerup, we remove a
corresponding entry in `input_cancel_list`.

But we missed one thing: it is possible to only dispatch keydown in
[element send
keys](https://w3c.github.io/webdriver/#dfn-element-send-keys). In that
case, we inserted an entry into `input_cancel_list` but removes Id from
`input_state_table` in the end. This causes a panic with a followup
[release actions](https://w3c.github.io/webdriver/#dfn-release-actions).

This PR makes sure we only remove if it is safe.

Testing: CI no longer panic on
dc9696c27d/components/webdriver_server/actions.rs (L338)
for some testdriver tests.

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
2025-11-08 00:10:14 +00:00
Euclid Ye
383b8e6658 webdriver: Print details when fail to start server (#40476)
This has made life much easier to debug servodriver.

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
2025-11-07 12:13:37 +00:00
Euclid Ye
834b1208a7 webdriver: Allow dummy sessionId for ServoExtensionCommand::Shutdown (#40450)
...This is unavoidable, unless we have our own fork of [webdriver
crate](https://crates.io/crates/webdriver). Right now it does not allow
any self-defined command to run without sessionId. See
[this](https://hg-edge.mozilla.org/mozilla-central/file/tip/testing/webdriver/src/server.rs#l84).
There is also no way to override
[Dispatcher](https://hg-edge.mozilla.org/mozilla-central/file/tip/testing/webdriver/src/server.rs#l65).

A follow up PR which changes wptrunner to gracefully shutdown servo
without killing depends on this.

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
2025-11-06 09:33:55 +00:00
Euclid Ye
73a7a8c1bb webdriver: Remove session requirement from Shutdown command (#40445)
Change API endpoint from "/session/{sessionId}/servo/shutdown" to
"/servo/shutdown", similar to [Status
command](https://w3c.github.io/webdriver/#dfn-status).

This will make it much easier to shutdown Servo properly from wptrunner.

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
2025-11-06 07:02:25 +00:00
Euclid Ye
bc76eb494e webdriver: Implement extension command Shutdown (#40422)
We implement `ServoExtensionCommand::Shutdown`, which shutdown Servo
elegantly. This is required for Coverage Report. Later, we will
implement Servo's override of [`stop()` in
`WebDriverBrowser`](0d44ca8ddc/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/base.py (L389)).

Testing: Manually tested with PowerShell script.

---------

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
2025-11-05 13:26:32 +00:00
Euclid Ye
2d89cd7471 Reduce unnecessary type conversion and share WebDriverCommandMsg::LoadUrl handler across platform (#40393)
- Reduces unnecessary type conversion between `ServoUrl`, `Url`, string
slice
- Share `WebDriverCommandMsg::LoadUrl` handler across platform

Testing: Covered by existing test. Manually tested for OHOS.

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
2025-11-04 13:57:00 +00:00
Simon Wülker
c4ae451612 Turn all commented links before functions into doccomments (#40331)
Servo has a lot of comments like this:
```rust
// https://example-spec.com/#do-the-thing
fn do_the_thing() {}
```
and I keep turning these into doc comments whenever I'm working close to
one of them. Doing so allows me to hover over a function call in an IDE
and open its specification without having to jump to the function
definition first. This change fixes all of these comments at once.

This was done using `find components -name '*.rs' -exec perl -i -0777
-pe 's|^([ \t]*)// (https?://.*)\n\1(fn )|\1/// <$2>\n\1$3|mg' {} +`.

Note that these comments should be doc comments even within trait `impl`
blocks, because rustdoc will use them as fallback documentation when the
method definition on the trait does not have documentation.

Testing: Comments only, no testing required
Preparation for https://github.com/servo/servo/pull/39552

---------

Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
2025-11-01 05:32:45 +00:00
Martin Robinson
9aa86938a7 webdriver: Add a 10 second timeout for screenshots (#40290)
This change adds a 10 second timeout for screenshots. Without this
timeout, tests that fail take a screenshot in a reasonable amount of
time cause the the WebDriver driver to kill the process leading to a
CRASH test result. This causes the results to differ and to obscure what
is really a TIMEOUT.

This behavior is unspecified, but it's still an improvement, as it
properly classifies failures when the WPT is run with WebDriver.

Testing: This causes some WPT tests run with WebDriver to have
their expected result.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
2025-10-30 16:50:49 +00:00
Euclid Ye
4de66051f6 webdriver: Replace wait_for_ipc_response with wait_for_ipc_response_flatten whenever possible (#39984)
This is a follow up to reduce the amount of code:
https://github.com/servo/servo/pull/39620#discussion_r2403825334

Testing: No behaviour change. Existing wdspec test should suffice.

Signed-off-by: Euclid <yezhizhenjiakang@gmail.com>
2025-10-18 21:35:37 +00:00
Euclid Ye
8971f69143 webdriver: Deserialize WebWindow and report error correctly for script execution (#39885)
We were relying on `fn WebdriverWindow` to report `NoSuchWindow` during
script execution, regardless of the fact that it is never `Fallible`. I
was really hoping to refactor this to return `Fallible` to reduce one
RTT of IPC, but there is no easy way to convert between DOM exception
56b806b129/components/script_bindings/error.rs (L15)
and JavaScriptEvaluationError
56b806b129/components/shared/embedder/lib.rs (L1092).

We also migrate `element.rs` to `script_argument_extraction.rs` to
reflect the true purpose of the file.

Testing: 10 new subtests passing.

---------

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
2025-10-16 03:26:27 +00:00
Euclid Ye
6247060ad6 webdriver: Reduce visibilty of some structures and functions (#39825)
Work on some chore before further improving script execution.

Testing: No behaviour change.

---------

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
2025-10-13 10:35:43 +00:00
Martin Robinson
f6d1ad9d06 webdriver: Send events to the embedder as InputEvent with a response channel (#39776)
This change simplifies the WebDriver <-> Embedder API by exposing a
single message for dispatching input event actions. This message now
includes a `Sender` which is used to inform the WebDriver server that
the embedder has finished processing the message in the DOM. This
replaces the system of ids and the side channel that was used for this
purpose before.

Testing: This is just a simplification of the WebDriver API and
shouldn't
really change behavior in a perceivable way, so it covered by existing
tests.

---------

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
2025-10-11 11:17:28 +00:00
Martin Robinson
a7d9142978 libservo: Improve JavaScript evaluation error name and documentation (#39770)
Testing: this just changes a type name and adds documentation, so
doesn't need new tests.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
2025-10-10 16:41:25 +00:00
Martin Robinson
35d4b1e937 script: Combine WebDriverJSError with JavaScriptEvaluationError and add the stack (#39647)
This change merges the WebDriver only `WebDriverJSError` with the API
`JavaScriptEvaluationError` and also allows passing `ErrorInfo`
information through to the API layer when possible. In addition, the
stack is added to `ErrorInfo` (but only in situations when evaluating
JavaScript code for WebDriver or via the API for performance reasons).

These changes allow much more useful error output when script execution
fails via WebDriver. Now the error message and source file line numbers
are printed by the test executor.

Testing: These changes should be reflected in the testing output.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
2025-10-10 11:34:42 +00:00
Martin Robinson
12e5d1b05e libservo: Unify notifications to the embedder that input events are handled (#39720)
Servo currently has three ways of notifying the embedder that input
events have been processed.

1. `WebViewDelegate::notify_keyboard_event`: This is used to implement
   overridable keybindings in servoshell. It notifies the embedder when
   a keyboard event has been processed, but not "handled" by the engine.
2. WebDriver's command message senders and receivers, this is used to
   let WebDriver wait until events have been handled to continue with
   script execution.
3. Touch event processing notifications: This is used to serialize touch
   event processing.

This change unifies the first two things with a new
`WebViewDelegate::notify_input_event_handled` API. This API informs the
embedder (via a generated id) that an input event has finished
processing and what the result of the processing was.

This allows embedders to do other things with events once they have been
processed. For example, embedders might want to chain unconsumed events
up to parent widgets or to add support for overridable keybindings.

As part of this the `canceled` flag in script's `Event` data structure
is turned into a `bitflags` mirror of the new API type to describe the
result of event handling.

Testing: This shouldn't change observable behavior and is thus covered
by existing tests.
The new API is consumed by servoshell, which uses it for tests.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
2025-10-10 07:48:06 +00:00
Euclid Ye
9f8b767289 webdriver: Stop making fields RefCell (#39679)
Stop making any fields of webdriver being RefCell to completely rely on
compile-time check.

Testing: No behaviour change
Fixes: #39497
Fixes: #39649

---------

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
Co-authored-by: Domenico Rizzo <domenico.rizzo@gmail.com>
2025-10-08 06:18:35 +00:00
Euclid Ye
bb2f8415ad script: Remove WebdriverTimeout callback (#39704)
After #39682, this callback is no longer necessary. We also remove
`WebDriverJSError::Timeout`.

Testing: No regression in wdspec. For servodriver,
[before](https://github.com/yezhizhen/servo/actions/runs/18300017112).
[after](https://github.com/yezhizhen/servo/actions/runs/18300911442) is
also the same.

---------

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
2025-10-07 07:23:00 +00:00
Martin Robinson
4b990c1dcc webdriver: Apply script timeout to related IPC messaging as well (#39682)
In some cases scripts never call their `setTimeout` guard. In that case
also
timeout if we never hear a reply from the script thread. In general, the
script timeout is applied to all synchronous IPC waiting for script
replies.

In addition, rework timeout setting a bit to be more similar to the
specifciation.

Testing: This causes some tests run with the WebDriver test runner to
fail with
TIMEOUT rather than CRASH, accurately reflecting their reason for
failing.

---------

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
Co-authored-by: Delan Azabani <dazabani@igalia.com>
Co-authored-by: Euclid Ye <yezhizhenjiakang@gmail.com>
2025-10-06 15:25:23 +00:00
Euclid Ye
cd4a72379b webdriver: Implement implicit wait for "Element retrieval" (#39620)
Implicit wait is specified in [WebDriver
spec](https://w3c.github.io/webdriver/#dfn-find), which is used to keep
retrieving elements until found or timeout. This is really convenient
for automation with real websites.

Testing: Manually tested with
[Selenium](https://www.selenium.dev/documentation/webdriver/waits/#implicit-waits).

---------

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
2025-10-06 13:29:14 +00:00
Euclid Ye
44d287cc39 webdriver: Implement Pointer ID (#39642)
This is necessary first step to distinguish pointer sources: "mouse,
pen, touch".

Spec: https://w3c.github.io/webdriver/#dfn-get-a-pointer-id.

Testing: No behaviour change yet as we still only dispatch pointer type:
mouse.
Fixes: Part of #39264.

---------

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
2025-10-04 15:16:34 +00:00
shuppy
cfa9e711c5 webdriver: Use take_screenshot() API in Take (Element) Screenshot (#39587)
WPT tests require us to reliably take screenshots when test pages are
fully loaded and testing is complete, and the WPT runner uses
[test-wait.js](a2f551eb2d/tests/wpt/tests/tools/wptrunner/wptrunner/executors/test-wait.js)
to do this in userland. when testing Servo with [--product
servo](a2f551eb2d/tests/wpt/tests/tools/wptrunner/wptrunner/executors/executorservo.py),
we use servoshell’s --output option, which backs that up with more
reliable waiting in Servo. but when testing Servo with [--product
servodriver](a2f551eb2d/tests/wpt/tests/tools/wptrunner/wptrunner/executors/executorservodriver.py),
we use the WebDriver Take Screenshot action, which currently takes the
screenshot immediately. we think this might be a source of regressions.

this patch makes the WebDriver actions Take Screenshot and Take Element
Screenshot use the same new WebView::take_screenshot() API as
servoshell’s --output option, such that those actions now wait for [a
variety of
conditions](a2f551eb2d/components/servo/webview.rs (L596-L602))
that may affect test output. it’s not clear if this is
[conformant](https://w3c.github.io/webdriver/#screen-capture), so we may
want to refine this to only wait when running tests at some point. other
changes:

- we remove the retry loop where we try to take a screenshot every
second for up to 30 seconds
- we send the result as a image::RgbaImage over crossbeam without shared
memory (it’s not cross-process)
- we now handle the zero-sized element case directly in the WebDriver
server

Testing: This should fix some flaky tests.
Fixes: #36715.
Fixes: (partially) #39180.
Fixes: (partially) #34683.

Signed-off-by: Delan Azabani <dazabani@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
2025-10-01 12:37:00 +00:00
Euclid Ye
6aa82309c3 webdriver: Wait animation frame callbacks before taking (element) screenshot (#39539)
According to spec, we should wait animation frame callbacks before
taking (element) screenshot. As "element screenshot" would automatically
scroll into view, this solves intermittency.

Testing: Manually tested on pages, and
`take_element_screenshot/scroll_into_view.py` passes stably now.
Fixes: #39306

---------

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
2025-09-27 13:29:44 +00:00
Euclid Ye
2e8fac9395 webdriver: Elegantly handle "element screenshot" when bounding box has area zero (#39499)
It is possible that the bounding rectangle of an element has area 0.
This PR avoids panic in this case.

It is worth to mention that the panic itself won't kill the entire
program for interaction, but only the webdriver thread.

Testing: Manually tested on the case of #39495

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
2025-09-27 02:20:35 +00:00
Kenzie Raditya Tirtarahardja
77ae3a0eb3 webdriver: Improve documentations for actions.rs and update TODOs (#39391)
Add specification quote for each steps, remove some irrelevant TODO, and
move function position closer to related function.

Testing: No behaviour change

---------

Signed-off-by: PotatoCP <kenzieradityatirtarahardja18@gmail.com>
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
Co-authored-by: Euclid Ye <yezhizhenjiakang@gmail.com>
2025-09-21 05:42:16 +00:00
Kenzie Raditya Tirtarahardja
097a69169a webdriver: Support "scroll into view" for commands (#38508)
Implement scroll into view steps for all WebDriver command that requires
it (element click, element send keys, element clear, and take element
screenshot).

Testing: `element_send_keys/scroll_into_view.py`,
`element_click/scroll_into_view.py`, `element_clear/clear.py`

---------

Signed-off-by: PotatoCP <Kenzie.Raditya.Tirtarahardja@huawei.com>
2025-09-12 06:07:58 +00:00
Euclid Ye
726b456120 webdriver: Focus WebView asynchronously (#39241)
#38160 added a webdriver-specific API to support waiting on focus
operations to complete. Later, #38243 added a unique id to track each
focus operation.

Back then we wait on focusing webview in webdriver hoping to improve
stability, but it does not matter as it turns out later. #39086 also
focuses browsing context asynchronously.

This PR would make webdriver's focusing-webview behaviour same as human
interaction.

Testing: 
[Before 1](https://github.com/yezhizhen/servo/actions/runs/17598288280),
[Before 2](https://github.com/yezhizhen/servo/actions/runs/17598289360),
[Before 3](https://github.com/yezhizhen/servo/actions/runs/17598290532)
[After 1](https://github.com/yezhizhen/servo/actions/runs/17598282988),
[After 2](https://github.com/yezhizhen/servo/actions/runs/17598280603),
[After 3](https://github.com/yezhizhen/servo/actions/runs/17589228530)

---------

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
2025-09-10 07:36:53 +00:00
Euclid Ye
bd3231847e webdriver: Serialize as i64 if the JS Number has no fractional part (#39186)
JavaScript Number does not have Integer type, except for recently added
`BigInt`. That's why we removed `Int` variant from `JSValue` earlier in
#38748. However, the Serde deserialization is strict: when it expects
`u64`, it cannot deserialize "3.0". But when it expects `f64`, it can
still deserialize "3".

Now, we serialize as i64 if the JS Number has no fractional part. This
not only fixes regression, but also improves the case where we have an
integer not representable by i32 and previously would be parsed as f64
again.

Testing: `./mach test-wpt -r
/infrastructure/testdriver/actions/eventOrder.html --headless --product
servodriver` no longer fails when deserializing HTTP request.
Fixes: #39181

Signed-off-by: Euclid Ye <euclid.ye@huawei.com>
2025-09-06 14:38:32 +00:00
Euclid Ye
802fdd9068 webdriver: Focus browsing context when switch frame (#39086)
#38889 adds back the mechanism to focus the window when [switch to
window](https://w3c.github.io/webdriver/#switch-to-window). After that,
it causes many flaky TIMEOUT. Turns out the real reason is same as the
phenomenon which I thought was unrelated:
https://github.com/servo/servo/pull/38889#issuecomment-3217512339: we
need to focus the browsing context as well according to spec. This is
important for Servo because it relies on
f4dd2960b8/components/constellation/constellation_webview.rs (L64)
to determine which pipeline to send `InputEvent` to.

Testing: Before, there are 9 ~ 13 flaky results. [Before
1](https://github.com/yezhizhen/servo/actions/runs/17379170889), [Before
2](https://github.com/yezhizhen/servo/actions/runs/17392219417), [Before
3](https://github.com/yezhizhen/servo/actions/runs/17379172612).
Now there are 2 ~ 4 flaky results. [After
1](https://github.com/yezhizhen/servo/actions/runs/17394359570), [After
2](https://github.com/yezhizhen/servo/actions/runs/17394358218), [After
3](https://github.com/yezhizhen/servo/actions/runs/17394357400).
Fixes: https://github.com/servo/servo/pull/38889#issuecomment-3218600566
Fixes: #38906, which is last blocking point to enable WebDriver CI.

---------

Signed-off-by: Euclid Ye <euclid.ye@huawei.com>
2025-09-02 08:57:45 +00:00
Euclid Ye
236e28aeab webdriver: Wait for navigation to complete when creating session with all WebViews closed (#39040)
In #37410 for webdriver mode, we introduced mechanism to keep program
alive when all webview are closed to comply with spec. But the test
fails with 90% probability, as the `browsing_context` is only registered
in constellation's `browsing_contexts` map when documents are ready.
This PR waits for navigation to complete without verifying browsing
context existence (as it's guaranteed from context) in this special case
by refactoring existing code.

Testing:
4571cc1b3b/tests/wpt/tests/webdriver/tests/classic/close_window/close.py (L87)
is no longer flaky. Previously, it has 90% probability to fail. Now it
always pass.

Signed-off-by: Euclid Ye <euclid.ye@huawei.com>
2025-09-01 08:56:51 +00:00