From 921a30403bfd051cb8f8484e05950a5fae8e70e1 Mon Sep 17 00:00:00 2001 From: Alex Man Date: Mon, 11 Apr 2022 12:42:08 -0700 Subject: [PATCH] WDIO7 TypeScript (applitools-wdio-service included) --- WDIO7/UFG/README.md | 11 + WDIO7/UFG/package.json | 34 +++ WDIO7/UFG/test/example-classic.ts | 72 ++++++ WDIO7/UFG/test/example-ufg.ts | 82 +++++++ WDIO7/UFG/test/specs/example_service.ts | 18 ++ WDIO7/UFG/tsconfig.json | 12 + WDIO7/UFG/wdio.conf.ts | 295 ++++++++++++++++++++++++ 7 files changed, 524 insertions(+) create mode 100644 WDIO7/UFG/package.json create mode 100644 WDIO7/UFG/test/example-classic.ts create mode 100644 WDIO7/UFG/test/example-ufg.ts create mode 100644 WDIO7/UFG/test/specs/example_service.ts create mode 100644 WDIO7/UFG/tsconfig.json create mode 100644 WDIO7/UFG/wdio.conf.ts diff --git a/WDIO7/UFG/README.md b/WDIO7/UFG/README.md index e69de29..7d847bb 100644 --- a/WDIO7/UFG/README.md +++ b/WDIO7/UFG/README.md @@ -0,0 +1,11 @@ +# Applitools Tutorial - WebdriverIO 7 + +Get started with Applitools visual testing with this example of using the ClassicRunner with the Applitools WebdriverIO 7 SDK and TypeScript. + + +## More Information + +Learn more about Applitools [Eyes](https://info.applitools.com/ucY77) and the [Ultrafast Test Cloud](https://info.applitools.com/ucY78) at [applitools.com](https://info.applitools.com/ucY76). + +More about the Eyes WebdriverIO SDK: +* https://www.npmjs.com/package/@applitools/eyes-webdriverio diff --git a/WDIO7/UFG/package.json b/WDIO7/UFG/package.json new file mode 100644 index 0000000..ee442f4 --- /dev/null +++ b/WDIO7/UFG/package.json @@ -0,0 +1,34 @@ +{ + "name": "tutorial-webdriverio7-typescript-basic", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "mocha --require ts-node/register ./test/example-ufg.ts -t 300000", + "test:service": "wdio ./wdio.conf.ts" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/applitools/tutorial-webdriverio5-basic.git" + }, + "author": "Applitools Team (http://www.applitools.com/)", + "license": "ISC", + "bugs": { + "url": "https://github.com/applitools/tutorial-webdriverio5-basic/issues" + }, + "homepage": "https://github.com/applitools/tutorial-webdriverio5-basic#readme", + "devDependencies": { + "@applitools/eyes-webdriverio": "^5.34.12", + "@applitools/eyes-webdriverio5-service": "1.13.6", + "@types/node": "^15.3.0", + "@wdio/local-runner": "^7.19.4", + "@wdio/mocha-framework": "^7.19.3", + "@wdio/spec-reporter": "^7.19.1", + "chromedriver": "^100.0.0", + "mocha": "^8.4.0", + "ts-node": "^9.1.1", + "typescript": "^4.6.3", + "wdio-chromedriver-service": "^7.3.2", + "webdriverio": "^7.6.0" + } +} diff --git a/WDIO7/UFG/test/example-classic.ts b/WDIO7/UFG/test/example-classic.ts new file mode 100644 index 0000000..3a2a83a --- /dev/null +++ b/WDIO7/UFG/test/example-classic.ts @@ -0,0 +1,72 @@ +'use strict'; + +import { ClassicRunner, Eyes } from '@applitools/eyes-webdriverio'; +import { remote, RemoteOptions } from 'webdriverio'; + +let browser: WebdriverIO.Browser; +let eyes: Eyes; + +describe('wdio7', function () { + beforeEach(async () => { + // Use chrome browser + + browser = await remote({ + capabilities: { + browserName: 'chrome', + 'goog:chromeOptions': { + headless: true, + }, + }, + logLevel: 'silent', + } as RemoteOptions); + + // Initialize the Runner for your test. + const runner = new ClassicRunner(); + + // Initialize the eyes SDK with configuration + eyes = new Eyes(runner, { + batch: { + name: 'Demo Batch - WDIO 7 - Ultrafast TS', + }, + }); + }); + + it('Classic Runner Test', async () => { + // Start the test by setting AUT's name, test name and viewport size (width X height) + await eyes.open(browser, { + appName: 'Demo App - WDIO 7 - Ultrafast TS', + testName: 'Smoke Test - WDIO 7 - Ultrafast TS', + viewportSize: { + width: 800, + height: 600, + }, + }); + + // Navigate the browser to the "ACME" demo app. + await browser.url('https://demo.applitools.com'); + + // To see visual bugs after the first run, use the commented line below instead. + // await driver.url("https://demo.applitools.com/index_v2.html"); + + // Visual checkpoint #1. + await eyes.check({ name: 'Login Window', fully: true }); + + // Click the "Log in" button. + const loginButton = await browser.$('#log-in'); + await loginButton.click(); + + // Visual checkpoint #2. + await eyes.check({ name: 'App Window', fully: true }); + + // End the test + await eyes.close(true); + }); + + afterEach(async () => { + // Close the browser + await browser.deleteSession(); + + // If the test was aborted before eyes.close was called, ends the test as aborted. + await eyes.abort(); + }); +}); diff --git a/WDIO7/UFG/test/example-ufg.ts b/WDIO7/UFG/test/example-ufg.ts new file mode 100644 index 0000000..4685008 --- /dev/null +++ b/WDIO7/UFG/test/example-ufg.ts @@ -0,0 +1,82 @@ +'use strict'; + +import { ClassicRunner, Eyes, Configuration, BrowserType, BatchInfo } from '@applitools/eyes-webdriverio'; +import { remote, RemoteOptions } from 'webdriverio'; + +let browser: WebdriverIO.Browser; +let eyes: Eyes; + +describe('wdio7', function () { + beforeEach(async () => { + // Use chrome browser + + browser = await remote({ + capabilities: { + browserName: 'chrome', + 'goog:chromeOptions': { + headless: true, + }, + }, + logLevel: 'silent', + } as RemoteOptions); + + // Initialize the Runner for your test. + const runner = new ClassicRunner(); + + // Initialize the eyes SDK with configuration + eyes = new Eyes(runner); + + // Initialize the eyes configuration + const configuration = new Configuration(); + + // create a new batch info instance and set it to the configuration + configuration.setBatch(new BatchInfo('Demo Batch - WDIO 5 - Ultrafast')) + + // Add browsers with different viewports + configuration.addBrowser(1200, 800, BrowserType.CHROME); + configuration.addBrowser(1200, 800, BrowserType.FIREFOX); + configuration.addBrowser(1200, 800, BrowserType.EDGE_CHROMIUM); + configuration.addBrowser(1200, 800, BrowserType.SAFARI); + + eyes.setConfiguration(configuration); + }); + + it('Classic Runner Test', async () => { + // Start the test by setting AUT's name, test name and viewport size (width X height) + await eyes.open(browser, { + appName: 'Demo App - WDIO 7 - Ultrafast TS', + testName: 'Smoke Test - WDIO 7 - Ultrafast TS', + viewportSize: { + width: 800, + height: 600, + }, + }); + + // Navigate the browser to the "ACME" demo app. + await browser.url('https://demo.applitools.com'); + + // To see visual bugs after the first run, use the commented line below instead. + // await driver.url("https://demo.applitools.com/index_v2.html"); + + // Visual checkpoint #1. + await eyes.check({ name: 'Login Window', fully: true }); + + // Click the "Log in" button. + const loginButton = await browser.$('#log-in'); + await loginButton.click(); + + // Visual checkpoint #2. + await eyes.check({ name: 'App Window', fully: true }); + + // End the test + await eyes.close(true); + }); + + afterEach(async () => { + // Close the browser + await browser.deleteSession(); + + // If the test was aborted before eyes.close was called, ends the test as aborted. + await eyes.abort(); + }); +}); diff --git a/WDIO7/UFG/test/specs/example_service.ts b/WDIO7/UFG/test/specs/example_service.ts new file mode 100644 index 0000000..7d4806c --- /dev/null +++ b/WDIO7/UFG/test/specs/example_service.ts @@ -0,0 +1,18 @@ +describe('My Login application', () => { + it('should login with valid credentials', async () => { + await browser.url(`https://the-internet.herokuapp.com/login`); + + await $('#username').setValue('tomsmith'); + await $('#password').setValue('SuperSecretPassword!'); + await $('button[type="submit"]').click(); + + await browser.eyesCheck('Typescript test'); + + await expect($('#flash')).toBeExisting(); + await expect($('#flash')).toHaveTextContaining( + 'You logged into a secure area!'); + + await browser.eyesGetTestResults(); + }); +}); + diff --git a/WDIO7/UFG/tsconfig.json b/WDIO7/UFG/tsconfig.json new file mode 100644 index 0000000..780ec56 --- /dev/null +++ b/WDIO7/UFG/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "sourceMap": false, + "target": "es2019", + "module": "commonjs", + "removeComments": true, + "noImplicitAny": true, + "strictPropertyInitialization": true, + "strictNullChecks": true, + "types": ["node", "webdriverio/async", "@wdio/mocha-framework", "@applitools/eyes-webdriverio/types/v7"] + } +} diff --git a/WDIO7/UFG/wdio.conf.ts b/WDIO7/UFG/wdio.conf.ts new file mode 100644 index 0000000..2d3e420 --- /dev/null +++ b/WDIO7/UFG/wdio.conf.ts @@ -0,0 +1,295 @@ +const { EyesService } = require('@applitools/eyes-webdriverio5-service'); + +export const config: WebdriverIO.Config = { + // + // ==================== + // Runner Configuration + // ==================== + // + // + // ================== + // Specify Test Files + // ================== + // Define which test specs should run. The pattern is relative to the directory + // from which `wdio` was called. + // + // The specs are defined as an array of spec files (optionally using wildcards + // that will be expanded). The test for each spec file will be run in a separate + // worker process. In order to have a group of spec files run in the same worker + // process simply enclose them in an array within the specs array. + // + // If you are calling `wdio` from an NPM script (see https://docs.npmjs.com/cli/run-script), + // then the current working directory is where your `package.json` resides, so `wdio` + // will be called from there. + // + specs: [ + './test/specs/**/*.ts' + ], + // Patterns to exclude. + exclude: [ + // 'path/to/excluded/files' + ], + // + // ============ + // Capabilities + // ============ + // Define your capabilities here. WebdriverIO can run multiple capabilities at the same + // time. Depending on the number of capabilities, WebdriverIO launches several test + // sessions. Within your capabilities you can overwrite the spec and exclude options in + // order to group specific specs to a specific capability. + // + // First, you can define how many instances should be started at the same time. Let's + // say you have 3 different capabilities (Chrome, Firefox, and Safari) and you have + // set maxInstances to 1; wdio will spawn 3 processes. Therefore, if you have 10 spec + // files and you set maxInstances to 10, all spec files will get tested at the same time + // and 30 processes will get spawned. The property handles how many capabilities + // from the same test should run tests. + // + maxInstances: 10, + // + // If you have trouble getting all important capabilities together, check out the + // Sauce Labs platform configurator - a great tool to configure your capabilities: + // https://docs.saucelabs.com/reference/platforms-configurator + // + capabilities: [{ + + // maxInstances can get overwritten per capability. So if you have an in-house Selenium + // grid with only 5 firefox instances available you can make sure that not more than + // 5 instances get started at a time. + maxInstances: 5, + // + browserName: 'chrome', + acceptInsecureCerts: true + // If outputDir is provided WebdriverIO can capture driver session logs + // it is possible to configure which logTypes to include/exclude. + // excludeDriverLogs: ['*'], // pass '*' to exclude all driver session logs + // excludeDriverLogs: ['bugreport', 'server'], + }], + // + // =================== + // Test Configurations + // =================== + // Define all options that are relevant for the WebdriverIO instance here + // + // Level of logging verbosity: trace | debug | info | warn | error | silent + logLevel: 'info', + // + // Set specific log levels per logger + // loggers: + // - webdriver, webdriverio + // - @wdio/browserstack-service, @wdio/devtools-service, @wdio/sauce-service + // - @wdio/mocha-framework, @wdio/jasmine-framework + // - @wdio/local-runner + // - @wdio/sumologic-reporter + // - @wdio/cli, @wdio/config, @wdio/utils + // Level of logging verbosity: trace | debug | info | warn | error | silent + // logLevels: { + // webdriver: 'info', + // '@wdio/appium-service': 'info' + // }, + // + // If you only want to run your tests until a specific amount of tests have failed use + // bail (default is 0 - don't bail, run all tests). + bail: 0, + // + // Set a base URL in order to shorten url command calls. If your `url` parameter starts + // with `/`, the base url gets prepended, not including the path portion of your baseUrl. + // If your `url` parameter starts without a scheme or `/` (like `some/path`), the base url + // gets prepended directly. + baseUrl: 'http://localhost', + // + // Default timeout for all waitFor* commands. + waitforTimeout: 10000, + // + // Default timeout in milliseconds for request + // if browser driver or grid doesn't send response + connectionRetryTimeout: 120000, + // + // Default request retries count + connectionRetryCount: 3, + // + // Test runner services + // Services take over a specific job you don't want to take care of. They enhance + // your test setup with almost no effort. Unlike plugins, they don't add new + // commands. Instead, they hook themselves up into the test process. + services: ['chromedriver', + [ + EyesService, + { + viewportSize: {width: 1200, height: 800}, + apiKey: process.env.APPLITOOLS_API_KEY, + useVisualGrid: true, + browsersInfo: [ + {width: 1200, height: 800, name: 'chrome'}, + {width: 1200, height: 800, name: 'firefox'}, + {width: 1200, height: 800, name: 'safari'}, + {width: 1200, height: 800, name: 'edgechromium'}, + {width: 1200, height: 800, name: 'ie'} + ], + concurrency: 5 + } + ] + ], + + // Framework you want to run your specs with. + // The following are supported: Mocha, Jasmine, and Cucumber + // see also: https://webdriver.io/docs/frameworks + // + // Make sure you have the wdio adapter package for the specific framework installed + // before running any tests. + framework: 'mocha', + // + // The number of times to retry the entire specfile when it fails as a whole + // specFileRetries: 1, + // + // Delay in seconds between the spec file retry attempts + // specFileRetriesDelay: 0, + // + // Whether or not retried specfiles should be retried immediately or deferred to the end of the queue + // specFileRetriesDeferred: false, + // + // Test reporter for stdout. + // The only one supported by default is 'dot' + // see also: https://webdriver.io/docs/dot-reporter + reporters: ['spec'], + + + + // + // Options to be passed to Mocha. + // See the full list at http://mochajs.org/ + mochaOpts: { + ui: 'bdd', + timeout: 60000 + }, + // + // ===== + // Hooks + // ===== + // WebdriverIO provides several hooks you can use to interfere with the test process in order to enhance + // it and to build services around it. You can either apply a single function or an array of + // methods to it. If one of them returns with a promise, WebdriverIO will wait until that promise got + // resolved to continue. + /** + * Gets executed once before all workers get launched. + * @param {Object} config wdio configuration object + * @param {Array.} capabilities list of capabilities details + */ + // onPrepare: function (config, capabilities) { + // }, + /** + * Gets executed before a worker process is spawned and can be used to initialise specific service + * for that worker as well as modify runtime environments in an async fashion. + * @param {String} cid capability id (e.g 0-0) + * @param {[type]} caps object containing capabilities for session that will be spawn in the worker + * @param {[type]} specs specs to be run in the worker process + * @param {[type]} args object that will be merged with the main configuration once worker is initialised + * @param {[type]} execArgv list of string arguments passed to the worker process + */ + // onWorkerStart: function (cid, caps, specs, args, execArgv) { + // }, + /** + * Gets executed just before initialising the webdriver session and test framework. It allows you + * to manipulate configurations depending on the capability or spec. + * @param {Object} config wdio configuration object + * @param {Array.} capabilities list of capabilities details + * @param {Array.} specs List of spec file paths that are to be run + */ + // beforeSession: function (config, capabilities, specs) { + // }, + /** + * Gets executed before test execution begins. At this point you can access to all global + * variables like `browser`. It is the perfect place to define custom commands. + * @param {Array.} capabilities list of capabilities details + * @param {Array.} specs List of spec file paths that are to be run + * @param {Object} browser instance of created browser/device session + */ + // before: function (capabilities, specs) { + // }, + /** + * Runs before a WebdriverIO command gets executed. + * @param {String} commandName hook command name + * @param {Array} args arguments that command would receive + */ + // beforeCommand: function (commandName, args) { + // }, + /** + * Hook that gets executed before the suite starts + * @param {Object} suite suite details + */ + // beforeSuite: function (suite) { + // }, + /** + * Function to be executed before a test (in Mocha/Jasmine) starts. + */ + // beforeTest: function (test, context) { + // }, + /** + * Hook that gets executed _before_ a hook within the suite starts (e.g. runs before calling + * beforeEach in Mocha) + */ + // beforeHook: function (test, context) { + // }, + /** + * Hook that gets executed _after_ a hook within the suite starts (e.g. runs after calling + * afterEach in Mocha) + */ + // afterHook: function (test, context, { error, result, duration, passed, retries }) { + // }, + /** + * Function to be executed after a test (in Mocha/Jasmine). + */ + // afterTest: function(test, context, { error, result, duration, passed, retries }) { + // }, + + + /** + * Hook that gets executed after the suite has ended + * @param {Object} suite suite details + */ + // afterSuite: function (suite) { + // }, + /** + * Runs after a WebdriverIO command gets executed + * @param {String} commandName hook command name + * @param {Array} args arguments that command would receive + * @param {Number} result 0 - command success, 1 - command error + * @param {Object} error error object if any + */ + // afterCommand: function (commandName, args, result, error) { + // }, + /** + * Gets executed after all tests are done. You still have access to all global variables from + * the test. + * @param {Number} result 0 - test pass, 1 - test fail + * @param {Array.} capabilities list of capabilities details + * @param {Array.} specs List of spec file paths that ran + */ + // after: function (result, capabilities, specs) { + // }, + /** + * Gets executed right after terminating the webdriver session. + * @param {Object} config wdio configuration object + * @param {Array.} capabilities list of capabilities details + * @param {Array.} specs List of spec file paths that ran + */ + // afterSession: function (config, capabilities, specs) { + // }, + /** + * Gets executed after all workers got shut down and the process is about to exit. An error + * thrown in the onComplete hook will result in the test run failing. + * @param {Object} exitCode 0 - success, 1 - fail + * @param {Object} config wdio configuration object + * @param {Array.} capabilities list of capabilities details + * @param {} results object containing test results + */ + // onComplete: function(exitCode, config, capabilities, results) { + // }, + /** + * Gets executed when a refresh happens. + * @param {String} oldSessionId session ID of the old session + * @param {String} newSessionId session ID of the new session + */ + //onReload: function(oldSessionId, newSessionId) { + //} +}