Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add WebDriver BiDi extension #622

Merged
merged 21 commits into from
Apr 23, 2024
Merged
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
209 changes: 209 additions & 0 deletions index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,12 @@ spec: html; urlPrefix: https://html.spec.whatwg.org/multipage/browsing-the-web.h
spec: PAGE-VISIBILITY; urlPrefix: https://www.w3.org/TR/page-visibility-2/#
type: dfn
text: document visibility state; url: dom-visibilitystate

spec: WEBDRIVER; urlPrefix: https://w3c.github.io/webdriver/
type: dfn
text: error; url: dfn-errors
text: local end; url: dfn-local-ends

</pre>
<pre class="link-defaults">
spec:dom
Expand Down Expand Up @@ -1476,6 +1482,9 @@ steps:
1. If |exclusionFilters| isn't `null`, remove devices from
<var>scanResult</var> if they <a>match a filter</a> in
<var>uuidExclusionFilters</var>.
1. Let |browsingContext| be [=this=]'s [=relevant global object=]'s [=browsing context=].
1. Let |promptId| be a new unique opaque string.
1. [=Trigger a prompt open event=] given |browsingContext|, |promptId|, and |scanResult|.
1. <p id="requestDevice-prompt">Even if <var>scanResult</var> is empty,
<a>prompt the user to choose</a> one of the devices in |scanResult|,
associated with |descriptor|, and let |device| be the result.
Expand All @@ -1490,6 +1499,7 @@ steps:
to indicate interest and then perform a privacy-disabled scan to retrieve
the name.
</div>
1. [=map/Remove=] [=map of browsing contexts to device prompts=][|browsingContext|'s [=browsing context id=]].
1. The UA MAY <a>add |device| to |storage|</a>.

<div class="note">
Expand Down Expand Up @@ -4827,6 +4837,205 @@ attribute on the {{Navigator}} object may be used.

The <a>default allowlist</a> for this feature is <code>["self"]</code>.

# Automated testing # {#automated-testing}

For the purposes of user-agent automation and application testing, this document defines extensions to the [[WebDriver-BiDi]] specification.

Issue: CDDL snippetes use the "text" type instead of
"browsingContext.BrowsingContext" to allow indepedent programmatic
processing of CDDL snippets. Currently, other modules cannot be
referenced.

## The bluetooth module ## {#bluetooth-module}

The bluetooth module contains commands for managing the remote end Bluetooth behavior.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrap "bluetooth" with <dfn>:

The <dfn>bluetooth</dfn> module contains commands

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have removed the definition because it conflicts with another definition with the same id. We also usually do not need the definition for the module, is there a place you want to reference it?


### Types ### {#bidi-types}

#### The bluetooth.RequestDevice Type #### {#bluetooth-requestdevice-type}

<pre highlight="cddl" class="cddl remote-cddl local-cddl">
bluetooth.RequestDevice = text
</pre>

The bluetooth.RequestDevice is an identifier for a single device in a request device prompt.
OrKoN marked this conversation as resolved.
Show resolved Hide resolved

A <dfn>device prompt</dfn> is a [=tuple=] consisting of a <dfn>device
prompt id</dfn> (a string) and a <dfn>set of devices</dfn> which is a
[=/set=] of {{BluetoothDevice}} objects. It represents a prompt which
allows a user to [=prompt the user to choose|choose=] a [=Bluetooth
device=].

#### The bluetooth.RequestDeviceInfo Type #### {#bluetooth-requestdeviceinfo-type}

<pre highlight="cddl" class="cddl remote-cddl local-cddl">
bluetooth.RequestDeviceInfo = {
id: bluetooth.RequestDevice,
name: text / null,
}
</pre>

The bluetooth.RequestDeviceInfo type represents a single device in a request device prompt.
OrKoN marked this conversation as resolved.
Show resolved Hide resolved

<div algorithm="serialize device">
To <dfn>serialize a device</dfn> given a {{BluetoothDevice}} |device|:

1. Let |id| be |device|.{{BluetoothDevice/id}}.
1. Let |name| be |device|.{{BluetoothDevice/name}}.
1. Return a [=map=] matching the <code>bluetooth.RequestDeviceInfo</code> production, with `"id"` set to |id| and `"name"` set to |name|.

</div>

#### The bluetooth.RequestDevicePrompt Type #### {#bluetooth-requestdeviceprompt-type}

<pre highlight="cddl" class="cddl remote-cddl local-cddl">
bluetooth.RequestDevicePrompt = text
</pre>

The bluetooth.RequestDevicePrompt is an identifier for a single prompt.
OrKoN marked this conversation as resolved.
Show resolved Hide resolved

A remote end has a <dfn>map of browsing contexts to device prompts</dfn> which is a [=/map=] whose keys are [=browsing context ids=] and values are [=device prompts=].

<div algorithm="get a prompt">
To <dfn>get a prompt</dfn> given |browsingContextId| and |promptId|:

1. Let |promptMap| be the [=map of browsing contexts to device prompts=].
1. If |promptMap|[|browsingContextId|] does not [=map/exist=]::
OrKoN marked this conversation as resolved.
Show resolved Hide resolved
1. Return [=error=] with [=error code=] [=no such prompt=].
1. Let |prompt| be [=map of browsing contexts to device prompts=][|browsingContextId|].
1. If |prompt|'s [=device prompt id=] is not |promptId|:
1. Return [=error=] with [=error code=] [=no such prompt=].
1. Return [=success=] with data |prompt|.

</div>

<div algorithm="match a device in prompt">
To <dfn>match a device in prompt</dfn> given [=device prompt=] |prompt| and |deviceId|:

1. For each |device| in |prompt|'s [=set of devices=]:
1. If |device|.{{BluetoothDevice/id}} is |deviceId|, return [=success=] with data |device|.
1. Otherwise:
1. Return [=error=] with [=error code=] [=no such device=].

</div>

<div algorithm="serialize prompt devices">
To <dfn>serialize prompt devices</dfn> given [=device prompt=] |prompt|:

1. Let |devices| be an empty [=/list=].
1. For each |device| in |prompt|'s [=set of devices=].
1. [=list/Append=] the result of [=serialize a device|serializing=] |device| to |devices|.
1. Return |devices|.

</div>

### Errors ### {#bidi-errors}

This specification extends the set of [=error codes=] from
[[WEBDRIVER-BIDI|WebDriver BiDi]] with the following additional codes:

<dl>
<dt><dfn>no such device</dfn>
<dd>Tried to reference an unknown {{BluetoothDevice}}.

<dt><dfn>no such prompt</dfn>
<dd>Tried to reference an unknown [=device prompt=].
</dl>

### Commands ### {#bidi-commands}

#### The bluetooth.handleRequestDevicePrompt Command #### {#bluetooth-handlerequestdeviceprompt-command}

<pre highlight="cddl" class="cddl remote-cddl local-cddl">
bluetooth.HandleRequestDevicePrompt = (
method: "bluetooth.handleRequestDevicePrompt",
params: bluetooth.HandleRequestDevicePromptParameters,
)

bluetooth.HandleRequestDevicePromptParameters = {
context: text,
prompt: bluetooth.RequestDevicePrompt,
(
bluetooth.HandleRequestDevicePromptAcceptParameters //
bluetooth.HandleRequestDevicePromptCancelParameters
)
}

bluetooth.HandleRequestDevicePromptAcceptParameters = (
accept: true,
device: bluetooth.RequestDevice,
)

bluetooth.HandleRequestDevicePromptCancelParameters = (
accept: false,
)
</pre>

<div algorithm="remote end steps for bluetooth.handleRequestDevicePrompt">
The [=remote end steps=] with |command parameters| are:
OrKoN marked this conversation as resolved.
Show resolved Hide resolved

1. Let |contextId| be |params|[`"context"`].
1. Let |promptId| be |params|[`"prompt"`].
1. Let |prompt| be the result of [=trying=] to [=get a prompt=] with |contextId| and |promptId|.
1. Let |accept| be the value of the <code>accept</code> field of |command parameters|.
1. If |accept| is true:
1. Let |deviceId| be the value of the <code>device</code> field of |command parameters|.
1. Let |device| be the result of [=trying=] to [=match a device in prompt=] given |prompt| and |deviceId|.
1. Acknowledge |prompt| with |device|.
1. Otherwise:
1. Dismiss |prompt|.
OrKoN marked this conversation as resolved.
Show resolved Hide resolved
1. Return [=success=] with data `null`.

</div>

<div class="example">
A [=local end=] could dismiss a prompt by sending the following message:

<pre highlight="json">
{
"method": "bluetooth.handleRequestDevicePrompt",
"params": {
"context": "cxt-d03fdd81",
"prompt": "pmt-e0a234b",
"accept": true,
"device": "dvc-9b3b872"
}
}
</pre>
</div>

### Events ### {#bidi-events}

#### The bluetooth.requestDevicePromptOpened Event #### {#bluetooth-requestdevicepromptopened-event}

<pre highlight="cddl" class="cddl local-cddl">
bluetooth.RequestDevicePromptOpened = (
method: "bluetooth.requestDevicePromptOpened",
params: bluetooth.RequestDevicePromptOpenedParameters
)

bluetooth.RequestDevicePromptOpenedParameters = {
context: text,
prompt: bluetooth.RequestDevicePrompt,
devices: [* bluetooth.RequestDeviceInfo],
}
</pre>

OrKoN marked this conversation as resolved.
Show resolved Hide resolved
<div algorithm="remote end event trigger for bluetooth.requestDevicePromptOpened">
To <dfn>trigger a prompt open event</dfn> given a [=browsing context=] |context|, a string |promptId|, and a [=/set=] of [=Bluetooth devices=] |devices|:
OrKoN marked this conversation as resolved.
Show resolved Hide resolved

1. Let |context id| be |context|'s [=browsing context id=].
1. Let |prompt| be the [=device prompt=] (|promptId|, |devices|).
1. Let |serialized devices| be the result of [=serialize prompt devices=] with |prompt|.
1. Set [=map of browsing contexts to device prompts=][|context id|] to |prompt|.
1. Let |params| be a [=map=] matching the <code>bluetooth.RequestDevicePromptOpenedParameters</code> production with the <code>context</code> field set to |context id|, the <code>prompt</code> field set to |promptId|, and the <code>devices</code> field set to |serialized devices|.
1. Let |body| be a [=map=] matching the <code>bluetooth.RequestDevicePromptOpened</code> production, with the <code>params</code> field set to |params|.
1. Let |related browsing contexts| be a [=/set=] containing |context|.
1. For each |session| in the [=set of sessions for which an event is enabled=] given "<code>bluetooth.requestDevicePromptOpened</code>" and |related browsing contexts|:
1. [=Emit an event=] with |session| and |body|.

</div>

# Terminology and Conventions # {#terminology}

This specification uses a few conventions and several terms from other
Expand Down