diff --git a/wdio/README.md b/wdio/README.md index 49e55863..d13281a0 100644 --- a/wdio/README.md +++ b/wdio/README.md @@ -57,6 +57,19 @@ npm run sauce-visual npm run sauce-visual-check ``` +**NOTE:** +By default the tests will be executed on the US DC, if you want to run them on the EU DC then please run the following command + +```sh { name=npm-run-eu } +REGION=eu npm run sauce-visual +``` + +or + +```sh { name=npm-run-modified-eu } +REGION=eu npm run sauce-visual-check +``` + - Open the test or go to https://app.saucelabs.com/visual/builds to review changes. ## How to add visual testing to your setup diff --git a/wdio/package.json b/wdio/package.json index 41547b6b..b8211ec5 100644 --- a/wdio/package.json +++ b/wdio/package.json @@ -12,8 +12,8 @@ "typescript": "^5.2.2" }, "scripts": { - "sauce-visual": "wdio run ./wdio.conf.ts --spec src/inventory.spec.ts", - "sauce-visual-check": "VISUAL_CHECK=true wdio run ./wdio.conf.ts --spec src/inventory.spec.ts" + "sauce-visual": "wdio run ./src/configs/wdio.saucelabs.desktop.conf.ts --spec src/inventory.spec.ts", + "sauce-visual-check": "VISUAL_CHECK=true wdio run ./src/configs/wdio.saucelabs.desktop.conf.ts --spec src/inventory.spec.ts" }, "dependencies": { "@saucelabs/wdio-sauce-visual-service": "^0.3.84", diff --git a/wdio/src/configs/wdio.saucelabs.desktop.conf.ts b/wdio/src/configs/wdio.saucelabs.desktop.conf.ts new file mode 100644 index 00000000..684bc1a1 --- /dev/null +++ b/wdio/src/configs/wdio.saucelabs.desktop.conf.ts @@ -0,0 +1,50 @@ +import type { Options } from '@wdio/types'; +import { config as sauceSharedConfig } from './wdio.saucelabs.shared.conf.ts'; + +const buildName = `Sauce Demo Test - ${new Date().getTime()}`; + +export const config: Options.Testrunner = { + ...sauceSharedConfig, + // + // ============ + // Capabilities + // ============ + capabilities: [ + { + browserName: 'chrome', + browserVersion: 'latest', + platformName: 'Windows 11', + 'sauce:options': { + screenResolution: '2560x1600', + build: buildName, + }, + }, + { + browserName: 'firefox', + browserVersion: 'latest', + platformName: 'Windows 11', + 'sauce:options': { + screenResolution: '2560x1600', + build: buildName, + }, + }, + { + browserName: 'microsoftedge', + browserVersion: 'latest', + platformName: 'Windows 11', + 'sauce:options': { + screenResolution: '2560x1600', + build: buildName, + }, + }, + { + browserName: 'safari', + browserVersion: 'latest', + platformName: 'macOS 13', + 'sauce:options': { + screenResolution: '2048x1536', + build: buildName, + }, + }, + ], +}; diff --git a/wdio/src/configs/wdio.saucelabs.shared.conf.ts b/wdio/src/configs/wdio.saucelabs.shared.conf.ts new file mode 100644 index 00000000..8ce530de --- /dev/null +++ b/wdio/src/configs/wdio.saucelabs.shared.conf.ts @@ -0,0 +1,59 @@ +import type { Options } from '@wdio/types'; +import { browser } from '@wdio/globals'; +import { SauceVisualService } from '@saucelabs/wdio-sauce-visual-service'; +import { config as sharedConfig } from './wdio.shared.conf.ts'; +import { getSauceCredentials } from '../helpers.ts'; + +// +// Get the Sauce Labs credentials +const { sauceUsername, sauceAccessKey } = await getSauceCredentials(); + +export const config: Options.Testrunner = { + ...sharedConfig, + // + // ================= + // Service Providers + // ================= + user: sauceUsername, + key: sauceAccessKey, + region: (process.env.REGION || 'us') as Options.SauceRegions, + // + // ============ + // Capabilities + // ============ + // Are not configured here, they can be found in: + // - wdio.saucelabs.desktop.conf.ts + // + // ======== + // Services + // ======== + services: (sharedConfig.services || []).concat([ + // + // This service is needed for WDIO to make sure it can connect to Sauce Labs to: + // - automatically update the names + // - automatically update the status (passed/failed) + // - automatically send the stacktrace in case of a failure + // + 'sauce', + // + // This service is needed for the Sauce Visual service to work + // + [ + SauceVisualService, + // The options for the Sauce Visual service + { + buildName: 'Sauce Demo Test', + branch: 'main', + project: 'WDIO examples', + }, + ], + ]), + // ===== + // Hooks + // ===== + before: async (_capabilities, _specs) => { + // Set all browsers to the "same" viewport + // @ts-ignore + await browser.setWindowSize(1920, 1080); + }, +}; diff --git a/wdio/wdio.conf.ts b/wdio/src/configs/wdio.shared.conf.ts similarity index 84% rename from wdio/wdio.conf.ts rename to wdio/src/configs/wdio.shared.conf.ts index 8edcc6fb..d277951e 100644 --- a/wdio/wdio.conf.ts +++ b/wdio/src/configs/wdio.shared.conf.ts @@ -1,10 +1,4 @@ import type { Options } from '@wdio/types'; -import 'dotenv/config'; -import updateDotenv from 'update-dotenv'; -import readline from 'readline-sync'; -import { SauceVisualService } from '@saucelabs/wdio-sauce-visual-service'; - -const { sauceUsername, sauceAccessKey } = await getSauceCredentials(); export const config: Options.Testrunner = { // @@ -28,17 +22,9 @@ export const config: Options.Testrunner = { // should work too though). These services define specific user and key (or access key) // values you need to put in here in order to connect to these services. // - user: sauceUsername, - key: sauceAccessKey, - // - // If you run your tests on Sauce Labs you can specify the region you want to run your tests - // in via the `region` property. Available short handles for regions are `us` (default), `eu` and `apac`. - // These regions are used for the Sauce Labs VM cloud and the Sauce Labs Real Device Cloud. - // If you don't provide the region it will default for the `us` - protocol: 'https', - hostname: 'ondemand.saucelabs.com', - port: 443, - path: '/wd/hub', + // ======================================================= + // See wdio.saucelabs.shared.conf.ts for more information. + // ======================================================= // // ================== // Specify Test Files @@ -82,18 +68,12 @@ export const config: Options.Testrunner = { // Sauce Labs platform configurator - a great tool to configure your capabilities: // https://saucelabs.com/platform/platform-configurator // - capabilities: [ - { - // capabilities for local browser web tests - browserName: 'chrome', // or 'firefox', 'microsoftedge', 'safari' - browserVersion: 'latest', - platformName: 'Windows 11', - 'sauce:options': { - screenResolution: '1920x1080', - build: `Sauce Demo Test - ${new Date().getTime()}`, - }, - }, - ], + // ================================= + // For capabilities see: + // - wdio.saucelabs.desktop.conf.ts + // ================================= + // + capabilities: [], // // =================== // Test Configurations @@ -141,17 +121,12 @@ export const config: Options.Testrunner = { // 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: [ - 'sauce', - [ - SauceVisualService, - { - buildName: 'Sauce Demo Test', - branch: 'main', - project: 'WDIO examples', - }, - ], - ], + // + // ============================================================== + // For implementing Sauce Labs, see wdio.saucelabs.shared.conf.ts + // ============================================================== + // + services: [], // Framework you want to run your specs with. // The following are supported: Mocha, Jasmine, and Cucumber @@ -329,36 +304,3 @@ export const config: Options.Testrunner = { // onReload: function(oldSessionId, newSessionId) { // } }; - -async function getSauceCredentials(): Promise<{ - sauceUsername: string; - sauceAccessKey: string; -}> { - var sauceUsername = process.env.SAUCE_USERNAME; - var sauceAccessKey = process.env.SAUCE_ACCESS_KEY; - - if (!sauceUsername) { - sauceUsername = await readline.question( - 'What is your Sauce Labs username? ' - ); - await updateDotenv({ - SAUCE_USERNAME: sauceUsername, - }); - console.log('Sauce Labs username is saved in the .env file.'); - } - - if (!sauceAccessKey) { - sauceAccessKey = await readline.question( - 'What is your Sauce Labs API key?? ', - { - hideEchoBack: true, - } - ); - await updateDotenv({ - SAUCE_ACCESS_KEY: sauceAccessKey, - }); - console.log('Sauce Labs API key is saved in the .env file.'); - } - - return { sauceUsername, sauceAccessKey }; -} diff --git a/wdio/src/helpers.ts b/wdio/src/helpers.ts new file mode 100644 index 00000000..53df77aa --- /dev/null +++ b/wdio/src/helpers.ts @@ -0,0 +1,40 @@ +import 'dotenv/config'; +import updateDotenv from 'update-dotenv'; +import readline from 'readline-sync'; + +/** + * Get the Sauce Labs credentials from the environment variables, if not available, + * ask the user to provide them and store them in a .env file. + */ +export async function getSauceCredentials(): Promise<{ + sauceUsername: string; + sauceAccessKey: string; +}> { + let sauceUsername = process.env.SAUCE_USERNAME; + let sauceAccessKey = process.env.SAUCE_ACCESS_KEY; + + if (!sauceUsername) { + sauceUsername = await readline.question( + 'What is your Sauce Labs username? ' + ); + await updateDotenv({ + SAUCE_USERNAME: sauceUsername, + }); + console.log('Sauce Labs username is saved in the .env file.'); + } + + if (!sauceAccessKey) { + sauceAccessKey = await readline.question( + 'What is your Sauce Labs API key?? ', + { + hideEchoBack: true, + } + ); + await updateDotenv({ + SAUCE_ACCESS_KEY: sauceAccessKey, + }); + console.log('Sauce Labs API key is saved in the .env file.'); + } + + return { sauceUsername, sauceAccessKey }; +} diff --git a/wdio/src/inventory.spec.ts b/wdio/src/inventory.spec.ts index 25cba68c..2d89c3c0 100644 --- a/wdio/src/inventory.spec.ts +++ b/wdio/src/inventory.spec.ts @@ -1,3 +1,4 @@ +import { browser } from '@wdio/globals'; import InventoryPage from './pages/inventory.page.js'; import LoginPage from './pages/login.page.js'; diff --git a/wdio/tsconfig.json b/wdio/tsconfig.json index 2b5072df..bb57caf3 100644 --- a/wdio/tsconfig.json +++ b/wdio/tsconfig.json @@ -1,7 +1,7 @@ { "compilerOptions": { - "moduleResolution": "node", - "module": "ESNext", + "module": "NodeNext", + "moduleResolution": "NodeNext", "types": [ "node", "@wdio/globals/types", @@ -10,6 +10,8 @@ "@wdio/sauce-service" ], "allowSyntheticDefaultImports": true, - "target": "es2022" + "target": "es2022", + "noEmit": true, + "allowImportingTsExtensions": true } } \ No newline at end of file