Skip to content

Commit

Permalink
feat(e2e-webdriverio): add e2e plugin for WebdriverIO (#5479)
Browse files Browse the repository at this point in the history
  • Loading branch information
christian-bromann committed Jul 31, 2020
1 parent d319007 commit 87e9d42
Show file tree
Hide file tree
Showing 23 changed files with 2,566 additions and 843 deletions.
3 changes: 2 additions & 1 deletion docs/.vuepress/config.js
Expand Up @@ -184,7 +184,8 @@ module.exports = {
'/core-plugins/unit-jest.md',
'/core-plugins/unit-mocha.md',
'/core-plugins/e2e-cypress.md',
'/core-plugins/e2e-nightwatch.md'
'/core-plugins/e2e-nightwatch.md',
'/core-plugins/e2e-webdriverio.md'
]
}],

Expand Down
4 changes: 4 additions & 0 deletions docs/config/README.md
Expand Up @@ -446,3 +446,7 @@ See [@vue/cli-plugin-e2e-cypress](https://github.com/vuejs/vue-cli/tree/dev/pack
### Nightwatch

See [@vue/cli-plugin-e2e-nightwatch](https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-e2e-nightwatch) for more details.

### WebdriverIO

See [@vue/cli-plugin-e2e-webdriverio](https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-e2e-webdriverio) for more details.
1 change: 1 addition & 0 deletions docs/core-plugins/README.md
Expand Up @@ -12,3 +12,4 @@ This section contains documentation for core Vue CLI plugins:
- [Mocha](unit-mocha.md)
- [Cypress](e2e-cypress.md)
- [Nightwatch](e2e-nightwatch.md)
- [WebdriverIO](e2e-webdriverio.md)
64 changes: 64 additions & 0 deletions docs/core-plugins/e2e-webdriverio.md
@@ -0,0 +1,64 @@
# @vue/cli-plugin-e2e-nightwatch

> e2e-webdriverio plugin for vue-cli
## Injected Commands

- **`vue-cli-service test:e2e`**

Run end-to-end tests with [WebdriverIO](https://webdriver.io/).

Options:

```
--url run the tests against given url instead of auto-starting dev server
--headless use chrome or firefox in headless mode
--remote run e2e tests on a cloud provider
```

Additionally, all [WebdriverIO CLI options](https://webdriver.io/docs/clioptions.html) are also supported.
E.g.: `--spec`, `--watch` etc.


## Project Structure

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.

```
tests/e2e/
├── pageobjects/
| └── app.page.js
├── specs/
| ├── app.spec.js
└── .eslintrc.js
```

#### `pageobjects`
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.

#### `specs`
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).

## Installing in an Already Created Project

``` sh
vue add e2e-webdriverio
```

## Running Tests

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.

```sh
$ vue-cli-service test:e2e
```

This will run the tests automatically in parallel on Firefox and Chrome.

**Running a single test**

To run a single test supply the filename path. E.g.:

```sh
$ vue-cli-service test:e2e --spec tests/e2e/specs/test.js
```
2 changes: 2 additions & 0 deletions packages/@vue/cli-plugin-e2e-webdriverio/.npmignore
@@ -0,0 +1,2 @@
__tests__
__mocks__
81 changes: 81 additions & 0 deletions packages/@vue/cli-plugin-e2e-webdriverio/README.md
@@ -0,0 +1,81 @@
# @vue/cli-plugin-e2e-webdriverio

> e2e-webdriverio plugin for vue-cli
## Injected Commands

- **`vue-cli-service test:e2e`**

Run end-to-end tests with [WebdriverIO](https://webdriver.io/).

Options:

```
--remote Run tests remotely on SauceLabs
All WebdriverIO CLI options are also supported.
```

Additionally, all [WebdriverIO CLI options](https://webdriver.io/docs/clioptions.html) are also supported.
E.g.: `--baseUrl`, `--bail` etc.


## Project Structure

The following structure will be generated when installing this plugin:

```
tests/e2e/
├── pageobjects/
| └── app.js
├── specs/
| ├── app.spec.js
└── globals.js
```

In addition to that there will be 3 configuration files generated:

- `wdio.shared.conf.js`: a shared configuration with all options defined for all environments
- `wdio.local.conf.js`: a local configuration for local testing
- `wdio.sauce.conf.js`: a remote configuration for testing on a cloud provider like [Sauce Labs](https://saucelabs.com/)

The directories contain:

#### `pageobjects`
Contains an example for an page object. Read more on using [PageObjects](https://webdriver.io/docs/pageobjects.html) with WebdriverIO.

#### `specs`
Your e2e tests.

## Installing in an Already Created Project

``` sh
vue add e2e-webdriverio
```

For users with older CLI versions you may need to run `vue add @vue/e2e-webdriverio`.

## Running Tests

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.

```sh
$ vue-cli-service test:e2e
```

**Running a single test**

To run a single test supply the filename path. E.g.:

```sh
$ vue-cli-service test:e2e --spec tests/e2e/specs/test.js
```

**Skip Dev server auto-start**

If the development server is already running and you want to skip starting it automatically, pass the `--url` argument:

```sh
$ vue-cli-service test:e2e --baseUrl=http://localhost:8080/
```
@@ -0,0 +1,41 @@
jest.setTimeout(process.env.APPVEYOR ? 120000 : 60000)

const create = require('@vue/cli-test-utils/createTestProject')

test('should work', async () => {
const project = await create('e2e-webdriverio', {
plugins: {
'@vue/cli-plugin-babel': {},
'@vue/cli-plugin-e2e-webdriverio': {},
'@vue/cli-plugin-eslint': {
config: 'airbnb',
lintOn: 'save'
}
}
})

if (!process.env.CI) {
await project.run(`vue-cli-service test:e2e`)
} else if (!process.env.APPVEYOR) {
await project.run(`vue-cli-service test:e2e --headless`)
}
})

test('should work with TS', async () => {
const project = await create('e2e-webdriverio-ts', {
plugins: {
'@vue/cli-plugin-typescript': {
'classComponent': true,
'tsLint': true,
'lintOn': ['save']
},
'@vue/cli-plugin-e2e-webdriverio': {}
}
})

if (!process.env.CI) {
await project.run(`vue-cli-service test:e2e`)
} else if (!process.env.APPVEYOR) {
await project.run(`vue-cli-service test:e2e --headless`)
}
})
35 changes: 35 additions & 0 deletions packages/@vue/cli-plugin-e2e-webdriverio/generator/index.js
@@ -0,0 +1,35 @@
const { installedBrowsers } = require('@vue/cli-shared-utils')

module.exports = (api, { webdrivers }) => {
api.render('./template', {
hasTS: api.hasPlugin('typescript'),
hasESLint: api.hasPlugin('eslint')
})

const devDependencies = {}

// Use devDependencies to store latest version number so as to automate update
const pluginDeps = require('../package.json').devDependencies

if (webdrivers && webdrivers.includes('firefox')) {
devDependencies.geckodriver = pluginDeps.geckodriver
devDependencies['wdio-geckodriver-service'] = pluginDeps['wdio-geckodriver-service']
}
if (webdrivers && webdrivers.includes('chrome')) {
// chromedriver major version bumps every 6 weeks following Chrome
// so there may be a mismatch between
// user's installed browser version and the default provided version
// fallback to the devDependencies version in case detection fails
devDependencies['wdio-chromedriver-service'] = pluginDeps['wdio-chromedriver-service']
devDependencies.chromedriver = installedBrowsers.chrome
? installedBrowsers.chrome.match(/^(\d+)\./)[1]
: pluginDeps.chromedriver
}

api.extendPackage({
scripts: {
'test:e2e': 'vue-cli-service test:e2e'
},
devDependencies
})
}
Empty file.
@@ -0,0 +1,12 @@
<%_ if (hasESLint) { _%>
module.exports = {
plugins: ['wdio'],
extends: 'plugin:wdio/recommended',
env: {
mocha: true
},
rules: {
strict: 'off'
}
}
<%_ } _%>
@@ -0,0 +1,16 @@
class App {
/**
* elements
*/
get heading () { return $('h1') }

/**
* methods
*/
open (path = '/') {
browser.url(path)
}
}

<%- hasTS ? 'export default new App()' : 'module.exports = new App()' %>

@@ -0,0 +1,8 @@
<%- hasTS ? 'import App from \'../pageobjects/app.page\'' : 'const App = require(\'../pageobjects/app.page\')' %>

describe('Vue.js app', () => {
it('should open and render', () => {
App.open()
expect(App.heading).toHaveText('Welcome to Your Vue.js <%- hasTS ? '+ TypeScript ' : '' %>App')
})
})
@@ -0,0 +1,25 @@
<%- hasTS ? 'const { config } = require(\'./wdio.shared.conf.ts\')' : 'const { config } = require(\'./wdio.shared.conf\')' %>

exports.config = {
/**
* base config
*/
...config,
/**
* config for local testing
*/
maxInstances: 1,
services: ['chromedriver', 'geckodriver'],
capabilities: [{
browserName: 'chrome',
acceptInsecureCerts: true,
'goog:chromeOptions': {
args: process.argv.includes('--headless')
? ['--headless', '--disable-gpu']
: []
}
}, {
browserName: 'firefox',
acceptInsecureCerts: true
}]
}
@@ -0,0 +1,41 @@
<%- hasTS ? 'import { config } from \'./wdio.shared.conf.ts\'' : 'const { config } = require(\'./wdio.shared.conf\')' %>

const BUILD_ID = Math.ceil(Date.now() / 1000)

exports.config = {
/**
* base config
*/
...config,
/**
* config for testing on Sauce Labs
*/
user: process.env.SAUCE_USERNAME,
key: process.env.SAUCE_ACCESS_KEY,
region: 'us',
headless: process.argv.includes('--headless'),

services: [
['sauce', {
sauceConnect: true,
tunnelIdentifier: 'Vue.js Integration tests'
}]
],

maxInstances: 10,
capabilities: [{
browserName: 'firefox',
browserVersion: 'latest',
platformName: 'Windows 10',
'sauce:options': {
build: `Build ${BUILD_ID}`
}
}, {
browserName: 'chrome',
browserVersion: 'latest',
platformName: 'Windows 10',
'sauce:options': {
build: `Build ${BUILD_ID}`
}
}]
}

0 comments on commit 87e9d42

Please sign in to comment.