`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>
`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>
- 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>
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>
... 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>
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>
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>
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>
Stop making any fields of webdriver being RefCell to completely rely on
compile-time check.
Testing: No behaviour change
Fixes: #39497Fixes: #39649
---------
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
Co-authored-by: Domenico Rizzo <domenico.rizzo@gmail.com>
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>
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>
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>
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>
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>
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>
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>