Skip to content

Commit 87e9d42

Browse files
feat(e2e-webdriverio): add e2e plugin for WebdriverIO (#5479)
1 parent d319007 commit 87e9d42

File tree

23 files changed

+2566
-843
lines changed

23 files changed

+2566
-843
lines changed

docs/.vuepress/config.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,8 @@ module.exports = {
184184
'/core-plugins/unit-jest.md',
185185
'/core-plugins/unit-mocha.md',
186186
'/core-plugins/e2e-cypress.md',
187-
'/core-plugins/e2e-nightwatch.md'
187+
'/core-plugins/e2e-nightwatch.md',
188+
'/core-plugins/e2e-webdriverio.md'
188189
]
189190
}],
190191

docs/config/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -446,3 +446,7 @@ See [@vue/cli-plugin-e2e-cypress](https://github.com/vuejs/vue-cli/tree/dev/pack
446446
### Nightwatch
447447

448448
See [@vue/cli-plugin-e2e-nightwatch](https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-e2e-nightwatch) for more details.
449+
450+
### WebdriverIO
451+
452+
See [@vue/cli-plugin-e2e-webdriverio](https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-e2e-webdriverio) for more details.

docs/core-plugins/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ This section contains documentation for core Vue CLI plugins:
1212
- [Mocha](unit-mocha.md)
1313
- [Cypress](e2e-cypress.md)
1414
- [Nightwatch](e2e-nightwatch.md)
15+
- [WebdriverIO](e2e-webdriverio.md)

docs/core-plugins/e2e-webdriverio.md

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# @vue/cli-plugin-e2e-nightwatch
2+
3+
> e2e-webdriverio plugin for vue-cli
4+
5+
## Injected Commands
6+
7+
- **`vue-cli-service test:e2e`**
8+
9+
Run end-to-end tests with [WebdriverIO](https://webdriver.io/).
10+
11+
Options:
12+
13+
```
14+
--url run the tests against given url instead of auto-starting dev server
15+
--headless use chrome or firefox in headless mode
16+
--remote run e2e tests on a cloud provider
17+
```
18+
19+
Additionally, all [WebdriverIO CLI options](https://webdriver.io/docs/clioptions.html) are also supported.
20+
E.g.: `--spec`, `--watch` etc.
21+
22+
23+
## Project Structure
24+
25+
The following structure will be generated when installing this plugin. It includes a spec file a page object definition for the Vue.js app as example.
26+
27+
```
28+
tests/e2e/
29+
├── pageobjects/
30+
| └── app.page.js
31+
├── specs/
32+
| ├── app.spec.js
33+
└── .eslintrc.js
34+
```
35+
36+
#### `pageobjects`
37+
Working with page objects is a popular methodology in end-to-end UI testing. See [working with page objects](https://webdriver.io/docs/pageobjects.html) section for details.
38+
39+
#### `specs`
40+
The main location where tests are located. You can specify specific tests or define suites to run various subsets of these tests. [More info](https://webdriver.io/docs/organizingsuites.html).
41+
42+
## Installing in an Already Created Project
43+
44+
``` sh
45+
vue add e2e-webdriverio
46+
```
47+
48+
## Running Tests
49+
50+
By default, all tests inside the `specs` folder will be run using Chrome. If you'd like to run end-to-end tests against Chrome (or Firefox) in headless mode, simply pass the `--headless` argument.
51+
52+
```sh
53+
$ vue-cli-service test:e2e
54+
```
55+
56+
This will run the tests automatically in parallel on Firefox and Chrome.
57+
58+
**Running a single test**
59+
60+
To run a single test supply the filename path. E.g.:
61+
62+
```sh
63+
$ vue-cli-service test:e2e --spec tests/e2e/specs/test.js
64+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
__tests__
2+
__mocks__
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# @vue/cli-plugin-e2e-webdriverio
2+
3+
> e2e-webdriverio plugin for vue-cli
4+
5+
## Injected Commands
6+
7+
- **`vue-cli-service test:e2e`**
8+
9+
Run end-to-end tests with [WebdriverIO](https://webdriver.io/).
10+
11+
Options:
12+
13+
```
14+
--remote Run tests remotely on SauceLabs
15+
16+
All WebdriverIO CLI options are also supported.
17+
18+
```
19+
20+
Additionally, all [WebdriverIO CLI options](https://webdriver.io/docs/clioptions.html) are also supported.
21+
E.g.: `--baseUrl`, `--bail` etc.
22+
23+
24+
## Project Structure
25+
26+
The following structure will be generated when installing this plugin:
27+
28+
```
29+
tests/e2e/
30+
├── pageobjects/
31+
| └── app.js
32+
├── specs/
33+
| ├── app.spec.js
34+
└── globals.js
35+
```
36+
37+
In addition to that there will be 3 configuration files generated:
38+
39+
- `wdio.shared.conf.js`: a shared configuration with all options defined for all environments
40+
- `wdio.local.conf.js`: a local configuration for local testing
41+
- `wdio.sauce.conf.js`: a remote configuration for testing on a cloud provider like [Sauce Labs](https://saucelabs.com/)
42+
43+
The directories contain:
44+
45+
#### `pageobjects`
46+
Contains an example for an page object. Read more on using [PageObjects](https://webdriver.io/docs/pageobjects.html) with WebdriverIO.
47+
48+
#### `specs`
49+
Your e2e tests.
50+
51+
## Installing in an Already Created Project
52+
53+
``` sh
54+
vue add e2e-webdriverio
55+
```
56+
57+
For users with older CLI versions you may need to run `vue add @vue/e2e-webdriverio`.
58+
59+
## Running Tests
60+
61+
By default, all tests inside the `specs` folder will be run using Chrome. If you'd like to run end-to-end tests against Chrome (or Firefox) in headless mode, simply pass the `--headless` argument. Tests will be automatically run in parallel when executed in the cloud.
62+
63+
```sh
64+
$ vue-cli-service test:e2e
65+
```
66+
67+
**Running a single test**
68+
69+
To run a single test supply the filename path. E.g.:
70+
71+
```sh
72+
$ vue-cli-service test:e2e --spec tests/e2e/specs/test.js
73+
```
74+
75+
**Skip Dev server auto-start**
76+
77+
If the development server is already running and you want to skip starting it automatically, pass the `--url` argument:
78+
79+
```sh
80+
$ vue-cli-service test:e2e --baseUrl=http://localhost:8080/
81+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
jest.setTimeout(process.env.APPVEYOR ? 120000 : 60000)
2+
3+
const create = require('@vue/cli-test-utils/createTestProject')
4+
5+
test('should work', async () => {
6+
const project = await create('e2e-webdriverio', {
7+
plugins: {
8+
'@vue/cli-plugin-babel': {},
9+
'@vue/cli-plugin-e2e-webdriverio': {},
10+
'@vue/cli-plugin-eslint': {
11+
config: 'airbnb',
12+
lintOn: 'save'
13+
}
14+
}
15+
})
16+
17+
if (!process.env.CI) {
18+
await project.run(`vue-cli-service test:e2e`)
19+
} else if (!process.env.APPVEYOR) {
20+
await project.run(`vue-cli-service test:e2e --headless`)
21+
}
22+
})
23+
24+
test('should work with TS', async () => {
25+
const project = await create('e2e-webdriverio-ts', {
26+
plugins: {
27+
'@vue/cli-plugin-typescript': {
28+
'classComponent': true,
29+
'tsLint': true,
30+
'lintOn': ['save']
31+
},
32+
'@vue/cli-plugin-e2e-webdriverio': {}
33+
}
34+
})
35+
36+
if (!process.env.CI) {
37+
await project.run(`vue-cli-service test:e2e`)
38+
} else if (!process.env.APPVEYOR) {
39+
await project.run(`vue-cli-service test:e2e --headless`)
40+
}
41+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
const { installedBrowsers } = require('@vue/cli-shared-utils')
2+
3+
module.exports = (api, { webdrivers }) => {
4+
api.render('./template', {
5+
hasTS: api.hasPlugin('typescript'),
6+
hasESLint: api.hasPlugin('eslint')
7+
})
8+
9+
const devDependencies = {}
10+
11+
// Use devDependencies to store latest version number so as to automate update
12+
const pluginDeps = require('../package.json').devDependencies
13+
14+
if (webdrivers && webdrivers.includes('firefox')) {
15+
devDependencies.geckodriver = pluginDeps.geckodriver
16+
devDependencies['wdio-geckodriver-service'] = pluginDeps['wdio-geckodriver-service']
17+
}
18+
if (webdrivers && webdrivers.includes('chrome')) {
19+
// chromedriver major version bumps every 6 weeks following Chrome
20+
// so there may be a mismatch between
21+
// user's installed browser version and the default provided version
22+
// fallback to the devDependencies version in case detection fails
23+
devDependencies['wdio-chromedriver-service'] = pluginDeps['wdio-chromedriver-service']
24+
devDependencies.chromedriver = installedBrowsers.chrome
25+
? installedBrowsers.chrome.match(/^(\d+)\./)[1]
26+
: pluginDeps.chromedriver
27+
}
28+
29+
api.extendPackage({
30+
scripts: {
31+
'test:e2e': 'vue-cli-service test:e2e'
32+
},
33+
devDependencies
34+
})
35+
}

packages/@vue/cli-plugin-e2e-webdriverio/generator/template/logs/.gitkeep

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<%_ if (hasESLint) { _%>
2+
module.exports = {
3+
plugins: ['wdio'],
4+
extends: 'plugin:wdio/recommended',
5+
env: {
6+
mocha: true
7+
},
8+
rules: {
9+
strict: 'off'
10+
}
11+
}
12+
<%_ } _%>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
class App {
2+
/**
3+
* elements
4+
*/
5+
get heading () { return $('h1') }
6+
7+
/**
8+
* methods
9+
*/
10+
open (path = '/') {
11+
browser.url(path)
12+
}
13+
}
14+
15+
<%- hasTS ? 'export default new App()' : 'module.exports = new App()' %>
16+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<%- hasTS ? 'import App from \'../pageobjects/app.page\'' : 'const App = require(\'../pageobjects/app.page\')' %>
2+
3+
describe('Vue.js app', () => {
4+
it('should open and render', () => {
5+
App.open()
6+
expect(App.heading).toHaveText('Welcome to Your Vue.js <%- hasTS ? '+ TypeScript ' : '' %>App')
7+
})
8+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<%- hasTS ? 'const { config } = require(\'./wdio.shared.conf.ts\')' : 'const { config } = require(\'./wdio.shared.conf\')' %>
2+
3+
exports.config = {
4+
/**
5+
* base config
6+
*/
7+
...config,
8+
/**
9+
* config for local testing
10+
*/
11+
maxInstances: 1,
12+
services: ['chromedriver', 'geckodriver'],
13+
capabilities: [{
14+
browserName: 'chrome',
15+
acceptInsecureCerts: true,
16+
'goog:chromeOptions': {
17+
args: process.argv.includes('--headless')
18+
? ['--headless', '--disable-gpu']
19+
: []
20+
}
21+
}, {
22+
browserName: 'firefox',
23+
acceptInsecureCerts: true
24+
}]
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<%- hasTS ? 'import { config } from \'./wdio.shared.conf.ts\'' : 'const { config } = require(\'./wdio.shared.conf\')' %>
2+
3+
const BUILD_ID = Math.ceil(Date.now() / 1000)
4+
5+
exports.config = {
6+
/**
7+
* base config
8+
*/
9+
...config,
10+
/**
11+
* config for testing on Sauce Labs
12+
*/
13+
user: process.env.SAUCE_USERNAME,
14+
key: process.env.SAUCE_ACCESS_KEY,
15+
region: 'us',
16+
headless: process.argv.includes('--headless'),
17+
18+
services: [
19+
['sauce', {
20+
sauceConnect: true,
21+
tunnelIdentifier: 'Vue.js Integration tests'
22+
}]
23+
],
24+
25+
maxInstances: 10,
26+
capabilities: [{
27+
browserName: 'firefox',
28+
browserVersion: 'latest',
29+
platformName: 'Windows 10',
30+
'sauce:options': {
31+
build: `Build ${BUILD_ID}`
32+
}
33+
}, {
34+
browserName: 'chrome',
35+
browserVersion: 'latest',
36+
platformName: 'Windows 10',
37+
'sauce:options': {
38+
build: `Build ${BUILD_ID}`
39+
}
40+
}]
41+
}

0 commit comments

Comments
 (0)