Files
url_tracker_tool/node_modules/chromium-bidi/README.md
Andrei 58f8093689 Rebrand from 'Redirect Intelligence v2' to 'URL Tracker Tool V2' throughout UI
- Updated all component headers and documentation
- Changed navbar and footer branding
- Updated homepage hero badge
- Modified page title in index.html
- Simplified footer text to 'Built with ❤️'
- Consistent V2 capitalization across all references
2025-08-19 19:12:23 +00:00

475 lines
11 KiB
Markdown

# WebDriver BiDi for Chromium [![chromium-bidi on npm](https://img.shields.io/npm/v/chromium-bidi)](https://www.npmjs.com/package/chromium-bidi)
## CI status
![E2E Tests](https://github.com/GoogleChromeLabs/chromium-bidi/actions/workflows/e2e.yml/badge.svg)
![Unit Tests](https://github.com/GoogleChromeLabs/chromium-bidi/actions/workflows/unit.yml/badge.svg)
![WPT Tests](https://github.com/GoogleChromeLabs/chromium-bidi/actions/workflows/wpt.yml/badge.svg)
![Pre-commit](https://github.com/GoogleChromeLabs/chromium-bidi/actions/workflows/pre-commit.yml/badge.svg)
[![codecov](https://codecov.io/gh/GoogleChromeLabs/chromium-bidi/branch/main/graph/badge.svg?token=LJSXSC9L09)](https://codecov.io/gh/GoogleChromeLabs/chromium-bidi)
This is an implementation of the
[WebDriver BiDi](https://w3c.github.io/webdriver-bidi/) protocol with some
extensions (**BiDi+**)
for Chromium, implemented as a JavaScript layer translating between BiDi and CDP,
running inside a Chrome tab.
Current status can be checked
at [WPT WebDriver BiDi status](https://wpt.fyi/results/webdriver/tests/bidi).
## BiDi+
**"BiDi+"** is an extension of the WebDriver BiDi protocol. In addition to [WebDriver BiDi](https://w3c.github.io/webdriver-bidi/) it has:
### Command `cdp.sendCommand`
```cddl
CdpSendCommandCommand = {
method: "cdp.sendCommand",
params: ScriptEvaluateParameters,
}
CdpSendCommandParameters = {
method: text,
params: any,
session?: text,
}
CdpSendCommandResult = {
result: any,
session: text,
}
```
The command runs the
described [CDP command](https://chromedevtools.github.io/devtools-protocol)
and returns the result.
### Command `cdp.getSession`
```cddl
CdpGetSessionCommand = {
method: "cdp.sendCommand",
params: ScriptEvaluateParameters,
}
CdpGetSessionParameters = {
context: BrowsingContext,
}
CdpGetSessionResult = {
session: text,
}
```
The command returns the default CDP session for the selected browsing context.
### Events `cdp`
```cddl
CdpEventReceivedEvent = {
method: "cdp.<CDP Event Name>",
params: CdpEventReceivedParameters,
}
CdpEventReceivedParameters = {
event: text,
params: any,
session: text,
}
```
The event contains a CDP event.
### Field `channel`
Each command can be extended with a `channel`:
```cddl
Command = {
id: js-uint,
channel?: text,
CommandData,
Extensible,
}
```
If provided and non-empty string, the very same `channel` is added to the response:
```cddl
CommandResponse = {
id: js-uint,
channel?: text,
result: ResultData,
Extensible,
}
ErrorResponse = {
id: js-uint / null,
channel?: text,
error: ErrorCode,
message: text,
?stacktrace: text,
Extensible
}
```
When client uses
commands [`session.subscribe`](https://w3c.github.io/webdriver-bidi/#command-session-subscribe)
and [`session.unsubscribe`](https://w3c.github.io/webdriver-bidi/#command-session-unsubscribe)
with `channel`, the subscriptions are handled per channel, and the corresponding
`channel` filed is added to the event message:
```cddl
Event = {
channel?: text,
EventData,
Extensible,
}
```
## Dev Setup
### `npm`
This is a Node.js project, so install dependencies as usual:
```sh
npm install
```
### `cargo`
<!-- TODO(jrandolf): Remove after binaries get published -->
We use [cddlconv](https://github.com/google/cddlconv) to generate our WebDriverBidi types before building.
1. Install [Rust](https://rustup.rs/).
2. Run `cargo install --git https://github.com/google/cddlconv.git cddlconv`
### pre-commit.com integration
Refer to the documentation at [.pre-commit-config.yaml](.pre-commit-config.yaml).
```sh
pre-commit install --hook-type pre-push
```
### Starting WebDriver BiDi Server
This will run the server on port `8080`:
```sh
npm run server
```
Use the `PORT=` environment variable or `--port=` argument to run it on another port:
```sh
PORT=8081 npm run server
npm run server -- --port=8081
```
Use the `DEBUG` environment variable to see debug info:
```sh
DEBUG=* npm run server
```
Use the `DEBUG_DEPTH` (default: `10`) environment variable to see debug deeply nested objects:
```sh
DEBUG_DEPTH=100 DEBUG=* npm run server
```
Use the CLI argument `--headless=false` to run browser in headful mode:
```sh
npm run server -- --headless=false
```
Use the `CHANNEL=...` environment variable or `--channel=...` argument with one of
the following values to run the specific Chrome channel: `stable`,
`beta`, `canary`, `dev`.
The requested Chrome version should be installed.
```sh
CHANNEL=dev npm run server
npm run server -- --channel=dev
```
Use the CLI argument `--verbose` to have CDP events printed to the console. Note: you have to enable debugging output `bidi:mapper:debug:*` as well.
```sh
DEBUG=bidi:mapper:debug:* npm run server -- --verbose
```
or
```sh
DEBUG=* npm run server -- --verbose
```
### Starting on Linux and Mac
TODO: verify it works on Windows.
You can also run the server by using `npm run server`. It will write
output to the file `log.txt`:
```sh
npm run server -- --port=8081 --headless=false
```
### Running with in other project
Sometimes it good to verify that a change will not affect thing downstream for other packages.
There is a useful `puppeteer` label you can add to any PR to run Puppeteer test with your changes.
It will bundle `chromium-bidi` and install it in Puppeteer project then run that package test.
## Running
### Unit tests
Running:
```sh
npm run unit
```
### E2E tests
The E2E tests are written using Python, in order to learn how to eventually do
this in web-platform-tests.
#### Installation
Python 3.10+ and some dependencies are required:
```sh
python -m pip install --user pipenv
pipenv install
```
#### Running
The E2E tests require BiDi server running on the same host. By default, tests
try to connect to the port `8080`. The server can be run from the project root:
```sh
npm run e2e # alias to to e2e-headless
npm run e2e-headful
npm run e2e-headless
```
Use the `PORT` environment variable to connect to another port:
```sh
PORT=8081 npm run e2e
```
#### Updating snapshots
```sh
npm run e2e -- --snapshot-update
```
See https://github.com/tophat/syrupy for more information.
### Local http server
E2E tests use local http
server [`pytest-httpserver`](https://pytest-httpserver.readthedocs.io/), which is run
automatically with the tests. However,
sometimes it is useful to run the http server outside the test
case, for example for manual debugging. This can be done by running:
```sh
pipenv run local_http_server
```
...or directly:
```sh
python tests/tools/local_http_server.py
```
### Examples
Refer to [examples/README.md](examples/README.md).
## WPT (Web Platform Tests)
WPT is added as
a [git submodule](https://git-scm.com/book/en/v2/Git-Tools-Submodules). To get run
WPT tests:
### Check out and setup WPT
#### 1. Check out WPT
```sh
git submodule update --init
```
#### 2. Go to the WPT folder
```sh
cd wpt
```
#### 3. Set up virtualenv
Follow the [_System
Setup_](https://web-platform-tests.org/running-tests/from-local-system.html#system-setup)
instructions.
#### 4. Setup `hosts` file
Follow
the [`hosts` File Setup](https://web-platform-tests.org/running-tests/from-local-system.html#hosts-file-setup)
instructions.
##### 4.a On Linux, macOS or other UNIX-like system
```sh
./wpt make-hosts-file | sudo tee -a /etc/hosts
```
##### 4.b On **Windows**
This must be run in a PowerShell session with Administrator privileges:
```sh
python wpt make-hosts-file | Out-File $env:SystemRoot\System32\drivers\etc\hosts -Encoding ascii -Append
```
If you are behind a proxy, you also need to make sure the domains above are excluded
from your proxy lookups.
#### 5. Set `BROWSER_BIN`
Set the `BROWSER_BIN` environment variable to a Chrome, Edge or Chromium binary to launch.
For example, on macOS:
```sh
# Chrome
export BROWSER_BIN="/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary"
export BROWSER_BIN="/Applications/Google Chrome Dev.app/Contents/MacOS/Google Chrome Dev"
export BROWSER_BIN="/Applications/Google Chrome Beta.app/Contents/MacOS/Google Chrome Beta"
export BROWSER_BIN="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
export BROWSER_BIN="/Applications/Chromium.app/Contents/MacOS/Chromium"
# Edge
export BROWSER_BIN="/Applications/Microsoft Edge Canary.app/Contents/MacOS/Microsoft Edge Canary"
export BROWSER_BIN="/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge"
```
### Run WPT tests
#### 1. Make sure you have Chrome Dev installed
https://www.google.com/chrome/dev/
#### 2. Build Chromedriver BiDi
Oneshot:
```sh
npm run build
```
Continuously:
```sh
npm run build --watch
```
#### 3. Run
```sh
npm run wpt -- webdriver/tests/bidi/
```
### Update WPT expectations if needed
```sh
UPDATE_EXPECTATIONS=true npm run wpt -- webdriver/tests/bidi/
```
## How does it work?
The architecture is described in the
[WebDriver BiDi in Chrome Context implementation plan](https://docs.google.com/document/d/1VfQ9tv0wPSnb5TI-MOobjoQ5CXLnJJx9F_PxOMQc8kY)
.
There are 2 main modules:
1. backend WS server in `src`. It runs webSocket server, and for each ws connection
runs an instance of browser with BiDi Mapper.
2. front-end BiDi Mapper in `src/bidiMapper`. Gets BiDi commands from the backend,
and map them to CDP commands.
## Contributing
The BiDi commands are processed in the `src/bidiMapper/commandProcessor.ts`. To add a
new command, add it to `_processCommand`, write and call processor for it.
### Publish new `npm` release
#### Automatic release
We use [release-please](https://github.com/googleapis/release-please) to automate releases. When a release should be done, check for the release PR in our [pull requests](https://github.com/GoogleChromeLabs/chromium-bidi/pulls) and merge it.
#### Manual release
1. Dry-run
```sh
npm publish --dry-run
```
1. Open a PR bumping the chromium-bidi version number in `package.json` for review:
```sh
npm version patch -m 'chore: Release v%s' --no-git-tag-version
```
Instead of `patch`, use `minor` or `major` [as needed](https://semver.org/).
1. After the PR is reviewed, [create a GitHub release](https://github.com/GoogleChromeLabs/chromium-bidi/releases/new) specifying the tag name matching the bumped version.
Our CI then automatically publishes the new release to npm based on the tag name.
#### Roll into Chromium
This section assumes you already have a Chromium set-up locally,
and knowledge on [how to submit changes to the repo](https://chromium.googlesource.com/chromium/src/+/refs/heads/main/docs/contributing.md).
Otherwise submit an issue for a project maintainer.
1. Create a new branch in chromium `src/`.
2. Update the mapper version:
```shell
third_party/bidimapper/pull.sh
third_party/bidimapper/build.sh
```
3. Submit a CL with bug `chromedriver:4226`.
4. [Regenerate WPT expectations or baselines](https://chromium.googlesource.com/chromium/src/+/HEAD/docs/testing/run_web_platform_tests.md#test-expectations-and-baselines):
4.1. Trigger a build and test run:
```shell
third_party/blink/tools/blink_tool.py rebaseline-cl --build="linux-blink-rel" --verbose
```
4.2. Once the test completes on the builder, rerun that command to update the
baselines. Update test expectations if there are any crashes or timeouts.
Commit the changes (if any), and upload the new patch to the CL.
5. Add appropriate reviewers or comment the CL link on the PR.