Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Test
on:
pull_request:
branches:
- master
- main

jobs:
build:
Expand All @@ -15,4 +15,4 @@ jobs:
node-version: 16
- run: npm ci
- run: npm run build
- run: npm run test
- run: npm run test:e2e
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
node_modules/
lib/
coverage/
test-e2e/report.xml
1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ test/
node_modules/
.github/
coverage/
test-e2e/
11,611 changes: 5,058 additions & 6,553 deletions package-lock.json

Large diffs are not rendered by default.

15 changes: 10 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
{
"name": "@qavajs/steps-playwright",
"version": "0.0.1",
"version": "0.0.2",
"description": "steps to interact with playwright",
"main": "./index.js",
"scripts": {
"build": "tsc",
"test": "jest --coverage"
"test": "jest --coverage",
"test:e2e": "ts-node node_modules/.bin/qavajs run --config test-e2e/webui.ts"
},
"repository": {
"type": "git",
Expand All @@ -21,16 +22,20 @@
"homepage": "https://github.com/qavajs/steps-playwright#readme",
"devDependencies": {
"@cucumber/cucumber": "^8.2.2",
"@qavajs/cli": "^0.0.9",
"@qavajs/po": "^1.0.2",
"@qavajs/xunit-formatter": "^0.0.1",
"@types/chai": "^4.3.1",
"@types/jest": "^28.1.4",
"jest": "^28.1.2",
"ts-jest": "^28.0.5"
"ts-jest": "^28.0.5",
"ts-node": "^10.9.1"
},
"dependencies": {
"@playwright/test": "^1.26.1",
"@playwright/test": "^1.27.1",
"@qavajs/memory": "^1.1.0",
"@qavajs/po-playwright": "^0.0.1",
"@qavajs/validation": "^0.0.2",
"playwright": "^1.26.1"
"playwright": "^1.27.1"
}
}
128 changes: 127 additions & 1 deletion src/actions.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { When } from '@cucumber/cucumber';
import { Locator } from 'playwright';
import { getValue, getElement } from './transformers';
import { po } from '@qavajs/po-playwright';

/**
* Opens provided url
Expand Down Expand Up @@ -33,3 +33,129 @@ When('I click {string}', async function (alias: string) {
const element = await getElement(alias);
await element.click();
});

/**
* Right click element
* @param {string} alias - element to right click
* @example I right click 'Google Button'
*/
When('I right click {string}', async function (alias: string) {
const element = await getElement(alias);
await element.click({button: 'right'});
});

/**
* Double click element
* @param {string} alias - double element to click
* @example I double click 'Google Button'
*/
When('I double click {string}', async function (alias: string) {
const element = await getElement(alias);
await element.dblclick();
});

/**
* Clear input
* @param {string} alias - element to clear
* @example I clear 'Google Input'
*/
When('I clear {string}', async function (alias: string) {
const element = await getElement(alias);
await element.fill('');
});

/**
* Switch to parent frame
* @example I switch to parent frame
*/
When('I switch to parent frame', async function () {
// @ts-ignore
po.driver = page;
});

/**
* Switch to frame by index
* @param {number} index - index to switch
* @example I switch to 2 frame
*/
When('I switch to {int} frame', async function (index: number) {
// @ts-ignore
po.driver = page.frames()[index];
});

/**
* Switch to window by index
* @param {number} index - index to switch
* @example I switch to 2 window
*/
When('I switch to {int} window', async function (index: number) {
global.context = browser.contexts()[index - 1];
global.page = context.pages()[index - 1];
//@ts-ignore
po.driver = page;
});

/**
* Refresh current page
* @example I refresh page
*/
When('I refresh page', async function () {
await page.reload();
});

/**
* Press button
* @param {string} key - key to press
* @example I press 'Enter' key
*/
When('I press {string} key', async function (key: string) {
await page.press('body', key);
});

/**
* Hover over element
* @param {string} alias - element to hover over
* @example I hover over 'Google Button'
*/
When('I hover over {string}', async function (alias: string) {
const element = await getElement(alias);
await element.hover();
});

/**
* Select option with certain text from select element
* @param {string} option - option to select
* @param {string} alias - alias of select
* @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 {string} option from {string} dropdown', async function (option: string, alias: string) {
const optionValue = await getValue(option);
const select = await getElement(alias);
await select.selectOption({ label: optionValue });
});

/**
* Select option with certain text from select element
* @param {number} optionIndex - index of option to select
* @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 {string} dropdown', async function (optionIndex: number, alias: string) {
const select = await getElement(alias);
await select.selectOption({ index: optionIndex - 1 });
});

/**
* Click on element with desired text in collection
* @param {string} expectedText - text to click
* @param {string} alias - collection to search text
* @example I click 'google' text in 'Search Engines' collection
*/
When(
'I click {string} text in {string} collection',
async function (value: string, alias: string) {
const collection = await getElement(alias);
await collection.getByText(value).click();
}
);
157 changes: 157 additions & 0 deletions src/validations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,160 @@ Then(
validation(elementText, expectedValue);
}
);

