Commit Graph

810 Commits

Author SHA1 Message Date
Timothy Flynn
6bc339b737 WebContent: Ensure we mark a driver endpoint as complete in early return
Fixes a mistake from 3da20aca65.
2024-11-04 16:16:44 -05:00
Timothy Flynn
5010e42cd3 WebContent: Treat <frame> elements as navigable containers in WebDriver 2024-11-04 09:54:32 +00:00
Timothy Flynn
64a8fcc4ef LibWeb: Begin implementing a Selenium-like method to get element text
Unfortunately, there isn't an exact spec method to get the rendered text
of an element, including its shadow DOM. The WebDriver spec requires
just doing exactly what Selenium does.

This patch does not implement this, but is a step in the right direction
as we will now handle text transforms.
2024-11-03 20:42:46 -05:00
Timothy Flynn
a4daf6f928 WebContent: Implement WebDriver's Switch Frame endpoint for numeric IDs 2024-11-03 20:42:46 -05:00
Timothy Flynn
3da20aca65 WebContent+WebDriver: Convert all user prompt handlers to be async
Making these async were all actually pretty trivial. This patch does so,
and removes the deprecated synchronous user prompt handler.
2024-11-03 22:11:19 +01:00
Timothy Flynn
fd3f8b7645 LibWeb+WebContent: Fully implement WebDriver JSON deserialization 2024-11-03 17:51:58 +01:00
Timothy Flynn
6fb8500a7a LibWeb+WebContent: Simplify hand-rolled script execution result struct
Instead of maintaining a list of script execution result types, which we
then map to WebDriver error types, just return the WebDriver error that
is specified by the spec. Then perform the JSON clone algorithm from the
caller in WebDriverConnection, again as specified by the spec. To do so,
this moves the JSON clone algorithm to its own file. This will also be
the future home of the JSON deserialize algorithm, which will need some
of the internal AOs implemented there.
2024-11-03 17:51:58 +01:00
Timothy Flynn
a5ca036d36 LibWeb+WebContent: Update and fully implement the JSON clone algorithm
We have the facilities now to fully implement this AO. Do so, and update
the AO to match the latest spec.
2024-11-03 17:51:58 +01:00
Timothy Flynn
f16eebb95c WebContent: Begin handling user prompts asynchronously
We have to handle user prompts during the exection of most WebDriver
endpoints. Of the ~50 endpoints which call this AO, ~20 are currently
currently async and handled here.
2024-11-02 11:09:41 +01:00
Timothy Flynn
5515cb56e8 WebContent: Deprecate the curent implementation of handling user prompts
There are approximately 1000 WPT subtests that rely on the handling of
user prompts being completely asynchronous. It will take a bit of elbow
grease to make all of our WebDriver endpoints comply with this. So for
now, we will deprecate the currently synchronous implementation, and a
future patch will implement an asynchronous version that already-async
endpoints can use.
2024-11-02 11:09:41 +01:00
Timothy Flynn
9dc1302768 WebContent+WebDriver: Consolidate driver execution completion callbacks
Some WebDriver hooks will need to inform the client that execution has
completed, but without any knowledge of what endpoint was running. Since
there can only ever be a single WebDriver endpoint executing at once, we
can replace the completion callbacks with a single callback.
2024-11-02 11:09:41 +01:00
Timothy Flynn
1be67faab7 LibWeb+WebContent: Handle user prompts that open during script execution
If a dialog is opened while a script is executing, we must give control
back to the WebDriver client. The script must also continue executing
though, so once it completes, we ignore its result.
2024-11-02 11:09:41 +01:00
Shannon Booth
da18551f10 LibWeb: Change HTML::Script to hold a realm instead of settings object
This is part of a refactor needed for introduction of the shadow realm
proposal in the web platform.
2024-11-01 18:55:23 -06:00
Shannon Booth
cc91473f4d LibWeb: Make TemporaryExecutionContext take a Realm& 2024-11-01 18:55:23 -06:00
Timothy Flynn
f064c6e930 LibWeb+WebContent+WebDriver: Make the screenshot endpoints asynchronous
These were the last WebDriver endpoints spinning the event loop.
2024-10-31 02:39:36 +00:00
Timothy Flynn
ad9d623664 WebContent+WebDriver: Make the element locator endpoints asynchronous
We currently spin the event loop to wait for the specified element to
become available. As we've seen with other endpoints, this can result
in dead locks if another web component also spins the event loop.

