From 1fe7ce9a6aeb9f649ee417c42c1bbaa562e18cca Mon Sep 17 00:00:00 2001 From: developer Date: Sun, 28 Sep 2025 11:27:33 +0300 Subject: [PATCH] added export of `QavajsPlaywrightWorld` and `QavajsPlaywrightElectronWorld` --- CHANGELOG.md | 3 ++ index.d.ts | 4 +- package-lock.json | 40 ++++++++--------- package.json | 8 ++-- src/QavajsPlaywrightWorld.ts | 12 ++++++ src/actions.ts | 69 +++++++++++++++--------------- src/conditionWait.ts | 2 +- src/cookies.ts | 9 ++-- src/dialog.ts | 11 ++--- src/electron.ts | 7 +-- src/execute.ts | 9 ++-- src/hooks.ts | 9 ++-- src/intercept.ts | 7 +-- src/keyboardActions.ts | 5 ++- src/localSessionStorage.ts | 9 ++-- src/memory.ts | 23 +++++----- src/mock.ts | 11 ++--- src/mouseActions.ts | 9 ++-- src/poDefine.ts | 3 +- src/validations.ts | 29 +++++++------ src/waits.ts | 13 +++--- test-e2e/step-definitions/index.ts | 9 ++-- test-e2e/tsconfig.json | 19 ++++++++ 23 files changed, 186 insertions(+), 134 deletions(-) create mode 100644 src/QavajsPlaywrightWorld.ts create mode 100644 test-e2e/tsconfig.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d1990d..0d94b8e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,9 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how :microscope: - experimental +## [2.11.0] +- :rocket: added export of `QavajsPlaywrightWorld` and `QavajsPlaywrightElectronWorld` + ## [2.10.0] - :rocket: added step to interact with electron app menu ```gherkin diff --git a/index.d.ts b/index.d.ts index c55afd2..1076601 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1 +1,3 @@ -export * from './src/IQavajsPlaywrightConfig'; \ No newline at end of file +export * from './src/IQavajsPlaywrightConfig'; +export * from './src/QavajsPlaywrightWorld'; +export * from './src/pageObject'; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 3f052d8..01953c5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "2.10.0", "license": "MIT", "dependencies": { - "@playwright/test": "^1.55.0" + "@playwright/test": "^1.55.1" }, "devDependencies": { "@cucumber/cucumber": "^12.2.0", @@ -20,10 +20,10 @@ "@qavajs/validation": "^1.3.0", "@qavajs/webstorm-adapter": "^8.0.0", "@types/express": "^5.0.3", - "@types/node": "^24.5.1", + "@types/node": "^24.5.2", "@vitest/coverage-v8": "^3.2.4", "@vitest/ui": "^3.2.4", - "electron": "^38.1.2", + "electron": "^38.2.0", "express": "^5.1.0", "ts-node": "^10.9.2", "typescript": "^5.9.2", @@ -1054,12 +1054,12 @@ } }, "node_modules/@playwright/test": { - "version": "1.55.0", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.55.0.tgz", - "integrity": "sha512-04IXzPwHrW69XusN/SIdDdKZBzMfOT9UNT/YiJit/xpy2VuAoB8NHc8Aplb96zsWDddLnbkPL3TsmrS04ZU2xQ==", + "version": "1.55.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.55.1.tgz", + "integrity": "sha512-IVAh/nOJaw6W9g+RJVlIQJ6gSiER+ae6mKQ5CX1bERzQgbC1VSeBlwdvczT7pxb0GWiyrxH4TGKbMfDb4Sq/ig==", "license": "Apache-2.0", "dependencies": { - "playwright": "1.55.0" + "playwright": "1.55.1" }, "bin": { "playwright": "cli.js" @@ -1855,9 +1855,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "24.5.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.5.1.tgz", - "integrity": "sha512-/SQdmUP2xa+1rdx7VwB9yPq8PaKej8TD5cQ+XfKDPWWC+VDJU4rvVVagXqKUzhKjtFoNA8rXDJAkCxQPAe00+Q==", + "version": "24.5.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.5.2.tgz", + "integrity": "sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2918,9 +2918,9 @@ "license": "MIT" }, "node_modules/electron": { - "version": "38.1.2", - "resolved": "https://registry.npmjs.org/electron/-/electron-38.1.2.tgz", - "integrity": "sha512-WXUcN3W8h8NTTZViA3KNX0rV2YBU0X0mEUM3ubupXTDY4QtIN7tmiqYVOKSKpR2LckTmBWGuEeY4D6xVoffwKQ==", + "version": "38.2.0", + "resolved": "https://registry.npmjs.org/electron/-/electron-38.2.0.tgz", + "integrity": "sha512-Cw5Mb+N5NxsG0Hc1qr8I65Kt5APRrbgTtEEn3zTod30UNJRnAE1xbGk/1NOaDn3ODzI/MYn6BzT9T9zreP7xWA==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -4562,12 +4562,12 @@ } }, "node_modules/playwright": { - "version": "1.55.0", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.55.0.tgz", - "integrity": "sha512-sdCWStblvV1YU909Xqx0DhOjPZE4/5lJsIS84IfN9dAZfcl/CIZ5O8l3o0j7hPMjDvqoTF8ZUcc+i/GL5erstA==", + "version": "1.55.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.55.1.tgz", + "integrity": "sha512-cJW4Xd/G3v5ovXtJJ52MAOclqeac9S/aGGgRzLabuF8TnIb6xHvMzKIa6JmrRzUkeXJgfL1MhukP0NK6l39h3A==", "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.55.0" + "playwright-core": "1.55.1" }, "bin": { "playwright": "cli.js" @@ -4580,9 +4580,9 @@ } }, "node_modules/playwright-core": { - "version": "1.55.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.55.0.tgz", - "integrity": "sha512-GvZs4vU3U5ro2nZpeiwyb0zuFaqb9sUiAJuyrWpcGouD8y9/HLgGbNRjIph7zU9D3hnPaisMl9zG9CgFi/biIg==", + "version": "1.55.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.55.1.tgz", + "integrity": "sha512-Z6Mh9mkwX+zxSlHqdr5AOcJnfp+xUWLCt9uKV18fhzA8eyxUd8NUWzAjxUh55RZKSYwDGX0cfaySdhZJGMoJ+w==", "license": "Apache-2.0", "bin": { "playwright-core": "cli.js" diff --git a/package.json b/package.json index d6404ee..0cd5c95 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@qavajs/steps-playwright", - "version": "2.10.0", + "version": "2.11.0", "description": "qavajs steps to interact with playwright", "main": "./index.js", "scripts": { @@ -34,17 +34,17 @@ "@qavajs/validation": "^1.3.0", "@qavajs/webstorm-adapter": "^8.0.0", "@types/express": "^5.0.3", - "@types/node": "^24.5.1", + "@types/node": "^24.5.2", "@vitest/coverage-v8": "^3.2.4", "@vitest/ui": "^3.2.4", - "electron": "^38.1.2", + "electron": "^38.2.0", "express": "^5.1.0", "ts-node": "^10.9.2", "typescript": "^5.9.2", "vitest": "^3.2.4" }, "dependencies": { - "@playwright/test": "^1.55.0" + "@playwright/test": "^1.55.1" }, "keywords": [ "test", diff --git a/src/QavajsPlaywrightWorld.ts b/src/QavajsPlaywrightWorld.ts new file mode 100644 index 0000000..379d448 --- /dev/null +++ b/src/QavajsPlaywrightWorld.ts @@ -0,0 +1,12 @@ +import { IQavajsWorld } from '@qavajs/core'; +import type { Locator, ElectronApplication } from '@playwright/test'; +import { Playwright } from './playwright'; + +export interface QavajsPlaywrightWorld extends IQavajsWorld { + playwright: Playwright + element(path: string): Locator +} + +export interface QavajsPlaywrightElectronWorld extends QavajsPlaywrightWorld { + playwright: Playwright & { driver: ElectronApplication, browser: ElectronApplication } +} \ No newline at end of file diff --git a/src/actions.ts b/src/actions.ts index fd45982..d7d5912 100644 --- a/src/actions.ts +++ b/src/actions.ts @@ -1,13 +1,14 @@ import { type Page, type Locator } from '@playwright/test'; import { parseCoords, parseCoordsAsObject, sleep } from './utils/utils'; import { type MemoryValue, When } from '@qavajs/core'; +import { QavajsPlaywrightWorld } from './QavajsPlaywrightWorld'; /** * Opens provided url * @param {string} url - url to navigate * @example I open 'https://google.com' */ -When('I open {value} url', async function (url: MemoryValue): Promise { +When('I open {value} url', async function (this: QavajsPlaywrightWorld, url: MemoryValue): Promise { await this.playwright.page.goto(await url.value()); }); @@ -18,7 +19,7 @@ When('I open {value} url', async function (url: MemoryValue): Promise { * @example I type 'wikipedia' to 'Google Input' * @example I type 'wikipedia' into 'Google Input' */ -When('I type {value} (in)to {playwrightLocator}', async function (value: MemoryValue, locator: Locator): Promise { +When('I type {value} (in)to {playwrightLocator}', async function (this: QavajsPlaywrightWorld, value: MemoryValue, locator: Locator): Promise { const typeValue = await value.value() await locator.fill(typeValue); }); @@ -30,7 +31,7 @@ When('I type {value} (in)to {playwrightLocator}', async function (value: MemoryV * @example I type 'wikipedia' chars to 'Google Input' * @example I type 'wikipedia' chars into 'Google Input' */ -When('I type {value} chars (in)to {playwrightLocator}', async function (value: MemoryValue, locator: Locator) { +When('I type {value} chars (in)to {playwrightLocator}', async function (this: QavajsPlaywrightWorld, value: MemoryValue, locator: Locator) { const typeValue = await value.value(); await locator.pressSequentially(typeValue); }); @@ -40,7 +41,7 @@ When('I type {value} chars (in)to {playwrightLocator}', async function (value: M * @param {string} alias - element to click * @example I click 'Google Button' */ -When('I click {playwrightLocator}', async function (locator: Locator) { +When('I click {playwrightLocator}', async function (this: QavajsPlaywrightWorld, locator: Locator) { await locator.click(); }); @@ -49,7 +50,7 @@ When('I click {playwrightLocator}', async function (locator: Locator) { * @param {string} alias - element to click * @example I force click 'Google Button' */ -When('I force click {playwrightLocator}', async function (locator: Locator) { +When('I force click {playwrightLocator}', async function (this: QavajsPlaywrightWorld, locator: Locator) { await locator.evaluate((e: HTMLElement) => e.click()); }); @@ -58,7 +59,7 @@ When('I force click {playwrightLocator}', async function (locator: Locator) { * @param {string} alias - element to right click * @example I right click 'Google Button' */ -When('I right click {playwrightLocator}', async function (locator: Locator) { +When('I right click {playwrightLocator}', async function (this: QavajsPlaywrightWorld, locator: Locator) { await locator.click({ button: 'right' }); }); @@ -67,7 +68,7 @@ When('I right click {playwrightLocator}', async function (locator: Locator) { * @param {string} alias - double element to click * @example I double click 'Google Button' */ -When('I double click {playwrightLocator}', async function (locator: Locator) { +When('I double click {playwrightLocator}', async function (this: QavajsPlaywrightWorld, locator: Locator) { await locator.dblclick(); }); @@ -76,7 +77,7 @@ When('I double click {playwrightLocator}', async function (locator: Locator) { * @param {string} alias - element to clear * @example I clear 'Google Input' */ -When('I clear {playwrightLocator}', async function (locator: Locator) { +When('I clear {playwrightLocator}', async function (this: QavajsPlaywrightWorld, locator: Locator) { await locator.fill(''); }); @@ -85,7 +86,7 @@ When('I clear {playwrightLocator}', async function (locator: Locator) { * @param {number} index - index to switch * @example I switch to 2 window */ -When('I switch to {int} window', async function (index: number) { +When('I switch to {int} window', async function (this: QavajsPlaywrightWorld, index: number) { await this.playwright.expect.poll( () => this.playwright.context.pages().length, { timeout:this.config.browser.timeout.page } @@ -99,7 +100,7 @@ When('I switch to {int} window', async function (index: number) { * @param {string} matcher - url or title of window to switch * @example I switch to 'google' window */ -When('I switch to {value} window', async function (matcher: MemoryValue) { +When('I switch to {value} window', async function (this: QavajsPlaywrightWorld, matcher: MemoryValue) { const urlOrTitle = await matcher.value(); const poll = async () => { const pages = this.playwright.context.pages(); @@ -125,7 +126,7 @@ When('I switch to {value} window', async function (matcher: MemoryValue) { * Refresh current page * @example I refresh page */ -When('I refresh page', async function () { +When('I refresh page', async function (this: QavajsPlaywrightWorld, ) { await this.playwright.page.reload(); }); @@ -135,7 +136,7 @@ When('I refresh page', async function () { * @example I press 'Enter' key * @example I press 'Control+C' keys */ -When('I press {string} key(s)', async function (key: string) { +When('I press {string} key(s)', async function (this: QavajsPlaywrightWorld, key: string) { await this.playwright.page.press('body', key); }); @@ -146,7 +147,7 @@ When('I press {string} key(s)', async function (key: string) { * @example I press 'Enter' key 5 times * @example I press 'Control+V' keys 5 times */ -When('I press {string} key(s) {int} time(s)', async function (key: string, num: number) { +When('I press {string} key(s) {int} time(s)', async function (this: QavajsPlaywrightWorld, key: string, num: number) { for (let i: number = 0; i < num; i++) { await this.playwright.page.keyboard.press(key); } @@ -157,7 +158,7 @@ When('I press {string} key(s) {int} time(s)', async function (key: string, num: * @param {string} alias - element to hover over * @example I hover over 'Google Button' */ -When('I hover over {playwrightLocator}', async function (locator: Locator) { +When('I hover over {playwrightLocator}', async function (this: QavajsPlaywrightWorld, locator: Locator) { await locator.hover(); }); @@ -168,7 +169,7 @@ When('I hover over {playwrightLocator}', async function (locator: Locator) { * @example I select '1900' option from 'Registration Form > Date Of Birth' * @example I select '$dateOfBirth' option from 'Registration Form > Date Of Birth' dropdown */ -When('I select {value} option from {playwrightLocator} dropdown', async function (option: MemoryValue, locator: Locator) { +When('I select {value} option from {playwrightLocator} dropdown', async function (this: QavajsPlaywrightWorld, option: MemoryValue, locator: Locator) { await locator.selectOption({ label: await option.value() }); }); @@ -178,7 +179,7 @@ When('I select {value} option from {playwrightLocator} dropdown', async function * @param {string} alias - alias of select * @example I select 1 option from 'Registration Form > Date Of Birth' dropdown */ -When('I select {int}(st|nd|rd|th) option from {playwrightLocator} dropdown', async function (optionIndex: number, locator: Locator) { +When('I select {int}(st|nd|rd|th) option from {playwrightLocator} dropdown', async function (this: QavajsPlaywrightWorld, optionIndex: number, locator: Locator) { await locator.selectOption({ index: optionIndex - 1 }); }); @@ -202,7 +203,7 @@ When( * @example * When I scroll by '0, 100' */ -When('I scroll by {value}', async function (offset: MemoryValue) { +When('I scroll by {value}', async function (this: QavajsPlaywrightWorld, offset: MemoryValue) { const [x, y] = parseCoords(await offset.value()); await this.playwright.page.mouse.wheel(x, y); }); @@ -212,7 +213,7 @@ When('I scroll by {value}', async function (offset: MemoryValue) { * @param {string} alias - alias of element * @example I scroll to 'Element' */ -When('I scroll to {playwrightLocator}', async function (locator: Locator) { +When('I scroll to {playwrightLocator}', async function (this: QavajsPlaywrightWorld, locator: Locator) { await locator.scrollIntoViewIfNeeded(); }); @@ -223,7 +224,7 @@ When('I scroll to {playwrightLocator}', async function (locator: Locator) { * @example * When I scroll by '0, 100' in 'Overflow Container' */ -When('I scroll by {value} in {playwrightLocator}', async function (offset: MemoryValue, locator: Locator) { +When('I scroll by {value} in {playwrightLocator}', async function (this: QavajsPlaywrightWorld, offset: MemoryValue, locator: Locator) { const [x, y] = parseCoords(await offset.value()); await locator.hover(); await this.playwright.page.mouse.wheel(x, y); @@ -235,7 +236,7 @@ When('I scroll by {value} in {playwrightLocator}', async function (offset: Memor * @example * When I scroll until 'Row 99' to be visible */ -When('I scroll until {playwrightLocator} to be visible', async function (locator: Locator) { +When('I scroll until {playwrightLocator} to be visible', async function (this: QavajsPlaywrightWorld, locator: Locator) { const isVisible = async () => await locator.isVisible(); while (!await isVisible()) { await this.playwright.page.mouse.wheel(0, 100); @@ -250,7 +251,7 @@ When('I scroll until {playwrightLocator} to be visible', async function (locator * @example * When I scroll in 'List' until 'Row 99' to be visible */ -When('I scroll in {playwrightLocator} until {playwrightLocator} to be visible', async function (scrollLocator: Locator, targetLocator: Locator) { +When('I scroll in {playwrightLocator} until {playwrightLocator} to be visible', async function (this: QavajsPlaywrightWorld, scrollLocator: Locator, targetLocator: Locator) { await scrollLocator.hover(); const isVisible = async () => await targetLocator.isVisible(); while (!await isVisible()) { @@ -265,7 +266,7 @@ When('I scroll in {playwrightLocator} until {playwrightLocator} to be visible', * @param {string} initiatorAlias - alias of an element triggering downloading process * @example I save file to './folder/file.pdf' by clicking 'Download Button' */ -When('I save file to {value} by clicking {playwrightLocator}', async function (path: MemoryValue, locator: Locator) { +When('I save file to {value} by clicking {playwrightLocator}', async function (this: QavajsPlaywrightWorld, path: MemoryValue, locator: Locator) { const downloadPromise = this.playwright.page.waitForEvent('download'); await locator.click(); const download = await downloadPromise; @@ -278,7 +279,7 @@ When('I save file to {value} by clicking {playwrightLocator}', async function (p * @param {string} value - file path * @example I upload '/folder/file.txt' to 'File Input' */ -When('I upload {value} file to {playwrightLocator}', async function (filePath: MemoryValue, locator: Locator) { +When('I upload {value} file to {playwrightLocator}', async function (this: QavajsPlaywrightWorld, filePath: MemoryValue, locator: Locator) { await locator.setInputFiles(await filePath.value()); }); @@ -288,7 +289,7 @@ When('I upload {value} file to {playwrightLocator}', async function (filePath: M * @param {string} value - file path * @example I upload '/folder/file.txt' by clicking 'Upload Button' */ -When('I upload {value} file by clicking {playwrightLocator}', async function (filePath: MemoryValue, locator: Locator) { +When('I upload {value} file by clicking {playwrightLocator}', async function (this: QavajsPlaywrightWorld, filePath: MemoryValue, locator: Locator) { const fileChooserPromise = this.playwright.page.waitForEvent('filechooser'); await locator.click(); const fileChooser = await fileChooserPromise; @@ -301,7 +302,7 @@ When('I upload {value} file by clicking {playwrightLocator}', async function (fi * @param {string} targetAlias - target * @example I drag and drop 'Bishop' to 'E4' */ -When('I drag and drop {playwrightLocator} to {playwrightLocator}', async function (locator: Locator, target: Locator) { +When('I drag and drop {playwrightLocator} to {playwrightLocator}', async function (this: QavajsPlaywrightWorld, locator: Locator, target: Locator) { await locator.dragTo(target); }); @@ -309,7 +310,7 @@ When('I drag and drop {playwrightLocator} to {playwrightLocator}', async functio * Open new browser tab * @example I open new tab */ -When('I open new tab', async function () { +When('I open new tab', async function (this: QavajsPlaywrightWorld, ) { await this.playwright.page.evaluate(() => { window.open('about:blank', '_blank') }); }); @@ -318,7 +319,7 @@ When('I open new tab', async function () { * @example * Then I close current tab */ -When('I close current tab', async function () { +When('I close current tab', async function (this: QavajsPlaywrightWorld, ) { await this.playwright.page.close(); const page = this.playwright.context.pages().at(0); if (page) { @@ -333,7 +334,7 @@ When('I close current tab', async function () { * @param {string} alias - element to click * @example When I click '0, 20' coordinates in 'Element' */ -When('I click {value} coordinates in {playwrightLocator}', async function (coords: MemoryValue, locator: Locator) { +When('I click {value} coordinates in {playwrightLocator}', async function (this: QavajsPlaywrightWorld, coords: MemoryValue, locator: Locator) { const coordinates = await coords.value(); const coordsObject = typeof coordinates === 'string' ? parseCoordsAsObject(coordinates) : coordinates; await locator.click({position: coordsObject}); @@ -344,7 +345,7 @@ When('I click {value} coordinates in {playwrightLocator}', async function (coord * @param {string} size - desired size * @example I set window size '1366,768' */ -When('I set window size {value}', async function (viewPort: MemoryValue) { +When('I set window size {value}', async function (this: QavajsPlaywrightWorld, viewPort: MemoryValue) { const {x, y} = parseCoordsAsObject(await viewPort.value()); await this.playwright.page.setViewportSize({width: x, height: y}); }); @@ -355,7 +356,7 @@ When('I set window size {value}', async function (viewPort: MemoryValue) { * @example I click back button * @example I click forward button */ -When('I click {playwrightBrowserButton} button', async function (button: 'back' | 'forward') { +When('I click {playwrightBrowserButton} button', async function (this: QavajsPlaywrightWorld, button: 'back' | 'forward') { if (button === 'back') return this.playwright.page.goBack(); if (button === 'forward') return this.playwright.page.goForward(); }); @@ -365,7 +366,7 @@ When('I click {playwrightBrowserButton} button', async function (button: 'back' * @param {string} alias - element to tap * @example I tap 'Google Button' */ -When('I tap {playwrightLocator}', async function (locator: Locator) { +When('I tap {playwrightLocator}', async function (this: QavajsPlaywrightWorld, locator: Locator) { await locator.tap(); }); @@ -375,14 +376,14 @@ When('I tap {playwrightLocator}', async function (locator: Locator) { * @example I grant 'geolocation' permission * Permissions documentation can be found here https://playwright.dev/docs/api/class-browsercontext#browser-context-grant-permissions-option-permissions */ -When('I grant {value} permission', async function (permission: MemoryValue) { +When('I grant {value} permission', async function (this: QavajsPlaywrightWorld, permission: MemoryValue) { await this.playwright.context.grantPermissions([await permission.value()]); }); /** * Clears all permission overrides for the browser this.playwright.context. */ -When('I revoke browser permissions', async function () { +When('I revoke browser permissions', async function (this: QavajsPlaywrightWorld, ) { await this.playwright.context.clearPermissions(); }); @@ -393,6 +394,6 @@ When('I revoke browser permissions', async function () { * where '$minsk' is memory alias of location object { latitude: 53.53, longitude: 27.34 }; * Passing null or undefined emulates position unavailable. */ -When('I set {value} geolocation', async function (geolocation: MemoryValue) { +When('I set {value} geolocation', async function (this: QavajsPlaywrightWorld, geolocation: MemoryValue) { await this.playwright.context.setGeolocation(await geolocation.value()); }); diff --git a/src/conditionWait.ts b/src/conditionWait.ts index af6c062..973baec 100644 --- a/src/conditionWait.ts +++ b/src/conditionWait.ts @@ -1,4 +1,4 @@ -import { Locator, expect } from '@playwright/test'; +import { type Locator, expect } from '@playwright/test'; class SoftAssertionError extends Error { name = 'SoftAssertionError'; diff --git a/src/cookies.ts b/src/cookies.ts index 5db71b9..7a98749 100644 --- a/src/cookies.ts +++ b/src/cookies.ts @@ -1,4 +1,5 @@ -import { type MemoryValue, When } from "@qavajs/core"; +import { type MemoryValue, When } from '@qavajs/core'; +import { QavajsPlaywrightWorld } from './QavajsPlaywrightWorld'; /** * Set cookie @@ -7,11 +8,11 @@ import { type MemoryValue, When } from "@qavajs/core"; * @example I set 'userID' cookie 'user1' * @example I set 'userID' cookie '$userIdCookie' */ -When('I set {value} cookie as {value}', async function (cookie: MemoryValue, value: MemoryValue) { +When('I set {value} cookie as {value}', async function (this: QavajsPlaywrightWorld, cookie: MemoryValue, value: MemoryValue) { const cookieValue = await value.value(); const cookieObject = typeof cookieValue === 'object' ? cookieValue : { value: cookieValue }; if (!cookieObject.url && !cookieObject.domain && !cookieObject.path) { - cookieObject.url =this.playwright.page.url(); + cookieObject.url = this.playwright.page.url(); } await this.playwright.context.addCookies([{ name: await cookie.value(), ...cookieObject }]); }); @@ -22,7 +23,7 @@ When('I set {value} cookie as {value}', async function (cookie: MemoryValue, val * @param {string} key - memory key * @example I save value of 'auth' cookie as 'authCookie' */ -When('I save value of {value} cookie as {value}', async function (cookie: MemoryValue, key: MemoryValue) { +When('I save value of {value} cookie as {value}', async function (this: QavajsPlaywrightWorld, cookie: MemoryValue, key: MemoryValue) { const cookieName = await cookie.value(); const cookies = await this.playwright.context.cookies(); const cookieValue = cookies.find((c: any) => c.name === cookieName); diff --git a/src/dialog.ts b/src/dialog.ts index 6bac209..dfaf31c 100644 --- a/src/dialog.ts +++ b/src/dialog.ts @@ -1,5 +1,6 @@ import { Dialog } from '@playwright/test'; import { type MemoryValue, type Validation, When, Then } from '@qavajs/core'; +import { QavajsPlaywrightWorld } from './QavajsPlaywrightWorld'; class DialogHolder { currentDialog!: Promise; @@ -18,7 +19,7 @@ function checkIfListening(isListening: boolean) { * Start listen for alert * @example I will wait for dialog */ -When('I will wait for alert/dialog', async function () { +When('I will wait for alert/dialog', async function (this: QavajsPlaywrightWorld) { dialogHolder.isListening = true; dialogHolder.currentDialog = new Promise(resolve => this.playwright.page.once('dialog', resolve)); }); @@ -27,7 +28,7 @@ When('I will wait for alert/dialog', async function () { * Accept alert * @example I accept alert */ -When('I accept alert/dialog', async function () { +When('I accept alert/dialog', async function (this: QavajsPlaywrightWorld) { checkIfListening(dialogHolder.isListening); const dialog = await dialogHolder.currentDialog; await dialog.accept(); @@ -38,7 +39,7 @@ When('I accept alert/dialog', async function () { * Playwright automatically dismisses all dialogs. This step is just to make it implicitly. * @example I dismiss alert */ -When('I dismiss alert/dialog', async function () { +When('I dismiss alert/dialog', async function (this: QavajsPlaywrightWorld) { checkIfListening(dialogHolder.isListening); const dialog = await dialogHolder.currentDialog; await dialog.dismiss(); @@ -48,7 +49,7 @@ When('I dismiss alert/dialog', async function () { * I type {string} to alert * @example I type 'coffee' to alert */ -When('I type {value} to alert/dialog', async function (value: MemoryValue) { +When('I type {value} to alert/dialog', async function (this: QavajsPlaywrightWorld, value: MemoryValue) { checkIfListening(dialogHolder.isListening); const typeValue = await value.value(); const dialog = await dialogHolder.currentDialog; @@ -63,7 +64,7 @@ When('I type {value} to alert/dialog', async function (value: MemoryValue) { */ Then( 'I expect text of alert/dialog {validation} {value}', - async function (validation: Validation, expected: MemoryValue) { + async function (this: QavajsPlaywrightWorld, validation: Validation, expected: MemoryValue) { checkIfListening(dialogHolder.isListening); const dialog = await dialogHolder.currentDialog; const message = dialog.message(); diff --git a/src/electron.ts b/src/electron.ts index ab25799..74570c8 100644 --- a/src/electron.ts +++ b/src/electron.ts @@ -1,4 +1,5 @@ import { type MemoryValue, When } from '@qavajs/core'; +import { QavajsPlaywrightElectronWorld } from './QavajsPlaywrightWorld'; /** * Execute client function on electron process and save result into memory @@ -7,7 +8,7 @@ import { type MemoryValue, When } from '@qavajs/core'; * @example I execute '$fn' function and save result as 'result' // fn is function reference * @example I execute '$js(async ({ app }) => app.getAppPath())' function and save result as 'scroll' */ -When('I execute {value} function/script on electron app', async function (fn: MemoryValue) { +When('I execute {value} function/script on electron app', async function (this: QavajsPlaywrightElectronWorld, fn: MemoryValue) { await this.playwright.driver.evaluate(await fn.value()); }); @@ -18,7 +19,7 @@ When('I execute {value} function/script on electron app', async function (fn: Me * @example I execute '$fn' function and save result as 'result' // fn is function reference * @example I execute '$js(async ({ app }) => app.getAppPath())' function on electron app and save result as 'result' */ -When('I execute {value} function/script on electron app and save result as {value}', async function (fn: MemoryValue, memoryKey: MemoryValue) { +When('I execute {value} function/script on electron app and save result as {value}', async function (this: QavajsPlaywrightElectronWorld, fn: MemoryValue, memoryKey: MemoryValue) { memoryKey.set(await this.playwright.driver.evaluate(await fn.value())); }); @@ -27,7 +28,7 @@ When('I execute {value} function/script on electron app and save result as {valu * @param {string} menuPath - menu path * @example I click 'File > Edit' electron menu */ -When('I click {value} electron menu', async function (menu: MemoryValue) { +When('I click {value} electron menu', async function (this: QavajsPlaywrightElectronWorld, menu: MemoryValue) { await this.playwright.driver.evaluate(async ({ Menu }: { Menu: any }, { menuPath }: { menuPath: string }) => { const path = menuPath.split(/\s*>\s*/) as string[]; const menu = Menu.getApplicationMenu(); diff --git a/src/execute.ts b/src/execute.ts index e951896..3ea765d 100644 --- a/src/execute.ts +++ b/src/execute.ts @@ -1,5 +1,6 @@ import { type MemoryValue, When } from '@qavajs/core'; import { Locator } from '@playwright/test'; +import { QavajsPlaywrightWorld } from './QavajsPlaywrightWorld'; /** * Execute client function @@ -7,7 +8,7 @@ import { Locator } from '@playwright/test'; * @example I execute '$fn' function // fn is function reference * @example I execute 'window.scrollBy(0, 100)' function */ -When('I execute {value} function/script', async function (fn: MemoryValue) { +When('I execute {value} function/script', async function (this: QavajsPlaywrightWorld, fn: MemoryValue) { await this.playwright.page.evaluate(await fn.value()); }); @@ -18,7 +19,7 @@ When('I execute {value} function/script', async function (fn: MemoryValue) { * @example I execute '$fn' function and save result as 'result' // fn is function reference * @example I execute 'window.scrollY' function and save result as 'scroll' */ -When('I execute {value} function/script and save result as {value}', async function (fn: MemoryValue, memoryKey: MemoryValue) { +When('I execute {value} function/script and save result as {value}', async function (this: QavajsPlaywrightWorld, fn: MemoryValue, memoryKey: MemoryValue) { memoryKey.set(await this.playwright.page.evaluate(await fn.value())); }); @@ -29,7 +30,7 @@ When('I execute {value} function/script and save result as {value}', async funct * @example I execute '$fn' function on 'Component > Element' // fn is function reference * @example I execute 'arguments[0].scrollIntoView()' function on 'Component > Element' */ -When('I execute {value} function/script on {playwrightLocator}', async function (fnKey: MemoryValue, locator: Locator) { +When('I execute {value} function/script on {playwrightLocator}', async function (this: QavajsPlaywrightWorld, fnKey: MemoryValue, locator: Locator) { let fn = await fnKey.value(); if (typeof fn === 'string') { fn = new Function('return ' + fn) @@ -46,7 +47,7 @@ When('I execute {value} function/script on {playwrightLocator}', async function */ When( 'I execute {value} function/script on {playwrightLocator} and save result as {value}', - async function (fnKey: MemoryValue, locator: Locator, memoryKey: MemoryValue) { + async function (this: QavajsPlaywrightWorld, fnKey: MemoryValue, locator: Locator, memoryKey: MemoryValue) { let fn = await fnKey.value(); if (typeof fn === 'string') { fn = new Function('return ' + fn) diff --git a/src/hooks.ts b/src/hooks.ts index 36f66c8..e957195 100644 --- a/src/hooks.ts +++ b/src/hooks.ts @@ -19,12 +19,13 @@ import { createJSEngine } from './selectorEngines'; import playwright from './playwright'; import tracingManager from './utils/tracingManager'; import { element } from './pageObject'; +import { QavajsPlaywrightWorld } from './QavajsPlaywrightWorld'; BeforeAll(async function () { await createJSEngine(); }); -Before({ name: 'Init playwright driver' }, async function () { +Before({ name: 'Init playwright driver' }, async function (this: QavajsPlaywrightWorld) { const driverConfig = this.config.browser ?? this.config.driver; driverConfig.isElectron = driverConfig.capabilities.browserName === 'electron'; driverConfig.timeout = { @@ -42,7 +43,7 @@ Before({ name: 'Init playwright driver' }, async function () { this.element = element; }); -BeforeStep(async function (step) { +BeforeStep(async function (this: QavajsPlaywrightWorld, step) { try { if (tracingManager.isTracingStarted) { await tracingManager.tracing.group(step.pickleStep.text); @@ -57,7 +58,7 @@ BeforeStep(async function (step) { } }); -AfterStep(async function (step: ITestStepHookParameter) { +AfterStep(async function (this: QavajsPlaywrightWorld, step: ITestStepHookParameter) { try { if (tracingManager.isTracingStarted) { await tracingManager.tracing.groupEnd(); @@ -72,7 +73,7 @@ AfterStep(async function (step: ITestStepHookParameter) { } }); -After({ name: 'Shutdown playwright driver' }, async function (scenario: ITestCaseHookParameter) { +After({ name: 'Shutdown playwright driver' }, async function (this: QavajsPlaywrightWorld, scenario: ITestCaseHookParameter) { await tracingManager.stop(this.config.driverConfig, this, scenario); await this.playwright.teardown({ reuseSession:this.config.driverConfig.reuseSession, diff --git a/src/intercept.ts b/src/intercept.ts index cdf3e84..609f736 100644 --- a/src/intercept.ts +++ b/src/intercept.ts @@ -1,4 +1,5 @@ import { type MemoryValue, When } from '@qavajs/core'; +import { QavajsPlaywrightWorld } from './QavajsPlaywrightWorld'; /** * Create interception for url or predicate function @@ -7,7 +8,7 @@ import { type MemoryValue, When } from '@qavajs/core'; * @example I create interception for '**\/api/qavajs' as 'intercept' * @example I create interception for '$interceptHandler' as 'intercept' // if you need to pass function as interception handler */ -When('I create interception for {value} as {value}', async function (predicate: MemoryValue, key: MemoryValue) { +When('I create interception for {value} as {value}', async function (this: QavajsPlaywrightWorld, predicate: MemoryValue, key: MemoryValue) { key.set(this.playwright.page.waitForResponse(await predicate.value())) }); @@ -16,7 +17,7 @@ When('I create interception for {value} as {value}', async function (predicate: * @param {string} interception - key of saved interception promise * @example I wait for '$interception' response */ -When('I wait for {value} response', async function (interception: MemoryValue) { +When('I wait for {value} response', async function (this: QavajsPlaywrightWorld, interception: MemoryValue) { const interceptionPromise = await interception.value(); await interceptionPromise; }); @@ -26,7 +27,7 @@ When('I wait for {value} response', async function (interception: MemoryValue) { * @param {string} interception - key of saved interception promise * @example I save '$interception' response as 'response' */ -When('I save {value} response as {value}', async function (interception: MemoryValue, key: MemoryValue) { +When('I save {value} response as {value}', async function (this: QavajsPlaywrightWorld, interception: MemoryValue, key: MemoryValue) { const interceptionPromise = await interception.value(); key.set(await interceptionPromise); }); diff --git a/src/keyboardActions.ts b/src/keyboardActions.ts index 9d8f188..1e4226a 100644 --- a/src/keyboardActions.ts +++ b/src/keyboardActions.ts @@ -1,11 +1,12 @@ import { When } from '@qavajs/core'; +import { QavajsPlaywrightWorld } from './QavajsPlaywrightWorld'; /** * Press and hold keyboard key * @param {string} key - key to press * @example When I hold down 'Q' key */ -When('I hold down {string} key', async function (key) { +When('I hold down {string} key', async function (this: QavajsPlaywrightWorld, key) { await this.playwright.page.keyboard.down(key); }); @@ -14,6 +15,6 @@ When('I hold down {string} key', async function (key) { * @param {string} key - key to release * @example When I release 'A' key */ -When('I release {string} key', async function (key) { +When('I release {string} key', async function (this: QavajsPlaywrightWorld, key) { await this.playwright.page.keyboard.up(key); }); diff --git a/src/localSessionStorage.ts b/src/localSessionStorage.ts index 7524bc5..c45593d 100644 --- a/src/localSessionStorage.ts +++ b/src/localSessionStorage.ts @@ -1,4 +1,5 @@ import { type MemoryValue, When } from '@qavajs/core'; +import { QavajsPlaywrightWorld } from './QavajsPlaywrightWorld'; /** * Set value of local/session storage * @param {string} storageKey - local/session storage key to set value @@ -7,12 +8,12 @@ import { type MemoryValue, When } from '@qavajs/core'; * @example I set 'username' local storage value as 'user1' * @example I set '$sessionStorageKey' session storage value as '$sessionStorageValue' */ -When('I set {value} {word} storage value as {value}', async function (storageKey: MemoryValue, storageType: string, value: MemoryValue) { +When('I set {value} {word} storage value as {value}', async function (this: QavajsPlaywrightWorld, storageKey: MemoryValue, storageType: string, value: MemoryValue) { await this.playwright.page.evaluate(function ([storageKey, storageType, value]: [string, string, string]) { const storage: string = storageType + 'Storage'; // @ts-ignore window[storage].setItem(storageKey, value); - }, [await storageKey.value(), storageType, await value.value()]); + } as any, [await storageKey.value(), storageType, await value.value()]); }); /** @@ -23,11 +24,11 @@ When('I set {value} {word} storage value as {value}', async function (storageKey * @example I save value of 'username' local storage as 'localStorageValue' * @example I save value of '$sessionStorageKey' session storage value as 'sessionStorageValue' */ -When('I save value of {value} {word} storage as {value}', async function (storageKey, storageType, key) { +When('I save value of {value} {word} storage as {value}', async function (this: QavajsPlaywrightWorld, storageKey, storageType, key) { const value = await this.playwright.page.evaluate(function ([storageKey, storageType]: [string, string]) { const storage: string = storageType + 'Storage'; // @ts-ignore return window[storage].getItem(storageKey); - }, [await storageKey.value(), storageType]); + } as any, [await storageKey.value(), storageType]); key.set(value); }); diff --git a/src/memory.ts b/src/memory.ts index 07012c9..bee922a 100644 --- a/src/memory.ts +++ b/src/memory.ts @@ -1,5 +1,6 @@ import { type Locator } from '@playwright/test'; import { type MemoryValue, When } from '@qavajs/core'; +import { QavajsPlaywrightWorld } from './QavajsPlaywrightWorld'; /** * Save text of element to memory @@ -7,7 +8,7 @@ import { type MemoryValue, When } from '@qavajs/core'; * @param {string} key - key to store value * @example I save text of 'Search Results (1)' as 'firstSearchResult' */ -When('I save text of {playwrightLocator} as {value}', async function (locator: Locator, key: MemoryValue) { +When('I save text of {playwrightLocator} as {value}', async function (this: QavajsPlaywrightWorld, locator: Locator, key: MemoryValue) { key.set(await locator.innerText()); }); @@ -19,7 +20,7 @@ When('I save text of {playwrightLocator} as {value}', async function (locator: L * @example I save 'checked' property of 'Checkbox' as 'checked' * @example I save '$prop' property of 'Checkbox' as 'checked' */ -When('I save {value} property of {playwrightLocator} as {value}', async function (property: MemoryValue, locator: Locator, key: MemoryValue) { +When('I save {value} property of {playwrightLocator} as {value}', async function (this: QavajsPlaywrightWorld, property: MemoryValue, locator: Locator, key: MemoryValue) { const propertyName = await property.value(); const value = await locator.evaluate((node: any, propertyName: string) => node[propertyName], propertyName); key.set(value); @@ -33,7 +34,7 @@ When('I save {value} property of {playwrightLocator} as {value}', async function * @example I save 'href' attribute of 'Link' as 'linkHref' * @example I save '$prop' attribute of 'Link' as 'linkHref' */ -When('I save {value} attribute of {playwrightLocator} as {value}', async function (attribute: MemoryValue, locator: Locator, key: MemoryValue) { +When('I save {value} attribute of {playwrightLocator} as {value}', async function (this: QavajsPlaywrightWorld, attribute: MemoryValue, locator: Locator, key: MemoryValue) { const attributeName = await attribute.value(); const value = await locator.getAttribute(attributeName); key.set(value); @@ -45,7 +46,7 @@ When('I save {value} attribute of {playwrightLocator} as {value}', async functio * @param {string} key - key to store value * @example I save number of elements in 'Search Results' as 'numberOfSearchResults' */ -When('I save number of elements in {playwrightLocator} collection as {value}', async function (locator: Locator, key: MemoryValue) { +When('I save number of elements in {playwrightLocator} collection as {value}', async function (this: QavajsPlaywrightWorld, locator: Locator, key: MemoryValue) { const value = await locator.count(); key.set(value); }); @@ -58,7 +59,7 @@ When('I save number of elements in {playwrightLocator} collection as {value}', a */ When( 'I save text of every element of {playwrightLocator} collection as {value}', - async function (locator: Locator, key: MemoryValue) { + async function (this: QavajsPlaywrightWorld, locator: Locator, key: MemoryValue) { const values = await locator.evaluateAll( (collection: Array) => collection.map(e => e.innerText) ); @@ -74,7 +75,7 @@ When( */ When( 'I save {value} attribute of every element of {playwrightLocator} collection as {value}', - async function (attribute: MemoryValue, locator: Locator, key: MemoryValue) { + async function (this: QavajsPlaywrightWorld, attribute: MemoryValue, locator: Locator, key: MemoryValue) { const values = await locator.evaluateAll( (collection: Array, attr: string) => collection.map(e => e.attributes[attr].value), await attribute.value() @@ -91,7 +92,7 @@ When( */ When( 'I save {value} property of every element of {playwrightLocator} collection as {value}', - async function (property: MemoryValue, locator: Locator, key: MemoryValue) { + async function (this: QavajsPlaywrightWorld, property: MemoryValue, locator: Locator, key: MemoryValue) { const values = await locator.evaluateAll( (collection: Array, prop: string) => collection.map(e => e[prop]), await property.value() @@ -105,7 +106,7 @@ When( * @param {string} key - key to store value * @example I save current url as 'currentUrl' */ -When('I save current url as {value}', async function (key: MemoryValue) { +When('I save current url as {value}', async function (this: QavajsPlaywrightWorld, key: MemoryValue) { key.set(this.playwright.page.url()); }); @@ -114,7 +115,7 @@ When('I save current url as {value}', async function (key: MemoryValue) { * @param {string} key - key to store value * @example I save page title as 'currentTitle' */ -When('I save page title as {value}', async function (key: MemoryValue) { +When('I save page title as {value}', async function (this: QavajsPlaywrightWorld, key: MemoryValue) { key.set(await this.playwright.page.title()); }); @@ -157,7 +158,7 @@ When('I save screenshot of {playwrightLocator} as {value}', async function(locat * @example I save 'color' css property of 'Checkbox' as 'checkboxColor' * @example I save '$propertyName' property of 'Checkbox' as 'checkboxColor' */ -When('I save {value} css property of {playwrightLocator} as {value}', async function (property: MemoryValue, locator: Locator, key: MemoryValue) { +When('I save {value} css property of {playwrightLocator} as {value}', async function (this: QavajsPlaywrightWorld, property: MemoryValue, locator: Locator, key: MemoryValue) { const propertyName = await property.value(); const value = await locator.evaluate( (node: Element, propertyName: string) => getComputedStyle(node).getPropertyValue(propertyName), @@ -175,7 +176,7 @@ When('I save {value} css property of {playwrightLocator} as {value}', async func * When I save bounding rect of 'Node' as 'boundingRect' * Then I expect '$boundingRect.width' to equal '42' */ -When('I save bounding rect of {playwrightLocator} as {value}', async function (locator: Locator, key: MemoryValue) { +When('I save bounding rect of {playwrightLocator} as {value}', async function (this: QavajsPlaywrightWorld, locator: Locator, key: MemoryValue) { const value = await locator.evaluate((node: Element) => node.getBoundingClientRect()); key.set(value); }); diff --git a/src/mock.ts b/src/mock.ts index a1020ae..803cbdf 100644 --- a/src/mock.ts +++ b/src/mock.ts @@ -1,5 +1,6 @@ import { Route } from '@playwright/test'; import { type MemoryValue, When } from '@qavajs/core'; +import { QavajsPlaywrightWorld } from './QavajsPlaywrightWorld'; /** * Create simple mock instance @@ -8,7 +9,7 @@ import { type MemoryValue, When } from '@qavajs/core'; * @example When I create mock for '/yourservice/**' as 'mock1' * @example When I create mock for '$mockUrlTemplate' as 'mock1' */ -When('I create mock for {value} as {value}', async function (urlTemplate: MemoryValue, memoryKey: MemoryValue) { +When('I create mock for {value} as {value}', async function (this: QavajsPlaywrightWorld, urlTemplate: MemoryValue, memoryKey: MemoryValue) { const url = await urlTemplate.value(); memoryKey.set(url); }); @@ -60,7 +61,7 @@ When('I set {value} mock to respond {value} with {string}', respondWith); * When I create mock for '/yourservice/**' as 'myServiceMock' * And I set '$myServiceMock' mock to abort with 'Failed' reason */ -When('I set {value} mock to abort with {value} reason', async function (mockKey: MemoryValue, reason: MemoryValue) { +When('I set {value} mock to abort with {value} reason', async function (this: QavajsPlaywrightWorld, mockKey: MemoryValue, reason: MemoryValue) { const mockUrl: string = await mockKey.value(); const errorCode: string = await reason.value(); await this.playwright.page.route(mockUrl, async (route: Route) => { @@ -73,7 +74,7 @@ When('I set {value} mock to abort with {value} reason', async function (mockKey: * @param {string} mockKey - memory key to get mock instance * @example When I restore '$myServiceMock' */ -When('I restore {value} mock', async function (mockKey: MemoryValue) { +When('I restore {value} mock', async function (this: QavajsPlaywrightWorld, mockKey: MemoryValue) { const mockUrl: string = await mockKey.value(); await this.playwright.page.unroute(mockUrl); }); @@ -82,6 +83,6 @@ When('I restore {value} mock', async function (mockKey: MemoryValue) { * Restore all mocks * @example When I restore all mocks */ -When('I restore all mocks', async function () { - this.playwright.page._routes = []; +When('I restore all mocks', async function (this: QavajsPlaywrightWorld) { + (this.playwright.page as any)._routes = []; }); diff --git a/src/mouseActions.ts b/src/mouseActions.ts index 49f3730..83f5ab1 100644 --- a/src/mouseActions.ts +++ b/src/mouseActions.ts @@ -1,3 +1,4 @@ +import { QavajsPlaywrightWorld } from './QavajsPlaywrightWorld'; import { parseCoords } from './utils/utils'; import { type MemoryValue, When } from '@qavajs/core'; @@ -6,7 +7,7 @@ import { type MemoryValue, When } from '@qavajs/core'; * @param {string} button - button to press (left, right, middle) * @example When I press left mouse button */ -When('I press {playwrightMouseButton} mouse button', async function (button) { +When('I press {playwrightMouseButton} mouse button', async function (this: QavajsPlaywrightWorld, button: 'left' | 'right' | 'middle') { await this.playwright.page.mouse.down({ button }); }); @@ -15,7 +16,7 @@ When('I press {playwrightMouseButton} mouse button', async function (button) { * @param {string} button - button to release (left, right, middle) * @example When I release left mouse button */ -When('I release {playwrightMouseButton} mouse button', async function (button) { +When('I release {playwrightMouseButton} mouse button', async function (this: QavajsPlaywrightWorld, button: 'left' | 'right' | 'middle') { await this.playwright.page.mouse.up({ button }); }); @@ -24,7 +25,7 @@ When('I release {playwrightMouseButton} mouse button', async function (button) { * @param {string} coords - x, y coordinates to move * @example When I move mouse to '10, 15' */ -When('I move mouse to {value}', async function (coords: MemoryValue){ +When('I move mouse to {value}', async function (this: QavajsPlaywrightWorld, coords: MemoryValue){ const [x, y] = parseCoords(await coords.value()); await this.playwright.page.mouse.move(x, y); }); @@ -34,7 +35,7 @@ When('I move mouse to {value}', async function (coords: MemoryValue){ * @param {string} coords - x, y offset to scroll * @example When I scroll mouse wheel by '0, 15' */ -When('I scroll mouse wheel by {value}', async function (offset: MemoryValue) { +When('I scroll mouse wheel by {value}', async function (this: QavajsPlaywrightWorld, offset: MemoryValue) { const [x, y] = parseCoords(await offset.value()); await this.playwright.page.mouse.wheel(x, y); }); diff --git a/src/poDefine.ts b/src/poDefine.ts index 12243bc..fb6da7e 100644 --- a/src/poDefine.ts +++ b/src/poDefine.ts @@ -1,5 +1,6 @@ import { type MemoryValue, When } from '@qavajs/core'; import { locator } from './pageObject'; +import { QavajsPlaywrightWorld } from './QavajsPlaywrightWorld'; /** * Register selector as page object @@ -9,7 +10,7 @@ import { locator } from './pageObject'; * When I define '#someId' as 'My Button' locator * And I click 'My Button' */ -When('I define {value} as {value} locator', async function (selectorKey: MemoryValue, aliasKey: MemoryValue) { +When('I define {value} as {value} locator', async function (this: QavajsPlaywrightWorld, selectorKey: MemoryValue, aliasKey: MemoryValue) { const selector = await selectorKey.value(); const alias = (await aliasKey.value()).replace(/\s/g, ''); const pageObjectRef = this.config.pageObject.prototype ?? this.config.pageObject; diff --git a/src/validations.ts b/src/validations.ts index f6fde48..97a9b48 100644 --- a/src/validations.ts +++ b/src/validations.ts @@ -1,5 +1,6 @@ import { type Locator } from '@playwright/test'; import { type MemoryValue, type Validation, Then } from '@qavajs/core'; +import { QavajsPlaywrightWorld } from './QavajsPlaywrightWorld'; /** * Verify element condition @@ -9,7 +10,7 @@ import { type MemoryValue, type Validation, Then } from '@qavajs/core'; * @example I expect 'Loading' not to be present * @example I expect 'Search Bar > Submit Button' to be clickable */ -Then('I expect {playwrightLocator} {playwrightCondition}', async function (locator: Locator, condition: any) { +Then('I expect {playwrightLocator} {playwrightCondition}', async function (this: QavajsPlaywrightWorld, locator: Locator, condition: any) { await condition(locator, this.config.browser.timeout.page); }); @@ -22,7 +23,7 @@ Then('I expect {playwrightLocator} {playwrightCondition}', async function (locat */ Then( 'I expect text of {playwrightLocator} {validation} {value}', - async function (locator: Locator, validation: Validation, expected: MemoryValue) { + async function (this: QavajsPlaywrightWorld, locator: Locator, validation: Validation, expected: MemoryValue) { const expectedValue = await expected.value(); const timeout = this.config.browser.timeout.value; const interval = this.config.browser.timeout.valueInterval; @@ -40,7 +41,7 @@ Then( */ Then( 'I expect value of {playwrightLocator} {validation} {value}', - async function (locator: Locator, validation: Validation, expected: MemoryValue) { + async function (this: QavajsPlaywrightWorld, locator: Locator, validation: Validation, expected: MemoryValue) { const expectedValue = await expected.value(); const timeout = this.config.browser.timeout.value; const interval = this.config.browser.timeout.valueInterval; @@ -60,7 +61,7 @@ Then( */ Then( 'I expect {value} property of {playwrightLocator} {validation} {value}', - async function (property: MemoryValue, locator: Locator, validation: Validation, expected: MemoryValue) { + async function (this: QavajsPlaywrightWorld, property: MemoryValue, locator: Locator, validation: Validation, expected: MemoryValue) { const propertyName = await property.value(); const expectedValue = await expected.value(); const timeout = this.config.browser.timeout.value; @@ -81,7 +82,7 @@ Then( */ Then( 'I expect {value} attribute of {playwrightLocator} {validation} {value}', - async function (attribute: MemoryValue, locator: Locator, validation: Validation, expected: MemoryValue) { + async function (this: QavajsPlaywrightWorld, attribute: MemoryValue, locator: Locator, validation: Validation, expected: MemoryValue) { const attributeName = await attribute.value(); const expectedValue = await expected.value(); const timeout = this.config.browser.timeout.value; @@ -100,7 +101,7 @@ Then( */ Then( 'I expect current url {validation} {value}', - async function (validation: Validation, expected: MemoryValue) { + async function (this: QavajsPlaywrightWorld, validation: Validation, expected: MemoryValue) { const expectedUrl = await expected.value(); const timeout = this.config.browser.timeout.value; const interval = this.config.browser.timeout.valueInterval; @@ -120,7 +121,7 @@ Then( */ Then( 'I expect number of elements in {playwrightLocator} collection {validation} {value}', - async function (locator: Locator, validation: Validation, expected: MemoryValue) { + async function (this: QavajsPlaywrightWorld, locator: Locator, validation: Validation, expected: MemoryValue) { const expectedValue = await expected.value(); const timeout = this.config.browser.timeout.value; const interval = this.config.browser.timeout.valueInterval; @@ -137,7 +138,7 @@ Then( */ Then( 'I expect page title {validation} {value}', - async function (validation: Validation, expected: MemoryValue) { + async function (this: QavajsPlaywrightWorld, validation: Validation, expected: MemoryValue) { const expectedTitle = await expected.value(); const timeout = this.config.browser.timeout.value; const interval = this.config.browser.timeout.valueInterval; @@ -153,7 +154,7 @@ Then( * @example I expect every element in 'Header > Links' collection to be visible * @example I expect every element in 'Loading Bars' collection not to be present */ -Then('I expect every element in {playwrightLocator} collection {playwrightCondition}', async function (locator: Locator, condition: any) { +Then('I expect every element in {playwrightLocator} collection {playwrightCondition}', async function (this: QavajsPlaywrightWorld, locator: Locator, condition: any) { const conditionWait = (element: Locator) => condition(element, this.config.browser.timeout.page); for (let i = 0; i < await locator.count(); i++) { await conditionWait(locator.nth(i)); @@ -170,7 +171,7 @@ Then('I expect every element in {playwrightLocator} collection {playwrightCondit */ Then( 'I expect text of every element in {playwrightLocator} collection {validation} {value}', - async function (locator: Locator, validation: Validation, expected: MemoryValue) { + async function (this: QavajsPlaywrightWorld, locator: Locator, validation: Validation, expected: MemoryValue) { const expectedValue = await expected.value(); const interval = this.config.browser.timeout.valueInterval; for (let i = 0; i < await locator.count(); i++) { @@ -189,7 +190,7 @@ Then( */ Then( 'I expect {value} attribute of every element in {playwrightLocator} collection {validation} {value}', - async function (attribute: MemoryValue, locator: Locator, validation: Validation, expected: MemoryValue) { + async function (this: QavajsPlaywrightWorld, attribute: MemoryValue, locator: Locator, validation: Validation, expected: MemoryValue) { const expectedValue = await expected.value(); const attributeName = await attribute.value(); const interval = this.config.browser.timeout.valueInterval; @@ -209,7 +210,7 @@ Then( */ Then( 'I expect {value} property of every element in {playwrightLocator} collection {validation} {value}', - async function (property: MemoryValue, locator: Locator, validation: Validation, expected: MemoryValue) { + async function (this: QavajsPlaywrightWorld, property: MemoryValue, locator: Locator, validation: Validation, expected: MemoryValue) { const expectedValue = await expected.value(); const propertyName = await property.value(); const interval = this.config.browser.timeout.valueInterval; @@ -235,7 +236,7 @@ Then( */ Then( 'I expect {value} css property of {playwrightLocator} {validation} {value}', - async function (property: MemoryValue, locator: Locator, validation: Validation, expected: MemoryValue) { + async function (this: QavajsPlaywrightWorld, property: MemoryValue, locator: Locator, validation: Validation, expected: MemoryValue) { const propertyName = await property.value(); const expectedValue = await expected.value(); const timeout = this.config.browser.timeout.value; @@ -260,7 +261,7 @@ Then( */ Then( 'I expect {value} css property of every element in {playwrightLocator} collection {validation} {value}', - async function (property: MemoryValue, collection: Locator, validation: Validation, expected: MemoryValue) { + async function (this: QavajsPlaywrightWorld, property: MemoryValue, collection: Locator, validation: Validation, expected: MemoryValue) { const propertyName = await property.value(); const expectedValue = await expected.value(); const timeout = this.config.browser.timeout.value; diff --git a/src/waits.ts b/src/waits.ts index 2366a4c..71404cf 100644 --- a/src/waits.ts +++ b/src/waits.ts @@ -1,5 +1,6 @@ import { type Locator } from '@playwright/test'; import { type MemoryValue, type Validation, When } from '@qavajs/core'; +import { QavajsPlaywrightWorld } from './QavajsPlaywrightWorld'; /** * Refresh page unless element matches condition @@ -12,7 +13,7 @@ import { type MemoryValue, type Validation, When } from '@qavajs/core'; */ When( 'I refresh page until {playwrightLocator} {playwrightCondition}( ){playwrightTimeout}', - async function (locator: Locator, condition: any, timeoutValue: number | null) { + async function (this: QavajsPlaywrightWorld, locator: Locator, condition: any, timeoutValue: number | null) { const timeout = timeoutValue ?? this.config.browser.timeout.value; await this.playwright.expect(async () => { await this.playwright.page.reload() @@ -33,7 +34,7 @@ When( */ When( 'I refresh page until text of {playwrightLocator} {validation} {value}( ){playwrightTimeout}', - async function (locator: Locator, validation: Validation, expected: MemoryValue, timeoutValue?: number) { + async function (this: QavajsPlaywrightWorld, locator: Locator, validation: Validation, expected: MemoryValue, timeoutValue?: number) { const expectedValue = await expected.value(); await validation.poll(async () => { await this.playwright.page.reload(); @@ -57,7 +58,7 @@ When( */ When( 'I click {playwrightLocator} until text of {playwrightLocator} {validation} {value}( ){playwrightTimeout}', - async function ( + async function (this: QavajsPlaywrightWorld, locatorToClick: Locator, locatorToCheck: Locator, validation: Validation, @@ -91,7 +92,7 @@ When( */ When( 'I click {playwrightLocator} until value of {playwrightLocator} {validation} {value}( ){playwrightTimeout}', - async function ( + async function (this: QavajsPlaywrightWorld, locatorToClick: Locator, locatorToCheck: Locator, validation: Validation, @@ -118,7 +119,7 @@ When( * @param {number} ms - milliseconds * @example I wait 1000 ms */ -When('I wait {int} ms', async function (ms) { +When('I wait {int} ms', async function (this: QavajsPlaywrightWorld, ms) { await new Promise((resolve: Function): void => { setTimeout(() => resolve(), ms) }); @@ -129,7 +130,7 @@ When('I wait {int} ms', async function (ms) { * @param {number} timeout - wait condition * @example I wait for network idle for 1000 ms */ -When('I wait for network idle {playwrightTimeout}', async function (timeoutValue: number | null) { +When('I wait for network idle {playwrightTimeout}', async function (this: QavajsPlaywrightWorld, timeoutValue: number | null) { const timeout = timeoutValue ?? this.config.browser.timeout.networkIdle ?? 500 return new Promise((resolve) => { let timerId: any = setTimeout(() => { diff --git a/test-e2e/step-definitions/index.ts b/test-e2e/step-definitions/index.ts index ecf278d..057f64d 100644 --- a/test-e2e/step-definitions/index.ts +++ b/test-e2e/step-definitions/index.ts @@ -1,20 +1,21 @@ import { expect, Route } from '@playwright/test'; import { existsSync } from 'node:fs'; import { Then, type MemoryValue, type Validation } from '@qavajs/core'; +import { QavajsPlaywrightWorld } from '../../index'; -Then('I expect {value} memory value {validation} {value}', async function (actual: MemoryValue, validation: Validation, expected: MemoryValue) { +Then('I expect {value} memory value {validation} {value}', async function (this: QavajsPlaywrightWorld, actual: MemoryValue, validation: Validation, expected: MemoryValue) { validation( await actual.value(), await expected.value() ); }); -Then('I expect viewport size to equal {value}', async function (expectedSize: MemoryValue) { +Then('I expect viewport size to equal {value}', async function (this: QavajsPlaywrightWorld, expectedSize: MemoryValue) { const actualValue = this.playwright.page.viewportSize(); expect(actualValue).toEqual(await expectedSize.value()); }) -Then('I set {int} ms delayed mock for {string} request', async function (delay: number, glob: string) { +Then('I set {int} ms delayed mock for {string} request', async function (this: QavajsPlaywrightWorld, delay: number, glob: string) { await this.playwright.page.route(glob, async (route: Route) => { setTimeout(async () => await route.fulfill({ status: 200, @@ -24,7 +25,7 @@ Then('I set {int} ms delayed mock for {string} request', async function (delay: }); }) -Then('I expect file {value} to exist', async function (path: MemoryValue){ +Then('I expect file {value} to exist', async function (this: QavajsPlaywrightWorld, path: MemoryValue){ const filePresence = existsSync(await path.value()); expect(filePresence).toBeTruthy(); }); diff --git a/test-e2e/tsconfig.json b/test-e2e/tsconfig.json new file mode 100644 index 0000000..7c3c734 --- /dev/null +++ b/test-e2e/tsconfig.json @@ -0,0 +1,19 @@ +{ + "include": [ + "./**/*.ts" + ], + "compilerOptions": { + "target": "es2022", + "module": "node16", + "moduleResolution": "node16", + "outDir": "./lib", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "sourceMap": true, + "types": [ + "node" + ] + } +}