(cherry picked from commit 229b64a4b723a391c21f247d72d78cd575ace6ff;
minorly amended to fix conflict in image.cpp due to serenity in the
meantime adding webp writing support, and due to changes in Android and
Vulkan-related files that serenity doesn't have)
We can currently crash on WebDriver session shutdown when we receive a
Delete Session command. This destroys the WebDriver client while we are
inside the client's socket's on_ready_to_read callback. This is not
allowed by AK::Function.
To avoid this, we now only read data from the socket in the callback. We
then defer handling the message to break out of the callback.
(cherry picked from commit 47af8c673381b1ffe15c85f711463a3fbeac165e)
Very similar to commit e5877cda61eb53cd9c1eebbfaf3c35d084b2973c.
By sending as much data as we can in a single write, we see a massive
performance improvement on WPT tests that hammer WebDriver with errors.
On my Linux machine, this reduces the runtime of:
/webdriver/tests/classic/perform_actions/invalid.py
from 45-60s down to 3-4s.
(cherry picked from commit 7a15e3ee5caa9332f3f6011cc21058e6ceab838c)
We must send a Cache-Control header, which then also requires that we
respond with an HTTP/1.1 response (the Pragma cache option is HTTP/1.0).
We should also send the Content-Type header using the same casing as is
written in the WebDriver spec (lowercase).
Both of these are explicitly tested by WPT.
(cherry picked from commit e436c31b97b5e25a6064013ae9deae0f979e95dc)
We currently spin the platform event loop while awaiting scripts to
complete. This causes WebContent to hang if another component is also
spinning the event loop. The particular example that instigated this
patch was the navigable's navigation loop (which spins until the fetch
process is complete), triggered by a form submission to an iframe.
So instead of spinning, we now return immediately from the script
executors, after setting up listeners for either the script's promise to
be resolved or for a timeout. The HTTP request to WebDriver must finish
synchronously though, so now the WebDriver process spins its event loop
until WebContent signals that the script completed. This should be ok -
the WebDriver process isn't expected to be doing anything else in the
meantime.
Also, as a consequence of these changes, we now actually handle time
outs. We were previously creating the timeout timer, but not starting
it.
(cherry picked from commit c2cf65adac78912883996153fb608dafe389b6e0)
This change updates `ExecuteScript::execute_script()` and
`ExecuteScript::execute_script()` to bring their behavior in line with
each other and the current specification text.
Instances of the variable `timeout` have also been renamed to
`timeout_ms`, for clarity.
(cherry picked from commit 107549dc86eb0a02bb6468ccfa03475114474187)
Previously, the conversion assumed that the supplied timeout was in
seconds rather than milliseconds.
(cherry picked from commit b688b5d9d4cfd8f781dd05d522d9533cd6796aca)
WPT uses Python's http.client.HTTPConnection to send/receive WebDriver
messages. For some reason, on Linux, we see an ~0.04s delay between the
WPT server receiving the WebDriver response headers and its body. There
are tests which make north of 1100 of these requests, which adds up to
~44s.
These connections are almost always going to be over localhost and able
the be sent in a single write. So let's send the response all at once.
On my Linux machine, this reduces the runtime of /cookies/name/name.html
from 45-60s down to 3-4s.
(cherry picked from commit e5877cda61eb53cd9c1eebbfaf3c35d084b2973c)
Reftest screenshots are now captured using the dimensions specified in
the draw a bounding box from the framebuffer AO defined in the
WebDriver specification.
(cherry picked from commit b4aff45854bd0d9aaaf76cdbb4f07411bd240755)
Following the structure of the ReleaseActions endpoints, define
analogous classes and methods for PerformActions
(cherry picked from commit ee352e59dbd4d2b8fbfbec396cb5232a13291274)
Added the following Routes, IPC definitions, and boilerplates for the
missing endpoints:
- Switch To Frame
- Switch To Parent Frame
- Element Clear
- Element Send Keys
(cherry picked from commit d1ba317e22d41fd948fd477d44735918a972c158)
This is required by the spec, so let's stop returning random IDs in
favor of a simple sequential integer sequence.
(cherry picked from commit 0e1256e5a405627fda18b597d8fd08073dd60b77)
No longer just for response headers! The same type is obviously useful
and ergonomic when making requests as well.
(cherry picked from commit 260c5c50ad19f19d0d4c30984e512f56c055ecff)
Updated various SerenityOS components to make it build.
This is to avoid including any LibProtocol header in Objective-C source
files, which will cause a conflict between the Protocol namespace and a
@Protocol interface.
See Ladybird/AppKit/Application/ApplicationBridge.cpp for why this
conflict unfortunately cannot be worked around.
By using separate struct we can avoid updating AST node and
ECMAScriptFunctionObject constructors every time there is a need to
add or remove some additional information colllected during parsing.
Allows to skip function environment allocation for non-arrow functions
if the only reason it is needed is to hold `this` binding.
The parser is changed to do following:
- If a function is an arrow function and uses `this` then all functions
in a scope chain are marked to allocate function environment for
`this` binding.
- If a function uses `new.target` then all functions in a scope chain
are marked to allocate function environment.
`ordinary_call_bind_this()` is changed to put `this` value in execution
context when function environment allocation is skipped.
35% improvement in Octane/typescript.js
50% improvement in Octane/deltablue.js
19% improvement in Octane/raytrace.js
If a function has the following properties:
- uses only local variables and registers
- does not use `this`
- does not use `new.target`
- does not use `super`
- does not use direct eval() calls
then it is possible to entirely skip function environment allocation
because it will never be used
This change adds gathering of information whether a function needs to
access `this` from environment and updates `prepare_for_ordinary_call()`
to skip allocation when possible.
For now, this optimisation is too aggressively blocked; e.g. if `this`
is used in a function scope, then all functions in outer scopes have to
allocate an environment. It could be improved in the future, although
this implementation already allows skipping >80% of environment
allocations on Discord, GitHub and Twitter.
Normally, assigning to e.g document.body.onload will forward to
window.onload. However, in a detached DOM tree, there is no associated
window, so we have nowhere to forward to, making this a no-op.
The bulk of this change is making Document::window() return a nullable
pointer, as documents created by DOMParser or DOMImplementation do not
have an associated window object, and so must be able to return null
from here.
The default canvas size is 300x150 pixels. If the element or document
we are trying to screenshot for the WebDriver is not at least that size,
then we will create a canvas that is wider or taller than the actual
element we are painting, resulting in a bunch of transparent pixels
falling off the end.
This fixes 14 WPT css/CSS2/floats tests that we run in CI, and
presumably a ton of other reftests in the WPT test suite.
This prevents us from returning an 'unrecognized capability' error when
a WebDriver client sends us a proxy capability. We still don't actually
support setting or returning a non-empty proxy capability, though.
We just don't choke on the input capability request from the server.
This patch also doesn't actually validate the input proxy requests.
`JsonValue::to_byte_string` has peculiar type-erasure semantics which is
not usually intended. Unfortunately, it also has a very stereotypical
name which does not warn about unexpected behavior. So let's prefix it
with `deprecated_` to make new code use `as_string` if it just wants to
get string value or `serialized<StringBuilder>` if it needs to do proper
serialization.
In a bunch of cases, this actually ends up simplifying the code as
to_number will handle something such as:
```
Optional<I> opt;
if constexpr (IsSigned<I>)
opt = view.to_int<I>();
else
opt = view.to_uint<I>();
```
For us.
The main goal here however is to have a single generic number conversion
API between all of the String classes.
This commit un-deprecates DeprecatedString, and repurposes it as a byte
string.
As the null state has already been removed, there are no other
particularly hairy blockers in repurposing this type as a byte string
(what it _really_ is).
This commit is auto-generated:
$ xs=$(ack -l \bDeprecatedString\b\|deprecated_string AK Userland \
Meta Ports Ladybird Tests Kernel)
$ perl -pie 's/\bDeprecatedString\b/ByteString/g;
s/deprecated_string/byte_string/g' $xs
$ clang-format --style=file -i \
$(git diff --name-only | grep \.cpp\|\.h)
$ gn format $(git ls-files '*.gn' '*.gni')
Since 2023-09-08, Clang trunk has had a bug which causes a segfault when
evaluating certain `requires` expressions inside templated lambdas.
There isn't an imminent fix on the horizon, so let's work around the
issue by specifying the type of the offending lambda arguments
explicitly.
See https://github.com/llvm/llvm-project/issues/67260
This required dealing with a *lot* of fallout, but it's all basically
just switching from DeprecatedFlyString to either FlyString or
Optional<FlyString> in a hundred places to accommodate the change.
Saving vector of local variables names in ECMAScriptFunctionObject
will allow to get a name by index in case message of ReferenceError
needs to contain a variable name.
Fixes the bug that currently we don't ever close webdriver client
connection socket when header "Connection: keep-alive" is specified.
This allows to run more WPT tests without running out of free file
descriptors :)
Before execute_async_script supported returning value from script to
/execute/async caller only if script returns promise that resolves into
returned value. This change fixes execute_async_script to also support
returning value to caller using callback that is always passed to
script as a last argument.