Skip to content

Commit b29001c

Browse files
Merge pull request #2 from qavajs/new-steps
implemented new actions and validation steps
2 parents c0ea85a + d329942 commit b29001c

File tree

20 files changed

+5796
-6565
lines changed

20 files changed

+5796
-6565
lines changed

.github/workflows/pull-request.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name: Test
33
on:
44
pull_request:
55
branches:
6-
- master
6+
- main
77

88
jobs:
99
build:
@@ -15,4 +15,4 @@ jobs:
1515
node-version: 16
1616
- run: npm ci
1717
- run: npm run build
18-
- run: npm run test
18+
- run: npm run test:e2e

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
node_modules/
22
lib/
33
coverage/
4+
test-e2e/report.xml

.npmignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ test/
22
node_modules/
33
.github/
44
coverage/
5+
test-e2e/

package-lock.json

Lines changed: 5058 additions & 6553 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
{
22
"name": "@qavajs/steps-playwright",
3-
"version": "0.0.1",
3+
"version": "0.0.2",
44
"description": "steps to interact with playwright",
55
"main": "./index.js",
66
"scripts": {
77
"build": "tsc",
8-
"test": "jest --coverage"
8+
"test": "jest --coverage",
9+
"test:e2e": "ts-node node_modules/.bin/qavajs run --config test-e2e/webui.ts"
910
},
1011
"repository": {
1112
"type": "git",
@@ -21,16 +22,20 @@
2122
"homepage": "https://github.com/qavajs/steps-playwright#readme",
2223
"devDependencies": {
2324
"@cucumber/cucumber": "^8.2.2",
25+
"@qavajs/cli": "^0.0.9",
26+
"@qavajs/po": "^1.0.2",
27+
"@qavajs/xunit-formatter": "^0.0.1",
2428
"@types/chai": "^4.3.1",
2529
"@types/jest": "^28.1.4",
2630
"jest": "^28.1.2",
27-
"ts-jest": "^28.0.5"
31+
"ts-jest": "^28.0.5",
32+
"ts-node": "^10.9.1"
2833
},
2934
"dependencies": {
30-
"@playwright/test": "^1.26.1",
35+
"@playwright/test": "^1.27.1",
3136
"@qavajs/memory": "^1.1.0",
3237
"@qavajs/po-playwright": "^0.0.1",
3338
"@qavajs/validation": "^0.0.2",
34-
"playwright": "^1.26.1"
39+
"playwright": "^1.27.1"
3540
}
3641
}

src/actions.ts

Lines changed: 127 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { When } from '@cucumber/cucumber';
2-
import { Locator } from 'playwright';
32
import { getValue, getElement } from './transformers';
3+
import { po } from '@qavajs/po-playwright';
44

55
/**
66
* Opens provided url
@@ -33,3 +33,129 @@ When('I click {string}', async function (alias: string) {
3333
const element = await getElement(alias);
3434
await element.click();
3535
});
36+
37+
/**
38+
* Right click element
39+
* @param {string} alias - element to right click
40+
* @example I right click 'Google Button'
41+
*/
42+
When('I right click {string}', async function (alias: string) {
43+
const element = await getElement(alias);
44+
await element.click({button: 'right'});
45+
});
46+
47+
/**
48+
* Double click element
49+
* @param {string} alias - double element to click
50+
* @example I double click 'Google Button'
51+
*/
52+
When('I double click {string}', async function (alias: string) {
53+
const element = await getElement(alias);
54+
await element.dblclick();
55+
});
56+
57+
/**
58+
* Clear input
59+
* @param {string} alias - element to clear
60+
* @example I clear 'Google Input'
61+
*/
62+
When('I clear {string}', async function (alias: string) {
63+
const element = await getElement(alias);
64+
await element.fill('');
65+
});
66+
67+
/**
68+
* Switch to parent frame
69+
* @example I switch to parent frame
70+
*/
71+
When('I switch to parent frame', async function () {
72+
// @ts-ignore
73+
po.driver = page;
74+
});
75+
76+
/**
77+
* Switch to frame by index
78+
* @param {number} index - index to switch
79+
* @example I switch to 2 frame
80+
*/
81+
When('I switch to {int} frame', async function (index: number) {
82+
// @ts-ignore
83+
po.driver = page.frames()[index];
84+
});
85+
86+
/**
87+
* Switch to window by index
88+
* @param {number} index - index to switch
89+
* @example I switch to 2 window
90+
*/
91+
When('I switch to {int} window', async function (index: number) {
92+
global.context = browser.contexts()[index - 1];
93+
global.page = context.pages()[index - 1];
94+
//@ts-ignore
95+
po.driver = page;
96+
});
97+
98+
/**
99+
* Refresh current page
100+
* @example I refresh page
101+
*/
102+
When('I refresh page', async function () {
103+
await page.reload();
104+
});
105+
106+
/**
107+
* Press button
108+
* @param {string} key - key to press
109+
* @example I press 'Enter' key
110+
*/
111+
When('I press {string} key', async function (key: string) {
112+
await page.press('body', key);
113+
});
114+
115+
/**
116+
* Hover over element
117+
* @param {string} alias - element to hover over
118+
* @example I hover over 'Google Button'
119+
*/
120+
When('I hover over {string}', async function (alias: string) {
121+
const element = await getElement(alias);
122+
await element.hover();
123+
});
124+
125+
/**
126+
* Select option with certain text from select element
127+
* @param {string} option - option to select
128+
* @param {string} alias - alias of select
129+
* @example I select '1900' option from 'Registration Form > Date Of Birth'
130+
* @example I select '$dateOfBirth' option from 'Registration Form > Date Of Birth' dropdown
131+
*/
132+
When('I select {string} option from {string} dropdown', async function (option: string, alias: string) {
133+
const optionValue = await getValue(option);
134+
const select = await getElement(alias);
135+
await select.selectOption({ label: optionValue });
136+
});
137+
138+
/**
139+
* Select option with certain text from select element
140+
* @param {number} optionIndex - index of option to select
141+
* @param {string} alias - alias of select
142+
* @example I select 1 option from 'Registration Form > Date Of Birth' dropdown
143+
*/
144+
When('I select {int}(st|nd|rd|th) option from {string} dropdown', async function (optionIndex: number, alias: string) {
145+
const select = await getElement(alias);
146+
await select.selectOption({ index: optionIndex - 1 });
147+
});
148+
149+
/**
150+
* Click on element with desired text in collection
151+
* @param {string} expectedText - text to click
152+
* @param {string} alias - collection to search text
153+
* @example I click 'google' text in 'Search Engines' collection
154+
*/
155+
When(
156+
'I click {string} text in {string} collection',
157+
async function (value: string, alias: string) {
158+
const collection = await getElement(alias);
159+
await collection.getByText(value).click();
160+
}
161+
);

src/validations.ts

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,160 @@ Then(
3434
validation(elementText, expectedValue);
3535
}
3636
);
37+
38+
/**
39+
* Verify that property of element satisfies condition
40+
* @param {string} property - element to verify
41+
* @param {string} alias - element to verify
42+
* @param {string} validationType - validation
43+
* @param {string} value - expected value
44+
* @example I expect 'value' property of 'Search Input' to be equal 'text'
45+
* @example I expect 'innerHTML' property of 'Label' to contain '<b>'
46+
*/
47+
Then(
48+
'I expect {string} property of {string} {playwrightValidation} {string}',
49+
async function (property: string, alias: string, validationType: string, value: string) {
50+
const propertyName = await getValue(property);
51+
const expectedValue = await getValue(value);
52+
const element = await getElement(alias);
53+
const validation = getValidation(validationType);
54+
const actualValue = await element.evaluate((node: any, propertyName: string) => node[propertyName], propertyName);
55+
validation(actualValue, expectedValue);
56+
}
57+
);
58+
59+
/**
60+
* Verify that attribute of element satisfies condition
61+
* @param {string} attribute - element to verify
62+
* @param {string} alias - element to verify
63+
* @param {string} validationType - validation
64+
* @param {string} value - expected value
65+
* @example I expect 'href' attribute of 'Home Link' to contain '/home'
66+
*/
67+
Then(
68+
'I expect {string} attribute of {string} {playwrightValidation} {string}',
69+
async function (attribute: string, alias: string, validationType: string, value: string) {
70+
const attributeName = await getValue(attribute);
71+
const expectedValue = await getValue(value);
72+
const element = await getElement(alias);
73+
const validation = getValidation(validationType);
74+
const actualValue = await element.getAttribute(attributeName);
75+
validation(actualValue, expectedValue);
76+
}
77+
);
78+
79+
/**
80+
* Verify that current url satisfies condition
81+
* @param {string} validationType - validation
82+
* @param {string} expected - expected value
83+
* @example I expect current url contains 'wikipedia'
84+
* @example I expect current url equals 'https://wikipedia.org'
85+
*/
86+
Then(
87+
'I expect current url {playwrightValidation} {string}',
88+
async function (validationType: string, expected: string) {
89+
const validation = getValidation(validationType);
90+
const expectedUrl = await getValue(expected);
91+
const actualUrl = page.url();
92+
validation(actualUrl, expectedUrl);
93+
}
94+
);
95+
96+
/**
97+
* Verify that number of element in collection satisfies condition
98+
* @param {string} alias - collection to verify
99+
* @param {string} validationType - validation
100+
* @param {string} value - expected value
101+
* @example I expect number of elements in 'Search Results' collection to be equal '50'
102+
* @example I expect number of elements in 'Search Results' collection to be above '49'
103+
* @example I expect number of elements in 'Search Results' collection to be below '51'
104+
*/
105+
Then(
106+
'I expect number of elements in {string} collection {playwrightValidation} {string}',
107+
async function (alias: string, validationType: string, value: string) {
108+
const expectedValue = await getValue(value);
109+
const collection = await getElement(alias);
110+
const validation = getValidation(validationType);
111+
validation(await collection.count(), expectedValue);
112+
}
113+
);
114+
115+
/**
116+
* Verify that page title satisfies condition
117+
* @param {string} validationType - validation
118+
* @param {string} expected - expected value
119+
* @example I expect page title equals 'Wikipedia'
120+
*/
121+
Then(
122+
'I expect page title {playwrightValidation} {string}',
123+
async function (validationType: string, expected: string) {
124+
const validation = getValidation(validationType);
125+
const expectedTitle = await getValue(expected);
126+
const actualTitle = await page.title();
127+
validation(actualTitle, expectedTitle);
128+
}
129+
);
130+
131+
/**
132+
* Verify that all texts in collection satisfy condition
133+
* @param {string} alias - collection to get texts
134+
* @param {string} validationType - validation
135+
* @param {string} value - expected result
136+
* @example I expect text of every element in 'Search Results' collection equals to 'google'
137+
* @example I expect text of every element in 'Search Results' collection does not contain 'yandex'
138+
*/
139+
Then(
140+
'I expect text of every element in {string} collection {playwrightValidation} {string}',
141+
async function (alias: string, validationType: string, value: string) {
142+
const expectedValue = await getValue(value);
143+
const collection = await getElement(alias);
144+
const validation = getValidation(validationType);
145+
for (let i = 0; i < await collection.count(); i++) {
146+
const elementText: string = await collection.nth(i).innerText();
147+
validation(elementText, expectedValue);
148+
}
149+
}
150+
);
151+
152+
/**
153+
* Verify that all particular attributes in collection satisfy condition
154+
* @param {string} alias - collection to get attrs
155+
* @param {string} validationType - validation
156+
* @param {string} value - expected result
157+
* @example I expect 'href' attribute of every element in 'Search Results' collection to contain 'google'
158+
*/
159+
Then(
160+
'I expect {string} attribute of every element in {string} collection {playwrightValidation} {string}',
161+
async function (attribute: string, alias: string, validationType: string, value: string) {
162+
const expectedValue = await getValue(value);
163+
const collection = await getElement(alias);
164+
const validation = getValidation(validationType);
165+
for (let i = 0; i < await collection.count(); i++) {
166+
const attributeValue: string | null = await collection.nth(i).getAttribute(attribute);
167+
validation(attributeValue, expectedValue);
168+
}
169+
}
170+
);
171+
172+
/**
173+
* Verify that all particular properties in collection satisfy condition
174+
* @param {string} alias - collection to get props
175+
* @param {string} validationType - validation
176+
* @param {string} value - expected result
177+
* @example I expect 'href' property of every element in 'Search Results' collection to contain 'google'
178+
*/
179+
Then(
180+
'I expect {string} property of every element in {string} collection {playwrightValidation} {string}',
181+
async function (property: string, alias: string, validationType: string, value: string) {
182+
const expectedValue = await getValue(value);
183+
const collection = await getElement(alias);
184+
const validation = getValidation(validationType);
185+
for (let i = 0; i < await collection.count(); i++) {
186+
const propertyValue: string | null = await collection.nth(i).evaluate(
187+
(node: any, property: string) => node[property], property
188+
);
189+
validation(propertyValue, expectedValue);
190+
}
191+
}
192+
);
193+

0 commit comments

Comments
 (0)