This patch makes the locator implementations asynchronous.
2024-10-31 00:42:29 +00:00
Shannon Booth
7487a782db LibWeb: Use HeapFunction for EventLoopPlugin::spin_until 2024-10-30 20:55:45 +01:00
Shannon Booth
de1a805898 LibWeb: Use HeapFunction for Platform::Timer 2024-10-30 20:55:45 +01:00
Shannon Booth
ede3c91688 LibWeb: Make Platform::Timer GC-allocated
This will allow us to remove the use of SafeFunction in it's
implementation. This requires a fair amount of plumbing to wire up the
GC heap to the appropriate places in order to create the timers.
2024-10-30 20:55:45 +01:00
Shannon Booth
e44702f090 LibWeb: Construct ResourceLoader with a GC Heap
This will allow us to easily make use of HeapFunctions instead of
SafeFunction for all of the callbacks in ResourceLoader.
2024-10-30 20:55:45 +01:00
Aliaksandr Kalenik
a8077f79cc LibWeb: Separate text control input events handling from contenteditable
This input event handling change is intended to address the following
design issues:
- Having `DOM::Position` is unnecessary complexity when `Selection`
  exists because caret position could be described by the selection
  object with a collapsed state. Before this change, we had to
  synchronize those whenever one of them was modified, and there were
  already bugs caused by that, i.e., caret position was not changed when
  selection offset was modified from the JS side.
- Selection API exposes selection offset within `<textarea>` and
  `<input>`, which is not supposed to happen. These objects should
  manage their selection state by themselves and have selection offset
  even when they are not displayed.
- `EventHandler` looks only at `DOM::Text` owned by `DOM::Position`
  while doing text manipulations. It works fine for `<input>` and
  `<textarea>`, but `contenteditable` needs to consider all text
  descendant text nodes; i.e., if the cursor is moved outside of
  `DOM::Text`, we need to look for an adjacent text node to move the
  cursor there.

With this change, `EventHandler` no longer does direct manipulations on
caret position or text content, but instead delegates them to the active
`InputEventsTarget`, which could be either
`FormAssociatedTextControlElement` (for `<input>` and `<textarea>`) or
`EditingHostManager` (for `contenteditable`). The `Selection` object is
used to manage both selection and caret position for `contenteditable`,
and text control elements manage their own selection state that is not
exposed by Selection API.

This change improves text editing on Discord, as now we don't have to
refocus the `contenteditable` element after character input. The problem
was that selection manipulations from the JS side were not propagated
to `DOM::Position`.

I expect this change to make future correctness improvements for
`contenteditable` (and `designMode`) easier, as now it's decoupled from
`<input>` and `<textarea>` and separated from `EventHandler`, which is
quite a busy file.
2024-10-30 19:29:56 +01:00
Timothy Flynn
2e71e300ee WebContent: Restore ability to use Inspector accessors like "$0"
We implement these built-in accessors via a lexical environment override
on the inspected document's global scope. However, ClassicScript will
parse the script we provide as a JS program, in which any evaluated
bindings will be interpreted as global bindings. Our global binding
lookup in the bytecode interpreter does not search the lexical env for
the binding, thus scripts like "$0" fail to evaluate.

