Browse Source

docs: webdriver guide (#2461)

Co-authored-by: Ngo Iok Ui (Wu Yu Wei) <wusyong9104@gmail.com>
chip 4 năm trước cách đây
mục cha
commit
40d08a60fe

+ 17 - 0
docs/sidebar.json

@@ -69,6 +69,23 @@
               "usage/guides/visual/menu",
               "usage/guides/visual/system-tray"
             ]
+          },
+          {
+            "label": "WebDriver Testing",
+            "type": "category",
+            "items": [
+              "usage/guides/webdriver/introduction",
+              {
+                "label": "Example Application",
+                "type": "category",
+                "items": [
+                  "usage/guides/webdriver/example/setup",
+                  "usage/guides/webdriver/example/webdriverio",
+                  "usage/guides/webdriver/example/selenium"
+                ]
+              },
+              "usage/guides/webdriver/ci"
+            ]
           }
         ]
       },

+ 100 - 0
docs/usage/guides/webdriver/ci.md

@@ -0,0 +1,100 @@
+---
+title: Continuous Integration
+---
+
+Utilizing Linux and some programs to create a fake display, it is possible to run [WebDriver] tests with
+[`tauri-driver`] on your CI. The following example will use the [WebdriverIO] example we [previously built together] and
+GitHub Actions.
+
+This means the following assumptions:
+
+1. The Tauri application is in the repository root and the binary builds when running `cargo build --release`.
+2. The [WebDriverIO] test runner is in the `webdriver/webdriverio` directory and runs when `yarn test` is used in that
+   directory.
+
+The following is a commented GitHub Actions workflow file at `.github/workflows/webdriver.yml`
+
+```yaml
+# run this action when the repository is pushed to
+on: [ push ]
+
+# the name of our workflow
+name: WebDriver
+
+jobs:
+  # a single job named test
+  test:
+    # the display name the test job
+    name: WebDriverIO Test Runner
+
+    # we want to run on the latest linux environment
+    runs-on: ubuntu-latest
+
+    # the steps our job runs **in order**
+    steps:
+      # checkout the code on the workflow runner
+      - uses: actions/checkout@v2
+
+      # install system dependencies that Tauri needs to compile on Linux.
+      # note the extra dependencies for `tauri-driver` to run which are `webkit2gtk-driver` and  `xvfb`
+      - name: Tauri dependencies
+        run: >-
+          sudo apt-get update &&
+          sudo apt-get install -y
+          libgtk-3-dev
+          libgtksourceview-3.0-dev
+          webkit2gtk-4.0
+          libappindicator3-dev
+          webkit2gtk-driver
+          xvfb
+
+      # install the latest Rust stable
+      - name: Rust stable
+        uses: actions-rs/toolchain@v1
+        with:
+          toolchain: stable
+
+      # we run our rust tests before the webdriver tests to avoid testing a broken application
+      - name: Cargo test
+        uses: actions-rs/cargo@v1
+        with:
+          command: test
+
+      # build a release build of our application to be used during our WebdriverIO tests
+      - name: Cargo build
+        uses: actions-rs/cargo@v1
+        with:
+          command: build
+          args: --release
+
+      # install the latest stable node version at the time of writing
+      - name: Node v16
+        uses: actions/setup-node@v1
+        with:
+          node-version: 16.x
+
+      # install our Node.js dependencies with Yarn
+      - name: Yarn install
+        run: yarn install
+        working-directory: webdriver/webdriverio
+
+      # install the latest version of `tauri-driver`.
+      # note: the tauri-driver version is independent of any other Tauri versions
+      - name: Install tauri-driver
+        uses: actions-rs/cargo@v1
+        with:
+          command: install
+          args: tauri-driver
+
+      # run the WebdriverIO test suite.
+      # we run it through `xvfb-run` (the dependency we installed earlier) to have a fake
+      # display server which allows our application to run headless without any changes to the code
+      - name: WebdriverIO
+        run: xvfb-run yarn test
+        working-directory: webdriver/webdriverio
+```
+
+[WebDriver]: https://www.w3.org/TR/webdriver/
+[`tauri-driver`]: https://crates.io/crates/tauri-driver
+[WebdriverIO]: https://webdriver.io/
+[previously built together]: example/webdriverio

