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.
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.
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.
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.
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.
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.
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.
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.
We are currently trying to access the current parent and top-level
browsing contexts from the current BC itself. However, if the current BC
is closed, its association to the parent and top-level BCs is lost, and
we are no longer able to handle WebDriver endpoints involving those BCs.
Instead, let's store the parent and top-level BCs separately, and update
them in accordance with the spec.
Similar to script execution, this spins the WebDriver process until the
action is complete (rather than spinning the WebContent process, which
we've seen result in deadlocks).
In particular, we need to convert web element references to the actual
element. The AO isn't fully implemented because we will need to work out
mixing JsonValue types with JS value types, which currently isn't very
straight forward with our JSON clone algorithm.
We are currently returning a JSON object of the form:
{
"name": "element-6066-11e4-a52e-4f735466cecf",
"value": "foo"
}
Instead, we are expected to return an object of the form:
{
"element-6066-11e4-a52e-4f735466cecf": "foo"
}
It's difficult to know what we need to implement if we silently ignore
these endpoints. Let's log the endpoints and their parameters, and clean
up the wall of FIXME comments to be easier to grok.
Previously, some otherwise unimplemented WebDriver endpoints were
indicating that they had executed successful, this was causing a large
number of Web Platform Tests to time out when they should have failed.
We were only looking at the current top-level navigable and its children
when searching for the specified window handle. We need to search *all*
known navigables if the handle belongs to a window not in the current
tree.
This is one of the few endpoints that does not ensure a top-level BC is
open. It's a bit of an implementation-defined endpoint, so let's protect
against a non-existent BC explicitly.
When we create a WebDriverConnection object, we currently hand it the
page client for which it was opened, and perform all actions on that
client. However, some WebDriver endpoints change the browsing context
(and therefore page client) on which future commands should be executed.
For example, the switch-frame endpoint will switch the current browsing
context to a frame/iframe context.
This patch implements the current browsing context (and current top-
level browsing context) concepts. They are initialized to that of the
original page. Most of this patch is making sure we execute actions on
the correct context.
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.
Added the following Routes, IPC definitions, and boilerplates for the
missing endpoints:
- Switch To Frame
- Switch To Parent Frame
- Element Clear
- Element Send Keys
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.