JSPM

  • Created
  • Published
  • Downloads 7559139
  • Score
    100M100P100Q228494F
  • License Apache-2.0

An implementation of the WebDriver BiDi protocol for Chromium implemented as a JavaScript layer translating between BiDi and CDP, running inside a Chrome tab.

Package Exports

    This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (chromium-bidi) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

    Readme

    WebDriver BiDi for Chromium chromium-bidi on npm

    E2E Tests Unit Tests WPT Tests

    This is an implementation of the 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 in WPT WebDriver BiDi status.

    BiDi+

    "BiDi+" is an extension of the WebDriver BiDi protocol. In addition to the WebDriver BiDi it has:

    Command cdp.sendCommand

    CdpSendCommandCommand = {
      method: "cdp.sendCommand",
      params: ScriptEvaluateParameters,
    }
    
    CdpSendCommandParameters = {
       cdpMethod: text,
       cdpParams: any,
       cdpSession?: text,
    }
    
    CdpSendCommandResult = {
       result: any,
       cdpSession: text,
    }

    The command runs the described CDP command and returns result.

    Command cdp.getSession

    CdpGetSessionCommand = {
       method: "cdp.sendCommand",
       params: ScriptEvaluateParameters,
    }
    
    CdpGetSessionParameters = {
       context: BrowsingContext,
    }
    
    CdpGetSessionResult = {
       cdpSession: text,
    }

    The command returns the default CDP session for the selected browsing context.

    Event cdp.eventReceived

    CdpEventReceivedEvent = {
       method: "cdp.eventReceived",
       params: ScriptEvaluateParameters,
    }
    
    CdpEventReceivedParameters = {
       cdpMethod: text,
       cdpParams: any,
       cdpSession: string,
    }

    The event contains a CDP event.

    Field channel

    Each command can be extended with a channel:

    Command = {
       id: js-uint,
       channel?: text,
       CommandData,
       Extensible,
    }

    If provided and non-empty string, the very same channel is added to the response:

    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 and session.unsubscribe with channel, the subscriptions are handled per channel, and the corresponding channel filed is added to the event message:

    Event = {
      channel?: text,
      EventData,
      Extensible,
    }

    Setup

    This is a Node.js project, so install dependencies as usual:

    npm install

    Starting the Server

    This will run the server on port 8080:

    npm run server

    Use the PORT= environment variable or --port= argument to run it on another port:

    PORT=8081 npm run server
    npm run server -- --port=8081

    Use the DEBUG environment variable to see debug info:

    DEBUG=* npm run server

    Use the CLI argument --headless=false to run browser in headful mode:

    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: chrome, chrome-beta, chrome-canary, chrome-dev.

    The requested Chrome version should be installed.

    CHANNEL=chrome-dev npm run server
    npm run server -- --channel=chrome-dev

    Starting on Linux and Mac

    TODO: verify if it works on Windows.

    You can also run the server by using script ./runBiDiServer.sh. It will write output to the file log.txt:

    ./runBiDiServer.sh --port=8081 --headless=false

    Running

    Unit tests

    Running:

    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.6+ and some dependencies are required:

    python3 -m pip install --user -r tests/requirements.txt

    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:

    npm run e2e

    Use the PORT environment variable to connect to another port:

    PORT=8081 npm run e2e

    Examples

    The examples are stored in the /examples folder and are intended to show who the BiDi protocol can be used. Examples are based on Puppeteer's examples .

    Installation

    The examples are written using Python, to align with e2e test. Python 3.6+ and some dependencies are required:

    python3 -m pip install --user -r tests/requirements.txt

    Running

    The examples require BiDi server running on the same host on the port 8080. The server can be run from the project root:

    npm run server

    After running server, examples can be simply run:

    python3 examples/console_log_example.py
    python3 examples/script_example.py

    WPT

    WPT is added as a git submodule. To get run WPT tests:

    Check out WPT and setup

    1. Check out WPT

    git submodule update --init

    2. Go to the WPT folder

    cd wpt

    3. Set up virtualenv

    Follow the System Setup instructions.

    4. Setup hosts file

    Follow the hosts File Setup instructions.

    On Linux, macOS or other UNIX-like system
    ./wpt make-hosts-file | sudo tee -a /etc/hosts
    And on Windows

    This must be run in a PowerShell session with Administrator privileges:

    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 the WPT_BROWSER_PATH environment variable to a Chrome, Edge or Chromium binary to launch. For example, on macOS:

    export WPT_BROWSER_PATH="/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary"
    export WPT_BROWSER_PATH="/Applications/Microsoft Edge Canary.app/Contents/MacOS/Microsoft Edge Canary"
    export WPT_BROWSER_PATH="/Applications/Chromium.app/Contents/MacOS/Chromium"

    Run WPT tests

    1. Make sure you have Chrome Dev instaled

    https://www.google.com/chrome/dev/

    1. Build ChromeDriver BiDi

    npm run build

    2. Run

    ./wpt/wpt run \
      --webdriver-binary ./runBiDiServer.sh \
      --binary "$WPT_BROWSER_PATH" \
      --manifest ./wpt/MANIFEST.json \
      --metadata ./wpt-metadata \
      chromium \
      webdriver/tests/bidi/

    Update WPT expectations if needed

    1. Run WPT tests with custom log-wptreport:

    ./wpt/wpt run \
      --webdriver-binary ./runBiDiServer.sh \
      --binary "$WPT_BROWSER_PATH" \
      --manifest ./wpt/MANIFEST.json \
      --metadata ./wpt-metadata \
      --log-wptreport wptreport.json \
      chromium \
      webdriver/tests/bidi/

    2. Update expectations based on the previous test run:

    ./wpt/wpt update-expectations \
      --product chromium \
      --manifest ./wpt/MANIFEST.json \
      --metadata ./wpt-metadata \
      ./wptreport.json

    How does it work?

    The architecture is described in the WebDriver BiDi in Chrome Context implementation plan .

    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

    1. On the main branch, bump the chromium-bidi version number in package.json:

      npm version patch -m 'Release v%s'

      Instead of patch, use minor or major as needed.

      Note that this produces a Git commit + tag.

    2. Push the release commit and tag:

      git push && git push --tags

      Our CI then automatically publishes the new release to npm.