From 40d08a60fe44fda034a2d3f014fad7cd7a18df1c Mon Sep 17 00:00:00 2001 From: chip Date: Tue, 24 Aug 2021 06:11:37 -0700 Subject: [PATCH] docs: webdriver guide (#2461) Co-authored-by: Ngo Iok Ui (Wu Yu Wei) --- docs/sidebar.json | 17 ++ docs/usage/guides/webdriver/ci.md | 100 +++++++ .../guides/webdriver/example/selenium.md | 256 ++++++++++++++++ docs/usage/guides/webdriver/example/setup.md | 190 ++++++++++++ .../guides/webdriver/example/webdriverio.md | 275 ++++++++++++++++++ docs/usage/guides/webdriver/introduction.md | 56 ++++ tooling/webdriver/README.md | 16 +- 7 files changed, 898 insertions(+), 12 deletions(-) create mode 100644 docs/usage/guides/webdriver/ci.md create mode 100644 docs/usage/guides/webdriver/example/selenium.md create mode 100644 docs/usage/guides/webdriver/example/setup.md create mode 100644 docs/usage/guides/webdriver/example/webdriverio.md create mode 100644 docs/usage/guides/webdriver/introduction.md diff --git a/docs/sidebar.json b/docs/sidebar.json index 39afbc481..36df2441f 100644 --- a/docs/sidebar.json +++ b/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" + ] } ] }, diff --git a/docs/usage/guides/webdriver/ci.md b/docs/usage/guides/webdriver/ci.md new file mode 100644 index 000000000..5aba5c94b --- /dev/null +++ b/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 diff --git a/docs/usage/guides/webdriver/example/selenium.md b/docs/usage/guides/webdriver/example/selenium.md new file mode 100644 index 000000000..361973dda --- /dev/null +++ b/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' + + + +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. + + +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. + +
Click me if you want to see how to set a project up from scratch + +If you wanted to install the dependencies from scratch, just run the following command. + + + + +```sh +npm install mocha chai selenium-webdriver +``` + + + + + +```sh +yarn add mocha chai selenium-webdriver +``` + + + + +I suggest also adding a `"test": "mocha"` item in the `package.json` `"scripts"` key so that running mocha can be called +simply with + + + + +```sh +npm test +``` + + + + + +```sh +yarn test +``` + + + + +
+ +## 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\((?\d+), (?\d+), (?\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! + + + + +```sh +npm test +``` + + + + + +```sh +yarn test +``` + + + + +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 diff --git a/docs/usage/guides/webdriver/example/setup.md b/docs/usage/guides/webdriver/example/setup.md new file mode 100644 index 000000000..a2ff6de28 --- /dev/null +++ b/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 + + + + + Hello Tauri! + + + +

Hello, Tauri!

+ + +``` + +## 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. + +
+ +
+ +_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. \ No newline at end of file diff --git a/docs/usage/guides/webdriver/example/webdriverio.md b/docs/usage/guides/webdriver/example/webdriverio.md new file mode 100644 index 000000000..3697f914c --- /dev/null +++ b/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' + + + +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. + + +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. + +
Click me if you want to see how to set a project up from scratch + +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. + + + + +```sh +npm install @wdio/cli +``` + + + + + +```sh +yarn add @wdio/cli +``` + + + + +To then run the interactive config command to set up a [WebdriverIO] test suite, you can then run: + + + + +```sh +npx wdio config +``` + + + + + +```sh +yarn wdio config +``` + + + + +
+ +## 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! + + + + +```sh +npm test +``` + + + + + +```sh +yarn test +``` + + + + +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) diff --git a/docs/usage/guides/webdriver/introduction.md b/docs/usage/guides/webdriver/introduction.md new file mode 100644 index 000000000..dc87ecd2d --- /dev/null +++ b/docs/usage/guides/webdriver/introduction.md @@ -0,0 +1,56 @@ +--- +title: Introduction +--- +import Alert from '@theme/Alert' + + + +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. + + +[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/ diff --git a/tooling/webdriver/README.md b/tooling/webdriver/README.md index 18e05f3bf..4f23bead7 100644 --- a/tooling/webdriver/README.md +++ b/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