/**
* Verify that property of element satisfies condition
* @param {string} property - element to verify
* @param {string} alias - element to verify
* @param {string} validationType - validation
* @param {string} value - expected value
* @example I expect 'value' property of 'Search Input' to be equal 'text'
* @example I expect 'innerHTML' property of 'Label' to contain '<b>'
*/
Then(
'I expect {string} property of {string} {playwrightValidation} {string}',
async function (property: string, alias: string, validationType: string, value: string) {
const propertyName = await getValue(property);
const expectedValue = await getValue(value);
const element = await getElement(alias);
const validation = getValidation(validationType);
const actualValue = await element.evaluate((node: any, propertyName: string) => node[propertyName], propertyName);
validation(actualValue, expectedValue);
}
);

/**
* Verify that attribute of element satisfies condition
* @param {string} attribute - element to verify
* @param {string} alias - element to verify
* @param {string} validationType - validation
* @param {string} value - expected value
* @example I expect 'href' attribute of 'Home Link' to contain '/home'
*/
Then(
'I expect {string} attribute of {string} {playwrightValidation} {string}',
async function (attribute: string, alias: string, validationType: string, value: string) {
const attributeName = await getValue(attribute);
const expectedValue = await getValue(value);
const element = await getElement(alias);
const validation = getValidation(validationType);
const actualValue = await element.getAttribute(attributeName);
validation(actualValue, expectedValue);
}
);

/**
* Verify that current url satisfies condition
* @param {string} validationType - validation
* @param {string} expected - expected value
* @example I expect current url contains 'wikipedia'
* @example I expect current url equals 'https://wikipedia.org'
*/
Then(
'I expect current url {playwrightValidation} {string}',
async function (validationType: string, expected: string) {
const validation = getValidation(validationType);
const expectedUrl = await getValue(expected);
const actualUrl = page.url();
validation(actualUrl, expectedUrl);
}
);

/**
* Verify that number of element in collection satisfies condition
* @param {string} alias - collection to verify
* @param {string} validationType - validation
* @param {string} value - expected value
* @example I expect number of elements in 'Search Results' collection to be equal '50'
* @example I expect number of elements in 'Search Results' collection to be above '49'
* @example I expect number of elements in 'Search Results' collection to be below '51'
*/
Then(
'I expect number of elements in {string} collection {playwrightValidation} {string}',
async function (alias: string, validationType: string, value: string) {
const expectedValue = await getValue(value);
const collection = await getElement(alias);
const validation = getValidation(validationType);
validation(await collection.count(), expectedValue);
}
);

/**
* Verify that page title satisfies condition
* @param {string} validationType - validation
* @param {string} expected - expected value
* @example I expect page title equals 'Wikipedia'
*/
Then(
'I expect page title {playwrightValidation} {string}',
async function (validationType: string, expected: string) {
const validation = getValidation(validationType);
const expectedTitle = await getValue(expected);
const actualTitle = await page.title();
validation(actualTitle, expectedTitle);
}
);

/**
* Verify that all texts in collection satisfy condition
* @param {string} alias - collection to get texts
* @param {string} validationType - validation
* @param {string} value - expected result
* @example I expect text of every element in 'Search Results' collection equals to 'google'
* @example I expect text of every element in 'Search Results' collection does not contain 'yandex'
*/
Then(
'I expect text of every element in {string} collection {playwrightValidation} {string}',
async function (alias: string, validationType: string, value: string) {
const expectedValue = await getValue(value);
const collection = await getElement(alias);
const validation = getValidation(validationType);
for (let i = 0; i < await collection.count(); i++) {
const elementText: string = await collection.nth(i).innerText();
validation(elementText, expectedValue);
}
}
);

/**
* Verify that all particular attributes in collection satisfy condition
* @param {string} alias - collection to get attrs
* @param {string} validationType - validation
* @param {string} value - expected result
* @example I expect 'href' attribute of every element in 'Search Results' collection to contain 'google'
*/
Then(
'I expect {string} attribute of every element in {string} collection {playwrightValidation} {string}',
async function (attribute: string, alias: string, validationType: string, value: string) {
const expectedValue = await getValue(value);
const collection = await getElement(alias);
const validation = getValidation(validationType);
for (let i = 0; i < await collection.count(); i++) {
const attributeValue: string | null = await collection.nth(i).getAttribute(attribute);
validation(attributeValue, expectedValue);
}
}
);

/**
* Verify that all particular properties in collection satisfy condition
* @param {string} alias - collection to get props
* @param {string} validationType - validation
* @param {string} value - expected result
* @example I expect 'href' property of every element in 'Search Results' collection to contain 'google'
*/
Then(
'I expect {string} property of every element in {string} collection {playwrightValidation} {string}',
async function (property: string, alias: string, validationType: string, value: string) {
const expectedValue = await getValue(value);
const collection = await getElement(alias);
const validation = getValidation(validationType);
for (let i = 0; i < await collection.count(); i++) {
const propertyValue: string | null = await collection.nth(i).evaluate(
(node: any, property: string) => node[property], property
);
validation(propertyValue, expectedValue);
}
}
);

Loading