Instead, we can create an ECMAScriptFunctionObject to evaluate scripts
entered into the Inspector. These are not evaluated as JS programs, and
thus any evaluated bindings are interpreted as non-global bindings. The
lexical environment override we set will then be considered.
2024-10-30 08:50:31 +01:00
Timothy Flynn
3ca2ee9c72 LibWeb+WebContent+WebDriver+UI: Make window min/maximize asynchronous
This follows suit of previous changes to never block the WebContent
process in WebDriver endpoints.
2024-10-29 11:03:20 +00:00
Timothy Flynn
fa83cc722c LibWeb+WebContent+WebDriver+UI: Make window rect updates asynchronous
It's currently possible for window size/position updates to hang, as the
underlying IPCs are synchronous. This updates the WebDriver endpoint to
be async, to unblock the WebContent process while the update is ongoing.
The UI process is now responsible for informing WebContent when the
update is complete.
2024-10-29 11:03:20 +00:00
Jonne Ransijn
07cd7d479f LibWeb: Remove reference counting for CSS::StyleProperties
`AK::CopyOnWrite` already does reference counting, so there is no need
to do it again.
2024-10-27 13:26:30 +01:00
Timothy Flynn
0722a3b1c0 LibWeb+WebContent+WebDriver: Asynchronously wait for dialog dismissal
There was a timing issue here where WebDriver would dismiss a dialog,
and then invoke another endpoint before the dialog was actually closed.
This is because the dismissal first has to hop over to the UI process to
close the graphical dialog, which then asynchronously informs WebContent
of the result. It's not until WebContent receives that result that the
dialog is considered closed, thus those subsequent endpoints would abort
due a dialog being "open".

We now wait for dialogs to be fully closed before returning from the
dismissal endpoints.
2024-10-26 11:25:42 +02:00
Timothy Flynn
bf0bc62654 WebContent+WebDriver: Asynchronously wait for navigations to complete
Similar to commit c2cf65adac, we should
avoid spinning the event loop from the WebContent-side of the WebDriver
connection. This can result in deadlocks if another component in LibWeb
also spins the event loop.

The AO to await navigations has two event loop spinners - waiting for
the navigation to complete and for the document to reach the target
readiness state. We now use NavigationObserver and DocumentObserver to
be notified when these conditions are met. And we use the same async IPC
mechanism as script execution to notify the WebDriver process when all
conditions are met (or timed out).
2024-10-26 11:25:42 +02:00
Timothy Flynn
e89d889219 LibWeb+WebContent: Ensure elements are in view before clicking them
This implements a couple of missing steps in the Element Click endpoint.
2024-10-24 18:59:51 -04:00
Timothy Flynn
9682b150ac WebContent: Do not raise errors from invoking element.scrollIntoView
The spec does not say to do this. We must instead implement methods to
validate the element after attempting to scroll.
2024-10-24 18:59:51 -04:00
Timothy Flynn
9f872d9aab WebContent: Do not use NodeIterator to iterate DOM nodes backwards
A NodeIterator rooted at some element cannot produce an element before
that root. That is, in a DOM tree such as:

    <div id=one><div id=two><div id=three></div></div></div>

If we create a NodeIterator rooted at element `three`, then invoking the
previousNode() method on that iterator is guaranteed to return null.

There was also a bug here where if we ever did enter the while() loop,
we would have looped indefinitely, as we were not updating the current
node.
2024-10-24 18:59:51 -04:00
Timothy Flynn
a9c858fc78 LibWeb: Implement WebDriver element references according to the spec
Our currently ad-hoc method of tracking element references is basically
a process-wide map, rather than grouping elements according to their
browsing context groups. This prevents us from recognizing when an
element reference is invalid due to its browsing context having been
closed.

This implements the WebDriver spec concept of element references grouped
according to their browsing context groups.

This patch is a bit noisy because we now need to plumb the current BC
through to the element reference AOs.
2024-10-24 18:59:51 -04:00
Andrew Kaster
7372b2af48 LibIPC+Everywhere: Introduce an IPC Transport abstraction
This abstraction will help us to support multiple IPC transport
mechanisms going forward. For now, we only have a TransportSocket that
implements the same behavior we previously had, using Unix Sockets for
IPC.
2024-10-23 12:29:01 -06:00
Timothy Flynn
b75a4d25b7 WebContent: Further validate cookie attributes set from WebDriver
Implement a few missing steps in the Add Cookie endpoint.
2024-10-23 09:05:33 +02:00
Jelle Raaijmakers
9309cc9df3 UI+LibWeb+WebContent: Implement KeyEvent repeat property
When a platform key press or release event is repeated, we now pass
along a `repeat` flag to indicate that auto-repeating is happening. This
flag eventually ends up in `KeyboardEvent.repeat`.
2024-10-22 11:20:35 -04:00
Timothy Flynn
ebe89a3207 WebContent: Parse the type hint in WebDriver's New Window endpoint
Although we aren't using this hint (we always create tabs), we do need
to validate the payload.
2024-10-21 13:15:11 -04:00
Timothy Flynn
6cba55893e WebContent: Return the handle of the newly opened window from New Window
We were returning the handle of the already opened window, rather than
the handle of the window we just opened.
2024-10-20 16:41:11 +01:00
Andreas Kling
4fdb266077 LibWeb: Make DOM Node unique IDs strongly typed (and 64 bit)
This is strictly nicer than passing them around as i32 everywhere,
and by switching to i64 as the underlying type, ID allocation becomes as
simple as incrementing an integer.
2024-10-20 13:42:33 +02:00
Tim Ledbetter
eca2318390 WebContent: Use window open steps to create a new window with WebDriver
This matches the specification steps and fixes a WPT regression caused
by us not loading `about:blank` when opening a new window.
2024-10-20 11:42:19 +01:00
Timothy Flynn
1aab7b51ea LibWebView: Generate hyperlinks for attributes that represent links
On the view-source page, generate anchor tags for any 'href' or 'src'
attribute value we come across. This handles both when the attribute
contains an absolute URL and a URL relative to the page.

