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>
- 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>
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>
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>
- 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>
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>
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>
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>
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>
This should be the final PR for the Hash Function series that is
trivial.
Of note: I decided to transform `HashMapTracedValues<Atom,..>` to use
FxBuildHasher. This is likely not going to improve performance as Atom's
already have a unique u32 that is used as the Hash but it safes a few
bytes for the RandomState that is normally in the HashMap.
Signed-off-by: Narfinger <Narfinger@users.noreply.github.com>
Testing: Hash function changes should not change functionality, we
slightly decrease the size and unit tests still work.
Signed-off-by: Narfinger <Narfinger@users.noreply.github.com>
- Add `ShadowRoot` to `JSValue` to avoid
`WebDriverJSError::UnknownType`, and
`JavaScriptEvaluationError::SerializationError` when execute JS from
embedder.
- Add unit test.
- Move [is_detached](https://w3c.github.io/webdriver/#dfn-is-detached)
to `fn is_detached` to be reused.
- Other random simplification.
Testing: WebDriver conformance tests.
---------
Signed-off-by: Euclid Ye <euclid.ye@huawei.com>
Ports the channel for WebDriverLoadStatus to GenericChannel.
Testing: No functional changes - Covered by existing webdriver tests
Part of #38912
Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
This PR contains 2 parts:
1. Refactor webdriver session.
2. Improve webdriver window handles:
- Webdriver always get window handles from script thread by default.
- If script thread is blocked by user prompt, embedder stores the window
handle before user prompt appears, then webdriver can get window handle
from embedder.
Testing: Clear timeout cause by user prompt blocking script thread:
https://github.com/longvatrong111/servo/actions/runs/17033900026
---------
Signed-off-by: batu_hoang <hoang.binh.trong@huawei.com>
Signed-off-by: batu_hoang <longvatrong111@gmail.com>
Co-authored-by: Euclid Ye <euclid.ye@huawei.com>
After #38748, `WebDriverJSValue` is almost same as `JSValue`. Now we
turn "potentially merge into one in the future" into reality. The only
thing we should be cautious is to properly serialize `WebFrame`,
`WebWindow`, `WebElement` for WebDriver.
Testing: No regression. Some error is fixed previously by #38709 which
didn't update test :)
Binary size reduced by 134KB.
---------
Signed-off-by: Euclid Ye <euclid.ye@huawei.com>
Implment get window handles according to
[spec](https://w3c.github.io/webdriver/#dfn-window-handles).
- Window handles are supposed to identify `browsing context`. However,
based on `get window handle command` and `get window handles command`,
we only need to care about top level browsing context.
- Back then, we use a random generated uuid for eacch webview id, it is
not correct but still work because all commands depend on `webview id`
and `browsing context id`. The only case we need window handle is is
when webdriver gets window object with js script. Since the object is
converted to the id of window's document node, `get window handle`
should return the same thing.
Action run (with updated expectation):
https://github.com/longvatrong111/servo/actions/runs/16957610535https://github.com/longvatrong111/servo/actions/runs/16957612027
Some tests may sporadically timeout due to unstable hit test.
cc: @xiaochengh
---------
Signed-off-by: batu_hoang <hoang.binh.trong@huawei.com>
1. Synchronize [Close
Window](https://w3c.github.io/webdriver/#dfn-close-window) command to
reduce intermittency
2. There was a update last month exposing that we are not returning
correct error type for Session getter.
https://github.com/web-platform-tests/wpt/pull/53735
3. Other trivial fix
Testing:
- `/webdriver/tests/classic/close_window/close.py` can now fully pass.
- `/webdriver/tests/classic/delete_session/*` can now fully pass.
---------
Signed-off-by: Euclid Ye <euclid.ye@huawei.com>
Adding basic webdriver support to servoshell on ohos and basic
communication between the ohos device and script.
Testing: Manual testing and tracing logs
Signed-off-by: abdelrahman1234567 <abdelrahman.hossameldin.awadalla@huawei.com>
For current implementation, when a command may trigger a navigation,
webdriver only waits for document readiness state.
However, not all navigations make change in document.
This PR handles more cases for waiting for a navigation, and apply to
`element_click`.
- Before sending a command which may trigger a navigation, `webdriver`
sets `load status send` to `embedder`, `constelltation` and `script
thread` to listen to `navigation events`.
- Webdriver check if there is a navigation with `script thread`.
- If the navigation is loading a new url, webdriver checks if the
request is approved with `constellation`, then waits for document
readiness state.
- If the navigation is a hashchange, webdriver waits untill all new
generated dom events have been processed.
Testing:
`tests/wpt/tests/webdriver/tests/classic/element_click/navigate.py`
`tests/wpt/tests/webdriver/tests/classic/element_click/user_prompts.py`
https://github.com/longvatrong111/servo/actions/runs/16488690749
cc: @xiaochengh
---------
Signed-off-by: batu_hoang <hoang.binh.trong@huawei.com>
Keep Constellation alive even when all browsing context closed in
WebDriver mode. In this case, when creating a new session, we would open
a new top-level browsing context.
Fixes: #37408
Testing: `./mach test-wpt -r
.\tests\wpt\tests\webdriver\tests\classic\close_window\close.py
--product servodriver`
---------
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
Signed-off-by: Euclid Ye <euclid.ye@huawei.com>
- Implement [Maximize
Window](https://w3c.github.io/webdriver/#maximize-window)
- Previously, headless window screen size is same as inner size if not
specified in preference. We make it double as required by the test to
not have max window initially.
- Some other random cleanup.
Testing: webdriver Stress test for maximize window (headed + headless).
---------
Signed-off-by: Euclid Ye <euclid.ye@huawei.com>
Cleaning up some dead code which has been here for 9 years. They are
never detected by Lint because we still initialize them as `None` but
never change afterwards.
Testing: No regression.
---------
Signed-off-by: Euclid Ye <euclid.ye@huawei.com>
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
Previously, we pretend we are able to set position in response. Now we
can really do it.
Testing: Able to set position accurately when tested locally.
Fixes: Task 5 of #37804.
---------
Signed-off-by: Euclid Ye <euclid.ye@huawei.com>
`WebDriverCommandMsg::TakeScreenshot` was the last thing blocking us
from removing constellation access in webdriver server. Now we can
happily remove it.
Surprisingly, this reduces binary size by 185KB for release profile in
Windows. #37737 removes a net total of 300 lines, but only reduced 98KB.
Testing: No regression after testing.
Signed-off-by: Euclid Ye <euclid.ye@huawei.com>
Previously the webdriver do not wait for focus to complete, which can
cause some instability.
No matter interact as human or webdriver, the focus chain always goes
as: Embedder forwards -> Constellation (do some updates) -> Embedder (do
some updates).
---------
Signed-off-by: Euclid Ye <euclid.ye@huawei.com>
- Add `handler any user prompt` step for all commands.
- Enable webdriver tests which were blocked by `handle any user prompt`
step.
---------
Signed-off-by: batu_hoang <hoang.binh.trong@huawei.com>
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>
Previously, we SendKeys will be forwarded to constellation by the
embedder. Now we use webview.notify_input_event, which will send
WebDriverCommandMsg::ForwardInputEvent for the KeyboardEvent and
CompositionEvent.
Fixes: part of https://github.com/servo/servo/issues/37370
---------
Signed-off-by: PotatoCP <kenzieradityatirtarahardja18@gmail.com>
Previously, we KeyboardAction will be forwarded to constellation by the
embedder. Now we use `webview.notify_input_event`, which will send
`WebDriverCommandMsg::ForwardInputEvent` for KeyboardAction
Fixes: part of https://github.com/servo/servo/issues/37370
---------
Signed-off-by: PotatoCP <kenzieradityatirtarahardja18@gmail.com>