Skip to content

Commit 54f5266

Browse files
feat(develop): update Webdriver tests section (#3450)
Co-authored-by: Fabian-Lars <[email protected]>
1 parent 268b54f commit 54f5266

File tree

6 files changed

+272
-103
lines changed

6 files changed

+272
-103
lines changed

src/content/docs/develop/Tests/WebDriver/Example/selenium.mdx

Lines changed: 65 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ sidebar:
55
i18nReady: true
66
---
77

8-
{/* TODO: REVISE COPY TO V2 */}
9-
108
import CommandTabs from '@components/CommandTabs.astro';
119

1210
:::note
@@ -16,14 +14,14 @@ Make sure to go through the [prerequisites instructions] to be able to follow th
1614
:::
1715

1816
This WebDriver testing example will use [Selenium] and a popular Node.js testing suite. You are expected to already have
19-
Node.js installed, along with `npm` or `yarn` although the [finished example project] uses `yarn`.
17+
Node.js installed, along with `npm` or `yarn` although the [finished example project] uses `pnpm`.
2018

2119
## Create a Directory for the Tests
2220

2321
Let's create a space to write these tests in our project. We will be using a nested directory for
2422
this example project as we will later also go over other frameworks, but typically you will only need to use one. Create
25-
the directory we will use with `mkdir -p webdriver/selenium`. The rest of this guide will assume you are inside the
26-
`webdriver/selenium` directory.
23+
the directory we will use with `mkdir -p e2e-tests`. The rest of this guide will assume you are inside the
24+
`e2e-tests` directory.
2725

2826
## Initializing a Selenium Project
2927

@@ -38,13 +36,14 @@ guide on how to set it up from scratch.
3836
"name": "selenium",
3937
"version": "1.0.0",
4038
"private": true,
39+
"type": "module",
4140
"scripts": {
4241
"test": "mocha"
4342
},
4443
"dependencies": {
45-
"chai": "^4.3.4",
46-
"mocha": "^9.0.3",
47-
"selenium-webdriver": "^4.0.0-beta.4"
44+
"chai": "^5.2.1",
45+
"mocha": "^11.7.1",
46+
"selenium-webdriver": "^4.34.0"
4847
}
4948
}
5049
```
@@ -80,42 +79,60 @@ testing file at `test/test.js` by default, so let's create that file now.
8079
`test/test.js`:
8180

8281
```javascript
83-
const os = require('os');
84-
const path = require('path');
85-
const { expect } = require('chai');
86-
const { spawn, spawnSync } = require('child_process');
87-
const { Builder, By, Capabilities } = require('selenium-webdriver');
82+
import os from 'os';
83+
import path from 'path';
84+
import { expect } from 'chai';
85+
import { spawn, spawnSync } from 'child_process';
86+
import { Builder, By, Capabilities } from 'selenium-webdriver';
87+
import { fileURLToPath } from 'url';
88+
89+
const __dirname = fileURLToPath(new URL('.', import.meta.url));
8890

8991
// create the path to the expected application binary
9092
const application = path.resolve(
9193
__dirname,
9294
'..',
9395
'..',
94-
'..',
96+
'src-tauri',
9597
'target',
96-
'release',
97-
'hello-tauri-webdriver'
98+
'debug',
99+
'tauri-app'
98100
);
99101

100102
// keep track of the webdriver instance we create
101103
let driver;
102104

103105
// keep track of the tauri-driver process we start
104106
let tauriDriver;
107+
let exit = false;
105108