This requires sending the document's base URL over IPC to resolve
relative URLs.
2024-10-20 08:50:01 +02:00
Timothy Flynn
048b51eb54 WebContent: Add a JS visitor to WebDriver's IPC connection
We've added a few JS::Handle members to this class over time. Let's
avoid creating a new GC root for each of these, and explicitly add a
visitation method.
2024-10-18 09:45:04 +02:00
Timothy Flynn
022e2b8a94 LibWeb+WebContent: Rename the WebDriver get-known-element AO
The underlying concept is the same, but this method was renamed in the
spec to drop the word "connected".
2024-10-18 09:45:04 +02:00
Timothy Flynn
a96a762305 LibWeb+WebContent: Use NNGCPtr in WebDriver code where appropriate
Some of this code is older than widespread use of GCPtr. These functions
returning raw pointers has been a point of confusion at times, so lets
just indicate that they are non-null.
2024-10-18 09:45:04 +02:00
Aliaksandr Kalenik
c690fb9df3 LibWeb: Rename Layout::Node::paintable() to first_paintable()
Layout node is allowed to have multiple corresponding paintables, so
first_paintable() is more explicit name for getter that returns first
paintable.
2024-10-16 20:25:42 +02:00
Sam Atkins
5cc75d4de4 LibWeb: Remove tiny-OOM handling from dump code 2024-10-16 08:32:29 +02:00
Timothy Flynn
e070ed5658 LibWeb+LibWebView: Add an internal API to expire cookies with an offset
Cookies have a minimum expiry resolution of 1 second. So to test cookie
expiration, the test had to idle for at least a second, which is quite a
noticeable delay now that LibWeb tests are parallelized.

Instead, we can add an internal API to expire cookies with a time offset
to avoid this idle delay.
2024-10-14 08:25:41 +02:00
Timothy Flynn
dae6200c1d LibWeb: Update (not replace) timeout values in WebDriver's Set Timeouts
Contradictory to the spec, the Set Timeouts endpoint should update the
existing timeouts configuration in-place, rather than replacing it. WPT
expects this, and other browsers already implement this endpoint this
way.
2024-10-12 15:02:41 +02:00
Timothy Flynn
8396afeb76 LibWeb: Update WebDriver timeout parsing/serializing to the latest spec
Namely, all fields in the timeouts object may now be null. There are a
few calling AOs that we will want to bring up to date as well.
2024-10-12 15:02:41 +02:00
Timothy Flynn
8598ed86fe LibWeb+WebContent: Implement the Element Clear endpoint 2024-10-12 15:01:35 +02:00
Timothy Flynn
23d134708c LibWeb: Begin implementing the Element Send Keys endpoint 2024-10-11 09:09:23 +02:00
Timothy Flynn
13fe3477ab WebContent: Wait for same-URL WebDriver navigations to complete
The spec says we don't need to await navigations if we navigate to the
same URL that we are already on, but at least in our implementation, we
should still await the page load. Otherwise, we will invoke WebDriver
endpoints on the wrong page.
2024-10-10 10:41:10 +02:00