+ 256 - 0
docs/usage/guides/webdriver/example/selenium.md

@@ -0,0 +1,256 @@
+---
+title: Selenium
+---
+import Alert from '@theme/Alert'
+import Tabs from '@theme/Tabs'
+import TabItem from '@theme/TabItem'
+
+<Alert title="Example Application" type="info" icon="info-alt">
+
+This [Selenium] guide expects you to have already gone through the [example Application setup] in order to follow
+step-by-step. The general information may still be useful otherwise.
+</Alert>
+
+This WebDriver testing example will use [Selenium] and a popular Node.js testing suite. It is expected to already have
+Node.js installed, along with `npm` or `yarn` although the [finished example project] uses `yarn`.
+
+## Create a Directory for the Tests
+
+Let's start off by creating a space in our project to write these tests. We are going to be using a nested directory for
+this example project as we will later also go over other frameworks, but typically you will only need to use one. Create
+the directory we will use with `mkdir -p webdriver/selenium`. The rest of this guide will assume you are inside the
+`webdriver/selenium` directory.
+
+## Initializing a Selenium Project
+
+We will be using a pre-existing `package.json` to bootstrap this test suite because we have already chosen specific
+dependencies to use and want to showcase a simple working solution. The bottom of this section has a collapsed
+guide on how to set it up from scratch.
+
+`package.json`:
+```json
+{
+  "name": "selenium",
+  "version": "1.0.0",
+  "private": true,
+  "scripts": {
+    "test": "mocha"
+  },
+  "dependencies": {
+    "chai": "^4.3.4",
+    "mocha": "^9.0.3",
+    "selenium-webdriver": "^4.0.0-beta.4"
+  }
+}
+```
+
+We have a script which runs [Mocha] as a test framework exposed as the `test` command. We also have various dependencies
+that we will be using to run the tests. [Mocha] as the testing framework, [Chai] as the assertion library, and
+[`selenium-webdriver`] which is the Node.js [Selenium] package.
+
+<details><summary>Click me if you want to see how to set a project up from scratch</summary>
+
+If you wanted to install the dependencies from scratch, just run the following command.
+
+<Tabs groupId="package-manager"
+defaultValue="yarn"
+values={[
+{label: 'npm', value: 'npm'}, {label: 'Yarn', value: 'yarn'},
+]}>
+<TabItem value="npm">
+
+```sh
+npm install mocha chai selenium-webdriver
+```
+
+</TabItem>
+
+<TabItem value="yarn">
+
+```sh
+yarn add mocha chai selenium-webdriver
+```
+
+</TabItem>
+</Tabs>
+
+I suggest also adding a `"test": "mocha"` item in the `package.json` `"scripts"` key so that running mocha can be called
+simply with
+
+<Tabs groupId="package-manager"
+defaultValue="yarn"
+values={[
+{label: 'npm', value: 'npm'}, {label: 'Yarn', value: 'yarn'},
+]}>
+<TabItem value="npm">
+
+```sh
+npm test
+```
+
+</TabItem>
+
+<TabItem value="yarn">
+
+```sh
+yarn test
+```
+
+</TabItem>
+</Tabs>
+
+</details>
+
+## Testing
+
+Unlike the [WebdriverIO Test Suite](webdriverio#config), Selenium does not come out of the box with a Test Suite and
+leaves it up to the developer to build those out. We chose [Mocha] which is pretty neutral, and not related to WebDrivers
+at all, so our script will need to do a bit of work to set up everything for us in the right order. [Mocha] expects a
+testing file at `test/test.js` by default, so let's create that file now.
+
+`test/test.js`:
+```js
+const os = require("os");
+const path = require("path");
+const { expect } = require("chai");
+const { spawn, spawnSync } = require("child_process");
+const { Builder, By, Capabilities } = require("selenium-webdriver");
+
+// create the path to the expected application binary
+const application = path.resolve(
+  __dirname,
+  "..",
+  "..",
+  "..",
+  "target",
+  "release",
+  "hello-tauri-webdriver"
+);
+
+// keep track of the webdriver instance we create
+let driver;
+
+// keep track of the tauri-driver process we start
+let tauriDriver;
+
+before(async function() {
+  // set timeout to 2 minutes to allow the program to build if it needs to
+  this.timeout(120000)
+
+  // ensure the program has been built
+  spawnSync("cargo", ["build", "--release"]);
+
+  // start tauri-driver
+  tauriDriver = spawn(
+    path.resolve(os.homedir(), ".cargo", "bin", "tauri-driver"),
+    [],
+    { stdio: [null, process.stdout, process.stderr] }
+  );
+
+  const capabilities = new Capabilities();
+  capabilities.set("tauri:options", { application });
+  capabilities.setBrowserName("wry");
+
+  // start the webdriver client
+  driver = await new Builder()
+    .withCapabilities(capabilities)
+    .usingServer("http://localhost:4444/")
+    .build();
+});
+
+after(async function() {
+  // stop the webdriver session
+  await driver.quit();
+
+  // kill the tauri-driver process
+  tauriDriver.kill();
+});
+
+describe("Hello Tauri", () => {
+  it("should be cordial", async () => {
+    const text = await driver.findElement(By.css("body > h1")).getText();
+    expect(text).to.match(/^[hH]ello/);
+  });
+
+  it("should be excited", async () => {
+    const text = await driver.findElement(By.css("body > h1")).getText();
+    expect(text).to.match(/!$/);
+  });
+
+  it("should be easy on the eyes", async () => {
+    // selenium returns color css values as rgb(r, g, b)
+    const text = await driver.findElement(By.css("body")).getCssValue("background-color");
+
+    const rgb = text.match(/^rgb\((?<r>\d+), (?<g>\d+), (?<b>\d+)\)$/).groups;
+    expect(rgb).to.have.all.keys('r','g','b');
+
+    const luma =  0.2126 * rgb.r + 0.7152 * rgb.g  + 0.0722 * rgb.b ;
+    expect(luma).to.be.lessThan(100)
+  });
+});
+```
+
+If you are familiar with JS testing frameworks, `describe`, `it`, and `expect` should look familiar. We also have
+semi-complex `before()` and `after()` callbacks to setup and teardown mocha. Lines that are not the tests themselves
+have comments explaining what the setup and teardown code is doing. If you were familiar with the Spec file from the
+[WebdriverIO example](webdriverio#spec), you will notice a lot more code that isn't tests, as we have to set up a few
+more WebDriver related items.
+
+## Running the Test Suite
+
+Now that we are all set up with our dependencies and our test script, lets run it!
+
+<Tabs groupId="package-manager"
+defaultValue="yarn"
+values={[
+{label: 'npm', value: 'npm'}, {label: 'Yarn', value: 'yarn'},
+]}>
+<TabItem value="npm">
+
+```sh
+npm test
+```
+
+</TabItem>
+
+<TabItem value="yarn">
+
+```sh
+yarn test
+```
+
+</TabItem>
+</Tabs>
+
+We should see output the following output:
+
+```text
+➜  selenium git:(main) ✗ yarn test
+yarn run v1.22.11
+$ mocha
+
+
+  Hello Tauri
+    ✔ should be cordial (120ms)
+    ✔ should be excited
+    ✔ should be easy on the eyes
+
+
+  3 passing (588ms)
+
+Done in 0.93s.
+```
+
+We can see that our `Hello Tauri` sweet we created with `decribe` had all 3 items we created with `it` pass their
+tests!
+
+With [Selenium] and some hooking up to a test suite, we just enabled e2e testing without modifying our Tauri
+application at all!
+
+
+[Selenium]: https://selenium.dev/
+[finished example project]: https://github.com/chippers/hello_tauri
+[example Application setup]: setup
+[Mocha]: https://mochajs.org/
+[Chai]: https://www.chaijs.com/
+[`selenium-webdriver`]: https://www.npmjs.com/package/selenium-webdriver

+ 190 - 0
docs/usage/guides/webdriver/example/setup.md

@@ -0,0 +1,190 @@
+---
+title: Setup Example
+---
+
+import HelloTauriWebdriver from '@site/static/img/webdriver/hello-tauri-webdriver.png'
+
+This example application is going to solely focus on adding WebDriver testing to an already existing project. To have a
+project to test on in the next two sections, we are going to set up an extremely minimal Tauri application for use in
+our testing. We will not use the Tauri CLI, any frontend dependencies or build steps, and not be bundling the
+application afterwards. This is to showcase exactly a minimal suite to show off adding WebDriver testing to an existing
+application.
+
+If you just want to see the finished example project that utilizes what will be shown in this example guide, then you
+can see https://github.com/chippers/hello_tauri.
+
+## Initializing a Cargo Project
+
+We want to create a new binary Cargo project to house this example application. We can easily do this from the command
+line with `cargo new hello-tauri-webdriver --bin` which will scaffold a minimal binary Cargo project for us. This
+directory will serve as the working directory for the rest of this guide, so make sure commands you run are inside this
+new `hello-tauri-webdriver/` directory.
+
+## Creating a Minimal Frontend
+
+We will create a minimal HTML file to act as the frontend to our example application. We will also be using a few things
+from this frontend later during our WebDriver tests.
+
+First, let's create our Tauri `distDir` that we know we will need once building the Tauri portion of the application.
+`mkdir dist` should create a new directory called `dist/` in which we will be placing the following `index.html` file.
+
+`dist/index.html`:
+
+```html
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Hello Tauri!</title>
+    <style>
+        body {
+            /* Add a nice colorscheme */
+            background-color: #222831;
+            color: #ececec;
+
+            /* Make the body the exact size of the window */
+            margin: 0;
+            height: 100vh;
+            width: 100vw;
+
+            /* Vertically and horizontally center children of the body tag */
+            display: flex;
+            justify-content: center;
+            align-items: center;
+        }
+    </style>
+</head>
+<body>
+<h1>Hello, Tauri!</h1>
+</body>
+</html>
+```
+
+## Adding Tauri to the Cargo Project
+
+Next, we will add some necessary items to make our Cargo project into a Tauri project. First, is adding the dependencies
+to the Cargo Manifest (`Cargo.toml`) so that Cargo knows to pull in our dependencies while building.
+
+`Cargo.toml`:
+
+```toml
+[package]
+name = "hello-tauri-webdriver"
+version = "0.1.0"
+edition = "2018"
+
+# Needed to set up some things for Tauri at build time
+[build-dependencies]
+tauri-build = "1.0.0-beta.4"
+
+# The actual Tauri dependency, along with `custom-protocol` to serve the pages.
+[dependencies]
+tauri = { version = "1.0.0-beta.6", features = ["custom-protocol"] }
+
+# Make --release build a binary that is small (opt-level = "s") and fast (lto = true).
+# This is completely optional, but shows that testing the application as close to the
+# typical release settings is possible. Note: this will slow down compilation.
+[profile.release]
+incremental = false
+codegen-units = 1
+panic = "abort"
+opt-level = "s"
+lto = true
+```
+
+As you may have noticed, we added a `[build-dependency]`. To use the build dependency, we must use it from a build
+script. We will create one now at `build.rs`.
+
+`build.rs`:
+
+```rust
+fn main() {
+    // Only watch the `dist/` directory for recompiling, preventing unnecessary
+    // changes when we change files in other project subdirectories.
+    println!("cargo:rerun-if-changed=dist");
+
+    // Run the Tauri build-time helpers
+    tauri_build::build()
+}
+```
+
+With all that setup, our Cargo Project now knows how to pull in and build our Tauri dependencies. Let's finish making
+this minimal example a Tauri application by setting up Tauri in the actual project code. We will be editing
+the `src/main.rs`
+file to add this Tauri functionality.
+
+`src/main.rs`:
+
+```rust
+fn main() {
+    tauri::Builder::default()
+        .run(tauri::generate_context!())
+        .expect("unable to run Tauri application");
+}
+```
+
+Pretty simple, right?
+
+## Tauri Configuration
+
+We are going to need 2 things to successfully build the application. First, we need an icon file. You can use any PNG
+for this next part and copy it into `icon.png`. Typically, this will be provided as part of the scaffolding when you use
+the Tauri CLI to create a project. To get the default Tauri icon, we can download the icon used by the Hello Tauri
+example repository with the
+command `curl -L "https://github.com/chippers/hello_tauri/raw/main/icon.png" --output icon.png`.
+
+The second thing we will need is a `tauri.conf.json` to specify some important configuration values to Tauri. Again,
+this would typically come from the `tauri init` scaffolding command, but we will be creating our own minimal config
+here.
+
+`tauri.conf.json`:
+
+```json
+{
+  "build": {
+    "distDir": "dist"
+  },
+  "tauri": {
+    "bundle": {
+      "identifier": "studio.tauri.hello_tauri_webdriver",
+      "icon": [
+        "icon.png"
+      ]
+    },
+    "allowlist": {
+      "all": false
+    },
+    "windows": [
+      {
+        "width": 800,
+        "height": 600,
+        "resizable": true,
+        "fullscreen": false
+      }
+    ]
+  }
+}
+```
+
+I'll go over some of these. You can see the `dist/` directory we created earlier specified as the `distDir` property. We
+set a bundle identifier so that the built application has a unique id, along with setting the `icon.png` as the only
+icon. We aren't using any Tauri apis or features, so we just disable all them in `allowlist` by setting `"all": false`.
+The window values just sets a single window to be created with some reasonable default values.
+
+At this point, we have a basic Hello World application that when ran, should display a simple greeting.
+
+## Running the Example Application
+
+To make sure we did it right, let's build this application! We will run this as a `--release` application because we
+will also run our WebDriver tests with a release profile. Run `cargo run --release` and after some compiling we should
+see the following application pop up.
+
+<div style={{textAlign: 'center'}}>
+    <img src={HelloTauriWebdriver}/>
+</div>
+
+_Note: If you are modifying the application and want to use the Devtools, then run it without `--release` and "Inspect
+Element" should be available in the right click menu._
+
+We should now be ready to start testing this application with some WebDriver frameworks. This guide will go over both
+[WebdriverIO](webdriverio) and [Selenium](selenium) in that order.

+ 275 - 0
docs/usage/guides/webdriver/example/webdriverio.md

@@ -0,0 +1,275 @@
+---
+title: WebdriverIO
+---
+import Alert from '@theme/Alert'
+import Tabs from '@theme/Tabs'
+import TabItem from '@theme/TabItem'
+
+<Alert title="Example Application" type="info" icon="info-alt">
+
+This [WebdriverIO] guide expects you to have already gone through the [example Application setup] in order to follow
+step-by-step. The general information may still be useful otherwise.
+</Alert>
+
+This WebDriver testing example will use [WebdriverIO] and its testing suite. It is expected to already have Node.js
+installed, along with `npm` or `yarn` although the [finished example project] uses `yarn`.
+
+## Create a Directory for the Tests
+
+Let's start off by creating a space in our project to write these tests. We are going to be using a nested directory for
+this example project as we will later also go over other frameworks, but typically you will only need to use one. Create
+the directory we will use with `mkdir -p webdriver/webdriverio`. The rest of this guide will assume you are inside the
+`webdriver/webdriverio` directory.
+
+## Initializing a WebdriverIO Project
+
+We will be using a pre-existing `package.json` to bootstrap this test suite because we have already chosen specific
+[WebdriverIO] config options and want to showcase a simple working solution. The bottom of this section has a collapsed
+guide on how to set it up from scratch.
+
+`package.json`:
+```json
+{
+  "name": "webdriverio",
+  "version": "1.0.0",
+  "private": true,
+  "scripts": {
+    "test": "wdio run wdio.conf.js"
+  },
+  "dependencies": {
+    "@wdio/cli": "^7.9.1"
+  },
+  "devDependencies": {
+    "@wdio/local-runner": "^7.9.1",
+    "@wdio/mocha-framework": "^7.9.1",
+    "@wdio/spec-reporter": "^7.9.0"
+  }
+}
+```
+
+We have a script which runs a [WebdriverIO] config as a test suite exposed as the `test` command. We also have various
+dependencies that were added by the `@wdio/cli` command when we first set it up. In short, these dependencies are for
+the most simple setup using a local WebDriver runner, [Mocha] as the test framework, and a simple Spec Reporter.
+
+<details><summary>Click me if you want to see how to set a project up from scratch</summary>
+
+The CLI is interactive, and you may choose the tools to work with yourself. Note that you will likely diverge from
+the rest of the guide, and need to set up the differences yourself.
+
+Let's add the [WebdriverIO] CLI to this npm project.
+
+<Tabs groupId="package-manager"
+defaultValue="yarn"
+values={[
+{label: 'npm', value: 'npm'}, {label: 'Yarn', value: 'yarn'},
+]}>
+<TabItem value="npm">
+
+```sh
+npm install @wdio/cli
+```
+
+</TabItem>
+
+<TabItem value="yarn">
+
+```sh
+yarn add @wdio/cli
+```
+
+</TabItem>
+</Tabs>
+
+To then run the interactive config command to set up a [WebdriverIO] test suite, you can then run:
+
+<Tabs groupId="package-manager"
+defaultValue="yarn"
+values={[
+{label: 'npm', value: 'npm'}, {label: 'Yarn', value: 'yarn'},
+]}>
+<TabItem value="npm">
+
+```sh
+npx wdio config
+```
+
+</TabItem>
+
+<TabItem value="yarn">
+
+```sh
+yarn wdio config
+```
+
+</TabItem>
+</Tabs>
+
+</details>
+
+## Config
+
+You may have noticed that the `test` script in our `package.json` mentions a file `wdio.conf.js`. That's the [WebdriverIO]
+config file which controls most aspects of our testing suite.
+
+`wdio.conf.js`:
+```js
+const os = require("os");
+const path = require("path");
+const { spawn, spawnSync } = require("child_process");
+
+// keep track of the `tauri-driver` child process
+let tauriDriver;
+
+exports.config = {
+  specs: ["./test/specs/**/*.js"],
+  maxInstances: 1,
+  capabilities: [
+    {
+      maxInstances: 1,
+      "tauri:options": {
+        application: "../../target/release/hello-tauri-webdriver",
+      },
+    },
+  ],
+  reporters: ["spec"],
+  framework: "mocha",
+  mochaOpts: {
+    ui: "bdd",
+    timeout: 60000,
+  },
+
+  // ensure the rust project is built since we expect this binary to exist for the webdriver sessions
+  onPrepare: () => spawnSync("cargo", ["build", "--release"]),
+
+  // ensure we are running `tauri-driver` before the session starts so that we can proxy the webdriver requests
+  beforeSession: () =>
+    (tauriDriver = spawn(
+      path.resolve(os.homedir(), ".cargo", "bin", "tauri-driver"),
+      [],
+      { stdio: [null, process.stdout, process.stderr] }
+    )),
+
+  // clean up the `tauri-driver` process we spawned at the start of the session
+  afterSession: () => tauriDriver.kill(),
+};
+```
+
+If you are interested in the properties on `exports.config` object, then I [suggest reading the documentation] for it.
+For non-WDIO specific items, there are comments explaining why we are running commands in `onPrepare`, `beforeSession`,
+and `afterSession`. We also have our specs set to `"./test/specs/**/*.js"`, so let's create a spec now.
+
+## Spec
+
+A spec contains the code that is testing your actual application. The test runner will load these specs and automatically
+run them as it sees fit. Let's create our spec now in the directory we specified.
+
+`test/specs/example.e2e.js`:
+```js
+// calculates the luma from a hex color `#abcdef`
+function luma(hex) {
+  if (hex.startsWith("#")) {
+    hex = hex.substring(1);
+  }
+
+  const rgb = parseInt(hex, 16);
+  const r = (rgb >> 16) & 0xff;
+  const g = (rgb >> 8) & 0xff;
+  const b = (rgb >> 0) & 0xff;
+  return  0.2126 * r + 0.7152 * g + 0.0722 * b;
+}
+
+describe("Hello Tauri", () => {
+  it("should be cordial", async () => {
+    const header = await $("body > h1");
+    const text = await header.getText();
+    expect(text).toMatch(/^[hH]ello/);
+  });
+
+  it("should be excited", async () => {
+    const header = await $("body > h1");
+    const text = await header.getText();
+    expect(text).toMatch(/!$/);
+  });
+
+  it("should be easy on the eyes", async () => {
+    const body = await $("body");
+    const backgroundColor = await body.getCSSProperty("background-color");
+    expect(luma(backgroundColor.parsed.hex)).toBeLessThan(100);
+  });
+});
+```
+
+The `luma` function on top is just a helper function for one of our tests and is not related to the actual testing of
+the application. If you are familiar with other testing frameworks, you may notice similar functions being exposed that
+are used such as `describe`, `it`, and `expect`. The other APIs, such as items like `$` and the methods it exposes is
+covered by the [WebdriverIO API docs](https://webdriver.io/docs/api).
+
+## Running the Test Suite
+
+Now that we are all set up with a config and a spec, let's run it!
+
+<Tabs groupId="package-manager"
+defaultValue="yarn"
+values={[
+{label: 'npm', value: 'npm'}, {label: 'Yarn', value: 'yarn'},
+]}>
+<TabItem value="npm">
+
+```sh
+npm test
+```
+
+</TabItem>
+
+<TabItem value="yarn">
+
+```sh
+yarn test
+```
+
+</TabItem>
+</Tabs>
+
+We should see output the following output:
+
+```text
+➜  webdriverio git:(main) ✗ yarn test
+yarn run v1.22.11
+$ wdio run wdio.conf.js
+
+Execution of 1 workers started at 2021-08-17T08:06:10.279Z
+
+[0-0] RUNNING in undefined - /test/specs/example.e2e.js
+[0-0] PASSED in undefined - /test/specs/example.e2e.js
+
+ "spec" Reporter:
+------------------------------------------------------------------
+[wry 0.12.1 linux #0-0] Running: wry (v0.12.1) on linux
+[wry 0.12.1 linux #0-0] Session ID: 81e0107b-4d38-4eed-9b10-ee80ca47bb83
+[wry 0.12.1 linux #0-0]
+[wry 0.12.1 linux #0-0] » /test/specs/example.e2e.js
+[wry 0.12.1 linux #0-0] Hello Tauri
+[wry 0.12.1 linux #0-0]    ✓ should be cordial
+[wry 0.12.1 linux #0-0]    ✓ should be excited
+[wry 0.12.1 linux #0-0]    ✓ should be easy on the eyes
+[wry 0.12.1 linux #0-0]
+[wry 0.12.1 linux #0-0] 3 passing (244ms)
+
+
+Spec Files:	 1 passed, 1 total (100% completed) in 00:00:01
+
+Done in 1.98s.
+```
+
+We see the Spec Reporter tell us that all 3 tests from the `test/specs/example.e2e.js` file, along with the final report
+`Spec Files:	 1 passed, 1 total (100% completed) in 00:00:01`.
+
+Using the [WebdriverIO] test suite, we just easily enabled e2e testing for our Tauri application from just a few lines
+of configuration and a single command to run it! Even better, we didn't have to modify the application at all.
+
+
+[WebdriverIO]: https://webdriver.io/
+[finished example project]: https://github.com/chippers/hello_tauri
+[example Application setup]: setup
+[Mocha]: https://mochajs.org/
+[suggest reading the documentation]: (https://webdriver.io/docs/configurationfile)

+ 56 - 0
docs/usage/guides/webdriver/introduction.md

@@ -0,0 +1,56 @@
+---
+title: Introduction
+---
+import Alert from '@theme/Alert'
+
+<Alert title="Currently in pre-alpha" type="info" icon="info-alt">
+
+Webdriver support for Tauri is still in pre-alpha. Tooling that is dedicated to it such as [tauri-driver] is still in
+active development and may change as necessary over time. Additionally, only Windows and Linux are currently supported.
+</Alert>
+
+[WebDriver] is a standardized interface to interact with web documents that is primarily intended for automated testing.
+Tauri supports the [WebDriver] interface by leveraging the native platform's [WebDriver] server underneath a
+cross-platform wrapper [`tauri-driver`].
+
+## System Dependencies
+
+Install the latest [`tauri-driver`] or update an existing installation by running:
+
+```sh
+cargo install tauri-driver
+```
+
+Because we currently utilize the platform's native [WebDriver] server, there are some requirements for running
+[`tauri-driver`] on supported platforms. Platform support is currently limited to Linux and Windows.
+
+### Linux
+
+We use `WebKitWebDriver` on linux platforms. Check if this binary exists already (command `which WebKitWebDriver`) as
+some distributions bundle it with the regular webkit package. Other platforms may have a separate package for them such
+as `webkit2gtk-driver` on Debian based distributions.
+
+### Windows
+
+Make sure to grab the version of [Microsoft Edge Driver] that matches your Windows' Edge version that the application is
+being built and tested on. On up-to-date Window installs, this should almost always be the latest stable version. If the
+two versions do not match, you may experience your WebDriver testing suite hanging while trying to connect.
+
+The download contains a binary called `msedgedriver.exe`. [`tauri-driver`] looks for that binary in the `$PATH` so make
+sure it's either available on the path or use the `--native-driver` option on [`tauri-driver`]. On Windows CI machines,
+you may want to download this automatically as part of the CI setup process to ensure the Edge and Edge Driver versions
+stay in sync. A guide on how to do this may be added at a later date.
+
+## Example Application
+
+The [next section](example/setup) of the guide will show step-by-step how to create a minimal example application that
+is tested with WebDriver.
+
+If you prefer to just see the result of the guide and look over a finished minimal codebase that utilizes it then you
+can look at https://github.com/chippers/hello_tauri. That example also comes with a CI script to test with GitHub
+actions, but you may still be interested in the [WebDriver CI](ci) guide as it explains the concept a bit more.
+
+[WebDriver]: https://www.w3.org/TR/webdriver/
+[`tauri-driver`]: https://crates.io/crates/tauri-driver
+[tauri-driver]: https://crates.io/crates/tauri-driver
+[Microsoft Edge Driver]: https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/

+ 4 - 12
tooling/webdriver/README.md

@@ -13,26 +13,18 @@ You can configure the ports used with arguments when starting the binary:
 * `--native-port` (default: `4445`)
 
 Supported platforms:
-* **[In Progress]** Linux w/ `WebKitWebDriver`
-* **[In Progress]** Windows w/ [Microsoft Edge Driver]
+* **[pre-alpha]** Linux w/ `WebKitWebDriver`
+* **[pre-alpha]** Windows w/ [Microsoft Edge Driver]
 * **[Todo]** macOS w/ [Appium Mac2 Driver] (probably)
 
 _note: the (probably) items haven't been proof-of-concept'd yet, and if it is
 not possible to use the listed native webdriver, then a custom implementation
 will be used that wraps around [wry]._
 
-
 ## Trying it out
 
-**Until this branch is merged into Tauri `dev`, this code works for pure [wry]
-applications only.**
-
-Currently, this uses a branch on [wry] `feat/webdriver`. The support for
-automated actions goes all the way down to wry with no real layer for just
-Tauri yet. For Windows, the [wry] branch only supports the `win32` backend
-and not `winrt`, unless you are okay with the webview not being closable by
-the webdriver.
-
+Check out the documentation at https://tauri.studio/en/docs/usage/guides/webdriver/ci to build a small example
+application that had WebDriver tests.
 
 [WebDriver Intermediary Node]: https://www.w3.org/TR/webdriver/#dfn-intermediary-nodes
 [WebDriver Remote Ends]: https://www.w3.org/TR/webdriver/#dfn-remote-ends