106109
before(async function () {
107110
// set timeout to 2 minutes to allow the program to build if it needs to
108111
this.timeout(120000);
109112

110-
// ensure the program has been built
111-
spawnSync('cargo', ['build', '--release']);
113+
// ensure the app has been built
114+
spawnSync('yarn', ['tauri', 'build', '--debug', '--no-bundle'], {
115+
cwd: path.resolve(__dirname, '../..'),
116+
stdio: 'inherit',
117+
shell: true,
118+
});
112119

113120
// start tauri-driver
114121
tauriDriver = spawn(
115122
path.resolve(os.homedir(), '.cargo', 'bin', 'tauri-driver'),
116123
[],
117124
{ stdio: [null, process.stdout, process.stderr] }
118125
);
126+
tauriDriver.on('error', (error) => {
127+
console.error('tauri-driver error:', error);
128+
process.exit(1);
129+
});
130+
tauriDriver.on('exit', (code) => {
131+
if (!exit) {
132+
console.error('tauri-driver exited with code:', code);
133+
process.exit(1);
134+
}
135+
});
119136

120137
const capabilities = new Capabilities();
121138
capabilities.set('tauri:options', { application });
@@ -130,10 +147,7 @@ before(async function () {
130147

131148
after(async function () {
132149
// stop the webdriver session
133-
await driver.quit();
134-
135-
// kill the tauri-driver process
136-
tauriDriver.kill();
150+
await closeTauriDriver();
137151
});
138152

139153
describe('Hello Tauri', () => {
@@ -160,6 +174,34 @@ describe('Hello Tauri', () => {
160174
expect(luma).to.be.lessThan(100);
161175
});
162176
});
177+
178+
async function closeTauriDriver() {
179+
exit = true;
180+
// kill the tauri-driver process
181+
tauriDriver.kill();
182+
// stop the webdriver session
183+
await driver.quit();
184+
}
185+
186+
function onShutdown(fn) {
187+
const cleanup = () => {
188+
try {
189+
fn();
190+
} finally {
191+
process.exit();
192+
}
193+
};
194+
195+
process.on('exit', cleanup);
196+
process.on('SIGINT', cleanup);
197+
process.on('SIGTERM', cleanup);
198+
process.on('SIGHUP', cleanup);
199+
process.on('SIGBREAK', cleanup);
200+
}
201+
202+
onShutdown(() => {
203+
closeTauriDriver();
204+
});
163205
```
164206
165207
If you are familiar with JS testing frameworks, `describe`, `it`, and `expect` should look familiar. We also have
@@ -201,7 +243,7 @@ application at all!
201243
202244
[prerequisites instructions]: /develop/tests/webdriver/
203245
[selenium]: https://selenium.dev/
204-
[finished example project]: https://github.com/chippers/hello_tauri
246+
[finished example project]: https://github.com/tauri-apps/webdriver-example
205247
[mocha]: https://mochajs.org/
206248
[chai]: https://www.chaijs.com/
207249
[`selenium-webdriver`]: https://www.npmjs.com/package/selenium-webdriver

src/content/docs/develop/Tests/WebDriver/Example/webdriverio.mdx

Lines changed: 74 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ sidebar:
55
i18nReady: true
66
---
77

8-
{/* TODO: REVISE COPY TO V2 */}
9-
108
import CommandTabs from '@components/CommandTabs.astro';
119

1210
:::note
@@ -16,14 +14,14 @@ Make sure to go through the [prerequisites instructions] to be able to follow th
1614
:::
1715

1816
This WebDriver testing example will use [WebdriverIO], and its testing suite. It is expected to have Node.js already
19-
installed, along with `npm` or `yarn` although the [finished example project] uses `yarn`.
17+
installed, along with `npm` or `yarn` although the [finished example project] uses `pnpm`.
2018

2119
## Create a Directory for the Tests
2220

2321
Let's create a space to write these tests in our project. We will be using a nested directory for
2422
this example project as we will later also go over other frameworks, but typically you only need to use one. Create
25-
the directory we will use with `mkdir -p webdriver/webdriverio`. The rest of this guide assumes you are inside the
26-
`webdriver/webdriverio` directory.
23+
the directory we will use with `mkdir e2e-tests`. The rest of this guide assumes you are inside the
24+
`e2e-tests` directory.
2725

2826
## Initializing a WebdriverIO Project
2927

@@ -38,16 +36,17 @@ guide on setting it up from scratch.
3836
"name": "webdriverio",
3937
"version": "1.0.0",
4038
"private": true,
39+
"type": "module",
4140
"scripts": {
4241
"test": "wdio run wdio.conf.js"
4342
},
4443
"dependencies": {
45-
"@wdio/cli": "^7.9.1"
44+
"@wdio/cli": "^9.19.0"
4645
},
4746
"devDependencies": {
48-
"@wdio/local-runner": "^7.9.1",
49-
"@wdio/mocha-framework": "^7.9.1",
50-
"@wdio/spec-reporter": "^7.9.0"
47+
"@wdio/local-runner": "^9.19.0,
48+
"@wdio/mocha-framework": "^9.19.0",
49+
"@wdio/spec-reporter": "^9.19.0"
5150
}
5251
}
5352
```
@@ -80,21 +79,27 @@ config file which controls most aspects of our testing suite.
8079
`wdio.conf.js`:
8180

8281
```javascript
83-
const os = require('os');
84-
const path = require('path');
85-
const { spawn, spawnSync } = require('child_process');
82+
import os from 'os';
83+
import path from 'path';
84+
import { spawn, spawnSync } from 'child_process';
85+
import { fileURLToPath } from 'url';
86+
87+
const __dirname = fileURLToPath(new URL('.', import.meta.url));
8688

8789
// keep track of the `tauri-driver` child process
8890
let tauriDriver;
91+
let exit = false;
8992

90-
exports.config = {
93+
export const config = {
94+
host: '127.0.0.1',
95+
port: 4444,
9196
specs: ['./develop/tests/specs/**/*.js'],
9297
maxInstances: 1,
9398
capabilities: [
9499
{
95100
maxInstances: 1,
96101
'tauri:options': {
97-
application: '../../target/release/hello-tauri-webdriver',
102+
application: '../src-tauri/target/debug/tauri-app',
98103
},
99104
},
100105
],
@@ -106,24 +111,71 @@ exports.config = {
106111
},
107112

108113
// ensure the rust project is built since we expect this binary to exist for the webdriver sessions
109-
onPrepare: () => spawnSync('cargo', ['build', '--release']),
114+
onPrepare: () => {
115+
spawnSync('yarn', ['tauri', 'build', '--debug', '--no-bundle'], {
116+
cwd: path.resolve(__dirname, '..'),
117+
stdio: 'inherit',
118+
shell: true,
119+
});
120+
},
110121

111122
// ensure we are running `tauri-driver` before the session starts so that we can proxy the webdriver requests
112-
beforeSession: () =>
113-
(tauriDriver = spawn(
123+
beforeSession: () => {
124+
tauriDriver = spawn(
114125
path.resolve(os.homedir(), '.cargo', 'bin', 'tauri-driver'),
115126
[],
116127
{ stdio: [null, process.stdout, process.stderr] }
117-
)),
128+
);
129+
130+
tauriDriver.on('error', (error) => {
131+
console.error('tauri-driver error:', error);
132+
process.exit(1);
133+
});
134+
tauriDriver.on('exit', (code) => {
135+
if (!exit) {
136+
console.error('tauri-driver exited with code:', code);
137+
process.exit(1);
138+
}
139+
});
140+
},
118141

119142
// clean up the `tauri-driver` process we spawned at the start of the session
120-
afterSession: () => tauriDriver.kill(),
143+
// note that afterSession might not run if the session fails to start, so we also run the cleanup on shutdown
144+
afterSession: () => {
145+
closeTauriDriver();
146+
},
121147
};
148+
149+
function closeTauriDriver() {
150+
exit = true;
151+
tauriDriver?.kill();
152+
}
153+
154+
function onShutdown(fn) {
155+
const cleanup = () => {
156+
try {
157+
fn();
158+
} finally {
159+
process.exit();
160+
}
161+
};
162+
163+
process.on('exit', cleanup);
164+
process.on('SIGINT', cleanup);
165+
process.on('SIGTERM', cleanup);
166+
process.on('SIGHUP', cleanup);
167+
process.on('SIGBREAK', cleanup);
168+
}
169+
170+
// ensure tauri-driver is closed when our test process exits
171+
onShutdown(() => {
172+
closeTauriDriver();
173+
});
122174
```
123175
124-
If you are interested in the properties on the `exports.config` object, I [suggest reading the documentation][webdriver documentation].
176+
If you are interested in the properties on the `config` object, we [suggest reading the documentation][webdriver documentation].
125177
For non-WDIO specific items, there are comments explaining why we are running commands in `onPrepare`, `beforeSession`,
126-
and `afterSession`. We also have our specs set to `"./develop/tests/specs/**/*.js"`, so let's create a spec now.
178+
and `afterSession`. We also have our specs set to `"./test/specs/**/*.js"`, so let's create a spec now.
127179
128180
## Spec
129181
@@ -217,7 +269,7 @@ of configuration and a single command to run it! Even better, we didn't have to
217269
218270
[prerequisites instructions]: /develop/tests/webdriver/
219271
[webdriverio]: https://webdriver.io/
220-
[finished example project]: https://github.com/chippers/hello_tauri
272+
[finished example project]: https://github.com/tauri-apps/webdriver-example
221273
[mocha]: https://mochajs.org/
222274
[webdriver documentation]: https://webdriver.io/docs/configurationfile
223275
[webdriverio api docs]: https://webdriver.io/docs/api

0 commit comments

Comments
 (0)