├── .babelrc ├── .circleci └── config.yml ├── .gitignore ├── LICENSE ├── README.md ├── example.spec.js ├── package-lock.json └── package.json /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["env"] 3 | } 4 | -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | # Javascript Node CircleCI 2.0 configuration file 2 | # 3 | # Check https://circleci.com/docs/2.0/language-javascript/ for more details 4 | # 5 | version: 2 6 | jobs: 7 | build: 8 | docker: 9 | - image: circleci/node:latest-browsers 10 | working_directory: ~/repo 11 | steps: 12 | - checkout 13 | - restore_cache: 14 | keys: 15 | - v1-dependencies-{{ checksum "package.json" }} 16 | # fallback to using the latest cache if no exact match is found 17 | - v1-dependencies- 18 | - run: npm install 19 | - save_cache: 20 | paths: 21 | - node_modules 22 | key: v1-dependencies-{{ checksum "package.json" }} 23 | - run: HEADLESS=1 npm test 24 | - run: BROWSER_NAME=chrome npm test 25 | - run: BROWSER_NAME=firefox npm test 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Zenc Labs Pty Ltd 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WebdriverIO with Jest 2 | 3 | [![CircleCI](https://circleci.com/gh/zenclabs/webdriverio-jest.svg?style=svg)](https://circleci.com/gh/zenclabs/webdriverio-jest) 4 | 5 | This is the simplest possible example of a WebdriverIO test written with the Jest framework. 6 | 7 | Because WebdriverIO doesn't support Jest as a first-class citizen, this test suite leverages the 8 | WebdriverIO remote API. This means that we need to do a few things ourselves, such as starting up 9 | Selenium server as well as the browser. It also means that we must use `async`/`await` statements. 10 | 11 | ## How to use it 12 | 13 | ```sh 14 | npm install 15 | npm test 16 | ``` 17 | 18 | ## Picking a different browser 19 | 20 | The browser is chosen based on the `BROWSER_NAME` environment variable, defaulting to `chrome`. 21 | 22 | Examples: 23 | ``` 24 | BROWSER_NAME=chrome npm test 25 | BROWSER_NAME=safari npm test 26 | BROWSER_NAME=firefox npm test 27 | BROWSER_NAME="internet explorer" npm test 28 | BROWSER_NAME=MicrosoftEdge npm test 29 | ``` 30 | 31 | # Running with Chrome headless 32 | 33 | Simply set the `HEADLESS` environment variable to `1`: 34 | ``` 35 | HEADLESS=1 npm test 36 | ``` 37 | 38 | # TypeScript 39 | 40 | Check out the [typescript branch](https://github.com/zenclabs/webdriverio-jest/tree/typescript) 41 | for the equivalent test written in TypeScript. 42 | -------------------------------------------------------------------------------- /example.spec.js: -------------------------------------------------------------------------------- 1 | import * as selenium from "selenium-standalone"; 2 | import * as webdriverio from "webdriverio"; 3 | 4 | // We expect the test to take a while, by nature. 5 | jest.setTimeout(60000); 6 | 7 | let seleniumProcess; 8 | let browser; 9 | 10 | beforeAll(async () => { 11 | // Install Selenium if required. 12 | await new Promise(resolve => { 13 | selenium.install(resolve); 14 | }); 15 | // Start Selenium server. 16 | seleniumProcess = await new Promise((resolve, reject) => 17 | selenium.start((error, childProcess) => { 18 | if (error) { 19 | reject(error); 20 | } else { 21 | resolve(childProcess); 22 | } 23 | }) 24 | ); 25 | }); 26 | 27 | afterAll(async () => { 28 | // Kill Selenium server. 29 | await seleniumProcess.kill(); 30 | }); 31 | 32 | beforeEach(async () => { 33 | // Configure the browser via BROWSER_NAME environment variable. 34 | // Setting HEADLESS to 1 will run the browser in headless mode (only available on Chrome). 35 | browser = webdriverio.remote({ 36 | desiredCapabilities: { 37 | browserName: process.env.BROWSER_NAME || "chrome", 38 | chromeOptions: { 39 | args: 40 | process.env.HEADLESS === "1" 41 | ? ["--headless", "--disable-gpu", "--window-size=1280,800"] 42 | : [] 43 | } 44 | }, 45 | // Wait for at most 10 seconds for elements to appear. 46 | waitforTimeout: 10000 47 | }); 48 | await browser.init(); 49 | }); 50 | 51 | afterEach(async () => { 52 | await browser.end(); 53 | }); 54 | 55 | const GOOGLE_SEARCH_INPUT_SELECTOR = `input[name="q"]`; 56 | const GOOGLE_SEARCH_BUTTON_SELECTOR = `input[value="Google Search"]`; 57 | const GITHUB_ISSUE_TITLE_SELECTOR = "*=Issue #2052"; 58 | const GITHUB_COMMENT_SELECTOR = 59 | "p*=Here is a minimal example of a WebdriverIO test written with the Jest framework:"; 60 | 61 | describe("Google", () => { 62 | it("can search on Google", async () => { 63 | // Load Google Search. 64 | await browser.url("https://www.google.com"); 65 | // Wait until the search field is visible. 66 | await browser.waitForVisible(GOOGLE_SEARCH_INPUT_SELECTOR); 67 | // Start typing. No need to click on the search field, as it should be automatically focused. 68 | await browser.keys("WebdriverIO Jest"); 69 | // Click search. 70 | await browser.click(GOOGLE_SEARCH_BUTTON_SELECTOR); 71 | // Wait until we find the relevant GitHub issue. 72 | await browser.waitForVisible(GITHUB_ISSUE_TITLE_SELECTOR); 73 | // Click through to GitHub. 74 | await browser.click(GITHUB_ISSUE_TITLE_SELECTOR); 75 | // Find the relevant answer. 76 | await browser.waitForExist(GITHUB_COMMENT_SELECTOR); 77 | // Scroll to it. 78 | await browser.scroll(GITHUB_COMMENT_SELECTOR); 79 | // Ensure it's now visible. 80 | await browser.waitForVisible(GITHUB_COMMENT_SELECTOR); 81 | }); 82 | }); 83 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "test": "jest" 4 | }, 5 | "dependencies": { 6 | "@types/jest": "^23.3.1", 7 | "@types/selenium-standalone": "^6.15.0", 8 | "@types/webdriverio": "^4.10.3", 9 | "babel-preset-env": "^1.7.0", 10 | "jest": "^23.5.0", 11 | "selenium-standalone": "^6.15.2", 12 | "webdriverio": "^4.13.2" 13 | } 14 | } 15 | --------------------------------------------------------------------------------