Skip to content

Commit

Permalink
Add new tests & update flaky tests (#2365)
Browse files Browse the repository at this point in the history
* Fix couple of pro flaky test

* Fix product qa flaky issues

* Fix a failed test

* Fix some flaky tests

* Fix locator issues

* Add a test and base methods

* Update test tag

* Fix the testdata issue

* fix failed booking tests

* Fix couple of flaky tests

* Update some tests
  • Loading branch information
shashwatahalder01 authored Sep 10, 2024
1 parent 616b620 commit 656056f
Show file tree
Hide file tree
Showing 37 changed files with 335 additions and 107 deletions.
5 changes: 4 additions & 1 deletion tests/pw/e2e.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,10 @@ export default defineConfig({
/* Size of viewport */
// viewport: { width: 1420, height: 900 }, // default 1280x720
/* whether to slow down test execution by provided seconds */
launchOptions: { slowMo: (SLOWMO ?? 0) * 1000 },
launchOptions: {
slowMo: (SLOWMO ?? 0) * 1000,
// devtools: true,
},
},

projects: [
Expand Down
2 changes: 2 additions & 0 deletions tests/pw/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
"pw:deps-only": "playwright install-deps chromium",
"test": "npx playwright test",
"test:site:setup": "npx playwright test --project=local_site_setup --config=e2e.config.ts",
"test:env:setup": "npx playwright test --project=e2e_setup --config=e2e.config.ts",
"test:site:reset": "NO_SETUP=false npm run test:site:setup && npm run test:env:setup",
"test:api": "npx playwright test --project=api_tests --config=api.config.ts",
"test:e2e": "npx playwright test --project=e2e_tests --config=e2e.config.ts",
"test:api:pro": "DOKAN_PRO=true npx playwright test --project=api_tests --config=api.config.ts",
Expand Down
13 changes: 8 additions & 5 deletions tests/pw/pages/abuseReportsPage.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Page, expect } from '@playwright/test';
import { Page } from '@playwright/test';
import { AdminPage } from '@pages/adminPage';
import { selector } from '@pages/selectors';
import { helpers } from '@utils/helpers';
Expand Down Expand Up @@ -27,7 +27,7 @@ export class AbuseReportsPage extends AdminPage {
await this.multipleElementVisible(abuseReportAdmin.bulkActions);

// filter elements are visible
const { filterInput, ...filters } = abuseReportAdmin.filters;
const { filterInput, reset, filteredResult, ...filters } = abuseReportAdmin.filters;
await this.multipleElementVisible(filters);

// abuse report table elements are visible
Expand All @@ -46,7 +46,7 @@ export class AbuseReportsPage extends AdminPage {

// filter abuse reports
async filterAbuseReports(input: string, action: string) {
await this.goIfNotThere(data.subUrls.backend.dokan.abuseReports);
await this.goto(data.subUrls.backend.dokan.abuseReports);

switch (action) {
case 'by-reason':
Expand All @@ -56,20 +56,23 @@ export class AbuseReportsPage extends AdminPage {
case 'by-product':
await this.click(abuseReportAdmin.filters.filterByProduct);
await this.typeAndWaitForResponse(data.subUrls.api.wc.products, abuseReportAdmin.filters.filterInput, input);
await this.pressAndWaitForResponse(data.subUrls.api.dokan.abuseReports, data.key.enter);
await this.clickAndWaitForResponse(data.subUrls.api.dokan.abuseReports, abuseReportAdmin.filters.filteredResult(input));
break;

case 'by-vendor':
await this.click(abuseReportAdmin.filters.filterByVendors);
await this.typeAndWaitForResponse(data.subUrls.api.dokan.stores, abuseReportAdmin.filters.filterInput, input);
await this.pressAndWaitForResponse(data.subUrls.api.dokan.abuseReports, data.key.enter);
await this.clickAndWaitForResponse(data.subUrls.api.dokan.abuseReports, abuseReportAdmin.filters.filteredResult(input));
break;

default:
break;
}
await this.notToHaveText(abuseReportAdmin.numberOfRowsFound, '0 items');
await this.notToBeVisible(abuseReportAdmin.noRowsFound);

//clear filter
await this.clickAndWaitForResponse(data.subUrls.api.dokan.abuseReports, abuseReportAdmin.filters.reset);
}

// abuse report bulk action
Expand Down
1 change: 1 addition & 0 deletions tests/pw/pages/announcementsPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export class AnnouncementsPage extends AdminPage {
// edit announcement
async editAnnouncement(announcement: announcement) {
await this.goto(data.subUrls.backend.dokan.announcements);
await this.toBeVisible(announcementsAdmin.announcementCell(announcement.title));
await this.hover(announcementsAdmin.announcementCell(announcement.title));
await this.clickAndWaitForResponseAndLoadState(data.subUrls.api.dokan.announcements, announcementsAdmin.announcementEdit(announcement.title));
await this.updateAnnouncementFields(announcement);
Expand Down
65 changes: 58 additions & 7 deletions tests/pw/pages/basePage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,12 @@ export class BasePage {
return value;
}

// set element css style property
async setElementCssStyle(selector: string, property: string, value: string): Promise<void> {
const element = this.getElement(selector);
await element.evaluate((element, [property, value]) => ((element.style as any)[property as string] = value), [property, value]);
}

// get element property value
async getElementPropertyValue(selector: string, property: string): Promise<string> {
const element = this.getElement(selector);
Expand Down Expand Up @@ -736,8 +742,11 @@ export class BasePage {

// check input fields [checkbox/radio]
async check(selector: string): Promise<void> {
await this.checkLocator(selector);
// await this.checkByPage(selector);
await this.toPass(async () => {
await this.checkLocator(selector);
await this.toBeChecked(selector, { timeout: 200 });
// await this.checkByPage(selector);
});
}

// check input fields [checkbox/radio]
Expand All @@ -758,6 +767,14 @@ export class BasePage {
}
}

// check if not checked
async checkIfNotChecked(selector: string): Promise<void> {
const isChecked = await this.isCheckedLocator(selector);
if (isChecked) {
await this.check(selector);
}
}

/**
* Input field methods
*/
Expand Down Expand Up @@ -791,7 +808,7 @@ export class BasePage {
return await this.page.selectOption(selector, { index: Number(value) });
}

// select by valid and wait for response
// select by value and wait for response
async selectByValueAndWaitForResponse(subUrl: string, selector: string, value: string, code = 200): Promise<Response> {
const [response] = await Promise.all([this.page.waitForResponse(resp => resp.url().includes(subUrl) && resp.status() === code), this.page.selectOption(selector, { value })]);
return response;
Expand All @@ -803,6 +820,27 @@ export class BasePage {
return response;
}

// get select value
async getSelectedValue(selector: string): Promise<string> {
const locator = this.page.locator(selector);
const selectValue = await locator.evaluate((select: HTMLSelectElement) => select.value);
return selectValue;
}

// get select text
async getSelectedText(selector: string): Promise<string | undefined> {
const locator = this.page.locator(selector);
const selectedText = await locator.evaluate((select: HTMLSelectElement) => select.options[select.selectedIndex]?.text);
return selectedText;
}

// get select value and test
async getSelectedValueAndText(selector: string): Promise<(string | undefined)[]> {
const locator = this.page.locator(selector);
const [selectValue, selectedText] = await locator.evaluate((select: HTMLSelectElement) => [select.value, select.options[select.selectedIndex]?.text]);
return [selectValue, selectedText];
}

/**
* Files & Media methods
*/
Expand Down Expand Up @@ -1373,14 +1411,19 @@ export class BasePage {
expect(received).toEqual(expected);
}

// assert element to be enabled
async toBeEnabled(selector: string, options?: { timeout?: number; visible?: boolean } | undefined) {
await expect(this.page.locator(selector)).toBeEnabled(options);
}

// assert element to be visible
async toBeVisible(selector: string, options?: { timeout?: number; visible?: boolean } | undefined) {
await expect(this.page.locator(selector)).toBeVisible(options);
}

// assert checkbox to be checked
async toBeChecked(selector: string) {
await expect(this.page.locator(selector)).toBeChecked();
async toBeChecked(selector: string, options?: { checked?: boolean; timeout?: number } | undefined) {
await expect(this.page.locator(selector)).toBeChecked(options);
}

// assert element to have text
Expand All @@ -1389,8 +1432,8 @@ export class BasePage {
}

// assert element to contain text
async toContainText(selector: string, text: string | RegExp) {
await expect(this.page.locator(selector)).toContainText(text);
async toContainText(selector: string, text: string | RegExp, options?: { ignoreCase?: boolean; timeout?: number; useInnerText?: boolean } | undefined) {
await expect(this.page.locator(selector)).toContainText(text, options);
}

// assert element to have count
Expand All @@ -1413,6 +1456,14 @@ export class BasePage {
await expect(this.page.locator(selector)).toHaveClass(className);
}

// assert select element to have value
async toHaveSelectedValue(selector: string, value: string, options?: { timeout?: number; intervals?: number[] }) {
await this.toPass(async () => {
const selectedValue = await this.getSelectedValue(selector);
expect(selectedValue).toBe(value);
}, options);
}

// assert element to have background color
async toHaveBackgroundColor(selector: string, backgroundColor: string, options?: { timeout?: number; intervals?: number[] }) {
await this.toPass(async () => {
Expand Down
5 changes: 2 additions & 3 deletions tests/pw/pages/customerPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,11 +228,10 @@ export class CustomerPage extends BasePage {
if (addonIsVisible) await this.selectByNumber(selector.customer.cSingleProduct.productAddon.addOnSelect, 1);
if (quantity) await this.clearAndType(selector.customer.cSingleProduct.productDetails.quantity, String(quantity));
await this.clickAndWaitForResponse(data.subUrls.frontend.productCustomerPage, selector.customer.cSingleProduct.productDetails.addToCart);
await this.toBeVisible(selector.customer.cWooSelector.wooCommerceSuccessMessage);
if (!quantity) {
await this.toContainText(selector.customer.cWooSelector.wooCommerceSuccessMessage, `“${productName}” has been added to your cart.`);
await this.toBeVisible(selector.customer.cSingleProduct.productDetails.productAddedSuccessMessage(productName));
} else {
await this.toContainText(selector.customer.cWooSelector.wooCommerceSuccessMessage, `${quantity} × “${productName}” have been added to your cart.`);
await this.toBeVisible(selector.customer.cSingleProduct.productDetails.productWithQuantityAddedSuccessMessage(productName, quantity));
}
}

Expand Down
4 changes: 2 additions & 2 deletions tests/pw/pages/privacyPolicyPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ export class PrivacyPolicyPage extends BasePage {
// go to privacy policy
async goToPrivacyPolicy(storeName: string) {
await this.goIfNotThere(data.subUrls.frontend.vendorDetails(helpers.slugify(storeName)));
// ensure page suppose to open on new tab
// ensure link suppose to open on new tab
await this.toHaveAttribute(singleStoreCustomer.storeContactForm.privacyPolicyLink, 'target', '_blank');
// force page to open on the same tab
// force link to open on the same tab
await this.setAttributeValue(singleStoreCustomer.storeContactForm.privacyPolicyLink, 'target', '_self');
await this.clickAndWaitForUrl(helpers.stringToRegex('privacy-policy'), singleStoreCustomer.storeContactForm.privacyPolicyLink);
}
Expand Down
6 changes: 3 additions & 3 deletions tests/pw/pages/productAdvertisingPage.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Page, expect } from '@playwright/test';
import { Page } from '@playwright/test';
import { AdminPage } from '@pages/adminPage';
import { selector } from '@pages/selectors';
import { data } from '@utils/testData';
Expand Down Expand Up @@ -57,7 +57,7 @@ export class ProductAdvertisingPage extends AdminPage {

// add new product advertisement
async addNewProductAdvertisement(advertising: productAdvertisement) {
await this.goIfNotThere(data.subUrls.backend.dokan.productAdvertising);
await this.goto(data.subUrls.backend.dokan.productAdvertising);

await this.click(productAdvertisingAdmin.addNewProductAdvertising);

Expand All @@ -80,7 +80,7 @@ export class ProductAdvertisingPage extends AdminPage {

// search advertised product
async searchAdvertisedProduct(searchKey: string | number) {
await this.goIfNotThere(data.subUrls.backend.dokan.productAdvertising);
await this.goto(data.subUrls.backend.dokan.productAdvertising);

await this.clearInputField(productAdvertisingAdmin.search);

Expand Down
Loading

0 comments on commit 656056f

Please sign in to comment.