`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>
- Rename `wait_for_user_agent_handling_complete` to
`wait_for_input_event_handled`
- Reduce the time-complexity from $O(N^2)$ to $O(N)$: we are waiting for
all `pending_input_event_receivers` anyway. There is no need for
`crossbeam_channel::Select` as the sender won't block, and channel is
`unbound`.
- Add a TODO: Some DOM events may not have been produced at the end of
wait.
Testing: This is refactor.
https://github.com/servo/servo/actions/runs/21627646437
---------
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
`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>
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>
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>
Fixes: #41725Fixes: #41620Fixes: #39264Fixes: #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>
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>
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>
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>
Changed most #[allow]s to #[expect]s, mainly for
clippy::too_many_arguments
Removed unfulfilled expectations
This is my first opensource contribution, so please let me know if
anything should
be done differently.
Testing: Refactor
Part of: #40838
---------
Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
Signed-off-by: TimurBora <timurborisov5561@gmail.com>
Co-authored-by: Tim van der Lippe <TimvdLippe@users.noreply.github.com>
- 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>
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>
Back in #41067, we added webdriver touch support for all platforms. All
touch-related testdriver tests which faked to work has been CRASH
instead, as we assume that touch down event always happens before touch
move and touch up.
But the assumption above is not wrong, as I observed embedder events
dispatched from OHOS/Android when interacting as human. It is just that
the tests are flawed: almost all of them have pointermove first even for
touch, and spec didn't consider touch/pen support well enough: #41042.
Luckily, our embedder `MouseMove` event would also update the webdriver
pointer status, which effectively allow touch down/touch up to happen at
right point. It **doesn't matter** whether the website has mouse
listener or not.
Testing: Tested manually on a touch-event-only complicated website.
Also, tests no longer crash, also with expectations different from
before https://github.com/servo/servo/pull/41067, e.g.
[this](https://github.com/servo/servo/pull/41067/files#diff-db149f4025dab43bd5a3c8a412ea2ac9e521f4745c0f982925b4d15b236ff955)
had been failing but now passes.
---------
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
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>
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>
Changed some allow to expects and removed the unfulfilled expectations.
Testing: Refactor
Part of: #40383
Signed-off-by: anonmiraj <nabilmalek48@gmail.com>
- 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>
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: #40668Fixes: #40672Fixes: #40673Fixes: #40674Fixes: #40695Fixes: #40697
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
This change is a major re-architecture of servoshell to support multiple
windows. Unfortunately it was not possible to do this incrementally, but
@mukilan and I did this together so we feel more confident about these
changes.
The main change here is that now the `HashMap` of windows that `App`
has can be filled with more than one `ServoShellWindow`.
`ServoShellWindow` is a wrapper around a `PlatformWindow` which can
either be headed, headless, or for embedded platforms. Embedded
platforms (Android and OHOS) are only expected to have a single window,
but there is no reason that more windows cannot be added.
There is still a little bit more work to be done in order to fully
enable
mulitple windows, so this change is just the architectural preparation.
This change enables the embedded and desktop versions of servoshell to
start to be fully integrated so that the entire `RunningAppState` is
shared between them.
Testing: servoshell is the test harness so these changes are covered
by the WPT tests.
---------
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Mukilan Thiyagarajan <mukilan@igalia.com>
... 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>
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>
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>
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>
- 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>
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>
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>
This change exposes two new data types in the API, which allow embedders
to supply coordinates in either page pixels or device pixels. In
particular, WebDriver wants to give coordiantes to the API in page
pixels. This prevents the embedder from having to do these conversions
and makes it harder to misuse the API.
Testing: This should fix WebDriver conformance tests that are run in
headed mode.
Fixes: #40152
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Rakhi Sharma <atbrakhi@igalia.com>
It is possible that the reference of `WebElement` and `ShadowRoot` in
the request is not String. Instead of panic, we should return "invalid
argument" same as the `WebWindow` and `WebFrame`.
Testing: Added 4 new subtests. There was only tests for `WebWindow` and
`WebFrame` somehow.
---------
Signed-off-by: Euclid <yezhizhenjiakang@gmail.com>
This is ~slightly~ quite different from the last PR for `WebWindow`.
This time, we need to consult constellation to verify the existence of
browsing context, without diving into script. But constellation requires
`BrowsingContextId` object to check the HashMap. As a result, we added a
regex check to convert the given `reference: string` to
`BrowsingContextId`.
Testing: 14 newly passing tests. Two of them are newly created, as
previous tests themselves are wrong and outdated with spec. We now fully
pass `execute_{async_}script/arguments.py`.
---------
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
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>
Work on some chore before further improving script execution.
Testing: No behaviour change.
---------
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
Previously, the JS deserialization is wrong for object like `{"-": 3}`.
This was because we never generate a valid JSON string literal from the
request.
Now I share @Loirooriol's laughter: "We just fixed something very basic,
but there is no existing test covering this", after fixing a bunch of
things in past few days.
Testing: Added two new subtests to
[wdspec](https://web-platform-tests.org/writing-tests/wdspec.html).
Fixes: #38083
---------
Signed-off-by: Euclid Ye <euclid.ye@huawei.com>
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>
According to
[spec](https://w3c.github.io/webdriver/#dfn-json-deserialize), we should
regard an object as webelement/shadowroot/webframe//webwindow, as long
as one of the key is the corresponding identifier. Moreover, the order
matters. This PR addresses this.
Testing: Added 8 subtests to wdspec.
Fixes: Part of #38083.
---------
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
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>
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>