Skip to content

Commit

Permalink
add privacy policy tests (automation suite) (#2378)
Browse files Browse the repository at this point in the history
* Fix privacy policy test

* Remove test.only

* Fix store & withdraw flaky issues

* Fix flakiness of storelist & singlestore tests

* Refactor some methods

* Fix a flaky test
  • Loading branch information
shashwatahalder01 authored Sep 24, 2024
1 parent 4ce4e2d commit e73c5df
Show file tree
Hide file tree
Showing 14 changed files with 79 additions and 64 deletions.
6 changes: 6 additions & 0 deletions tests/pw/pages/basePage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,12 @@ export class BasePage {
return response;
}

// select by value and wait for response and load state
async selectByValueAndWaitForResponseAndLoadState(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.waitForLoadState(), this.page.selectOption(selector, { value })]);
return response;
}

// select by label and wait for response
async selectByLabelAndWaitForResponse(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, { label: value })]);
Expand Down
4 changes: 4 additions & 0 deletions tests/pw/pages/customerPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ export class CustomerPage extends BasePage {
await this.goIfNotThere(data.subUrls.frontend.storeListing);
}

async gotoSingleStore(storeName: string): Promise<void> {
await this.goIfNotThere(data.subUrls.frontend.vendorDetails(helpers.slugify(storeName)), 'networkidle');
}

async goToProductDetails(productName: string): Promise<void> {
await this.goIfNotThere(data.subUrls.frontend.productDetails(helpers.slugify(productName)));
}
Expand Down
15 changes: 9 additions & 6 deletions tests/pw/pages/privacyPolicyPage.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Page } from '@playwright/test';
import { BasePage } from '@pages/basePage';
import { CustomerPage } from './customerPage';
import { selector } from '@pages/selectors';
import { helpers } from '@utils/helpers';
import { data } from '@utils/testData';
Expand All @@ -8,14 +8,17 @@ import { storeContactData } from '@utils/interfaces';
// selectors
const singleStoreCustomer = selector.customer.cSingleStore;

export class PrivacyPolicyPage extends BasePage {
export class PrivacyPolicyPage extends CustomerPage {
constructor(page: Page) {
super(page);
}

// contact vendor
async contactVendor(storeName: string, storeContactData: storeContactData) {
await this.goIfNotThere(data.subUrls.frontend.vendorDetails(helpers.slugify(storeName)));
await this.toPass(async () => {
await this.gotoUntilNetworkidle(data.subUrls.frontend.vendorDetails(helpers.slugify(storeName)));
await this.toBeVisible(singleStoreCustomer.storeContactForm.storeContactForm);
});
await this.clearAndType(singleStoreCustomer.storeContactForm.name, storeContactData.name);
await this.clearAndType(singleStoreCustomer.storeContactForm.email, storeContactData.email);
await this.clearAndType(singleStoreCustomer.storeContactForm.message, storeContactData.message);
Expand All @@ -25,7 +28,7 @@ export class PrivacyPolicyPage extends BasePage {

// go to privacy policy
async goToPrivacyPolicy(storeName: string) {
await this.goIfNotThere(data.subUrls.frontend.vendorDetails(helpers.slugify(storeName)));
await this.gotoSingleStore(storeName);
// ensure link suppose to open on new tab
await this.toHaveAttribute(singleStoreCustomer.storeContactForm.privacyPolicyLink, 'target', '_blank');
// force link to open on the same tab
Expand All @@ -34,12 +37,12 @@ export class PrivacyPolicyPage extends BasePage {
}

async disablePrivacyPolicy(storeName: string) {
await this.goIfNotThere(data.subUrls.frontend.vendorDetails(helpers.slugify(storeName)));
await this.gotoUntilNetworkidle(data.subUrls.frontend.vendorDetails(helpers.slugify(storeName)));
await this.notToBeVisible(singleStoreCustomer.storeContactForm.privacyPolicy);
}

async disableStoreContactForm(storeName: string) {
await this.goto(data.subUrls.frontend.vendorDetails(helpers.slugify(storeName)));
await this.gotoUntilNetworkidle(data.subUrls.frontend.vendorDetails(helpers.slugify(storeName)));
await this.notToBeVisible(singleStoreCustomer.storeContactForm.storeContactForm);
}
}
8 changes: 4 additions & 4 deletions tests/pw/pages/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7268,10 +7268,10 @@ export const selector = {
},

storeContactForm: {
storeContactForm: '#dokan-form-contact-seller',
name: '//form[@id="dokan-form-contact-seller"]//input[@placeholder="Your Name"]',
email: '//form[@id="dokan-form-contact-seller"]//input[@placeholder="you@example.com"]',
message: '//form[@id="dokan-form-contact-seller"]//textarea[@name="message"]',
storeContactForm: 'form#dokan-form-contact-seller',
name: 'form#dokan-form-contact-seller input[placeholder="Your Name"]',
email: 'form#dokan-form-contact-seller input[placeholder="you@example.com"]',
message: 'form#dokan-form-contact-seller textarea[name="message"]',
sendMessage: 'input[name="store_message_send"]',
successMessage: 'div.alert.alert-success',
privacyPolicy: 'div.dokan-privacy-policy-text p',
Expand Down
28 changes: 2 additions & 26 deletions tests/pw/pages/settingsPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,35 +269,11 @@ export class SettingsPage extends AdminPage {
}

// Admin Set Dokan MenuManager Settings
async setDokanMenuManagerSettings(menuManager: dokanSettings['menuManager']) {
async setDokanMenuManagerSettings(menus: string[]) {
await this.goToDokanSettings();
await this.click(settingsAdmin.menus.menuManager);

const menus = [
'Products',
'Orders',
'Request Quotes',
'Coupons',
'Reports',
'Delivery Time',
'Reviews',
'Withdraw',
'Reverse Withdrawal',
'Badge',
'Product Q&A',
'Return Request',
'Staff',
'Followers',
// 'Subscription',
'Booking',
'Announcements',
'Analytics',
'Tools',
'Auction',
'Support',
];

// menumanager Settings
// menuManager Settings
for (const menu of menus) {
await this.enableSwitcher(settingsAdmin.menuManager.menuSwitcher(menu));
}
Expand Down
15 changes: 8 additions & 7 deletions tests/pw/pages/singleStorePage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export class SingleStorePage extends CustomerPage {
// single store render properly
async singleStoreRenderProperly(storeName: string) {
// todo: update for other layouts
await this.goIfNotThere(data.subUrls.frontend.vendorDetails(helpers.slugify(storeName)));
await this.gotoSingleStore(storeName);

// store profile elements are visible
const { verifiedIcon, verifiedIconByIcon, euComplianceData, ...storeProfile } = singleStoreCustomer.storeProfile;
Expand Down Expand Up @@ -59,21 +59,22 @@ export class SingleStorePage extends CustomerPage {

// sort products on single store
async singleStoreSortProducts(storeName: string, sortBy: string) {
await this.goIfNotThere(data.subUrls.frontend.vendorDetails(helpers.slugify(storeName)));
await this.selectByValueAndWaitForResponse(data.subUrls.frontend.vendorDetails(helpers.slugify(storeName)), singleStoreCustomer.sortBy, sortBy);
await this.gotoSingleStore(storeName);
await this.selectByValueAndWaitForResponseAndLoadState(data.subUrls.frontend.vendorDetails(helpers.slugify(storeName)), singleStoreCustomer.sortBy, sortBy);
await this.notToHaveCount(singleStoreCustomer.productCard.card, 0);
}

// search product on single store
async singleStoreSearchProduct(storeName: string, productName: string): Promise<void> {
await this.goIfNotThere(data.subUrls.frontend.vendorDetails(helpers.slugify(storeName)));
await this.gotoSingleStore(storeName);
await this.clearAndType(singleStoreCustomer.search.input, productName);
await this.clickAndWaitForResponse(data.subUrls.frontend.vendorDetails(helpers.slugify(storeName)), singleStoreCustomer.search.button);
await this.toContainText(singleStoreCustomer.productCard.productTitle, productName);
}

// store open close
async storeOpenCloseTime(storeName: string): Promise<void> {
await this.goIfNotThere(data.subUrls.frontend.vendorDetails(helpers.slugify(storeName)));
await this.gotoSingleStore(storeName);
await this.hover(singleStoreCustomer.storeTime.storeTimeDropDown);

await this.toBeVisible(singleStoreCustomer.storeTime.storeTimeDiv);
Expand All @@ -85,14 +86,14 @@ export class SingleStorePage extends CustomerPage {

// store terms and condition
async storeTermsAndCondition(storeName: string, toc: string): Promise<void> {
await this.goIfNotThere(data.subUrls.frontend.vendorDetails(helpers.slugify(storeName)));
await this.gotoSingleStore(storeName);
await this.clickAndWaitForResponse(data.subUrls.frontend.vendorDetails(helpers.slugify(storeName)), singleStoreCustomer.storeTabs.toc);
await this.toContainText(singleStoreCustomer.toc.tocContent, toc);
}

// store share
async storeShare(storeName: string, site: string): Promise<void> {
await this.goIfNotThere(data.subUrls.frontend.vendorDetails(helpers.slugify(storeName)));
await this.gotoSingleStore(storeName);
await this.click(singleStoreCustomer.storeTabs.share);
// ensure link suppose to open on new tab
await this.toHaveAttribute(singleStoreCustomer.sharePlatForms[site as keyof typeof singleStoreCustomer.sharePlatForms], 'target', '_blank');
Expand Down
17 changes: 8 additions & 9 deletions tests/pw/pages/storeListingPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export class StoreListingPage extends CustomerPage {
if (link) {
await this.goto(link);
} else {
await this.goIfNotThere(data.subUrls.frontend.storeListing);
await this.gotoUntilNetworkidle(data.subUrls.frontend.storeListing);
// store list text is visible
await this.toBeVisible(storeList.storeListText);
}
Expand Down Expand Up @@ -70,13 +70,14 @@ export class StoreListingPage extends CustomerPage {

// sort store
async sortStores(sortBy: string) {
await this.goIfNotThere(data.subUrls.frontend.storeListing);
await this.selectByValueAndWaitForResponse(data.subUrls.frontend.storeListing, storeList.filters.sortBy, sortBy);
await this.goToStoreList();
await this.selectByValueAndWaitForResponseAndLoadState(data.subUrls.frontend.storeListing, storeList.filters.sortBy, sortBy);
await this.notToHaveCount(storeList.storeCard.storeCardDiv, 0);
}

// store view layout
async storeViewLayout(style: string) {
await this.goIfNotThere(data.subUrls.frontend.storeListing);
await this.goToStoreList();

switch (style) {
case 'grid':
Expand All @@ -95,7 +96,7 @@ export class StoreListingPage extends CustomerPage {

// search store
async searchStore(storeName: string): Promise<void> {
await this.goIfNotThere(data.subUrls.frontend.storeListing);
await this.goToStoreList();
await this.click(storeList.filters.filterButton);
await this.clearAndType(storeList.filters.filterDetails.searchVendor, storeName);
await this.clickAndWaitForResponse(data.subUrls.frontend.storeListing, storeList.filters.filterDetails.apply);
Expand All @@ -104,15 +105,13 @@ export class StoreListingPage extends CustomerPage {

// filter stores
async filterStores(filterBy: string, value?: string): Promise<void> {
await this.goIfNotThere(data.subUrls.frontend.storeListing);
await this.goToStoreList();
await this.click(storeList.filters.filterButton);

switch (filterBy) {
case 'by-location':
await this.typeAndWaitForResponse(data.subUrls.gmap, storeList.filters.filterDetails.location, value!);
await this.click(storeList.mapResultFirst);
// await this.press(data.key.arrowDown);
// await this.pressAndWaitForResponse(data.subUrls.gmap, data.key.enter);
break;

case 'by-category':
Expand Down Expand Up @@ -142,7 +141,7 @@ export class StoreListingPage extends CustomerPage {

// stores on map
async storeOnMap(storeName?: string) {
await this.goIfNotThere(data.subUrls.frontend.storeListing);
await this.goToStoreList();
const storePinIsVisible = await this.isVisible(storeList.map.storeOnMap.storePin);
if (storePinIsVisible) {
await this.click(storeList.map.storeOnMap.storePin);
Expand Down
1 change: 1 addition & 0 deletions tests/pw/pages/withdrawsPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ export class WithdrawsPage extends AdminPage {
default:
break;
}
await this.notToBeVisible(withdrawsAdmin.withdrawCell(vendorName));
}

// withdraw bulk action
Expand Down
7 changes: 2 additions & 5 deletions tests/pw/tests/e2e/privacyPolicy.spec.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,31 @@
import { test, request, Page } from '@playwright/test';
import { PrivacyPolicyPage } from '@pages/privacyPolicyPage';
// import { CustomerPage } from '@pages/customerPage';
import { ApiUtils } from '@utils/apiUtils';
import { dbUtils } from '@utils/dbUtils';
import { data } from '@utils/testData';
import { dbData } from '@utils/dbData';

test.describe.skip('Privacy Policy & Store Contact form test', () => {
test.describe('Privacy Policy & Store Contact form test', () => {
let customer: PrivacyPolicyPage;
// let customerPage: CustomerPage;
let cPage: Page;
let apiUtils: ApiUtils;

test.beforeAll(async ({ browser }) => {
const customerContext = await browser.newContext(data.auth.customerAuth);
cPage = await customerContext.newPage();
// customerPage = new CustomerPage(cPage);
customer = new PrivacyPolicyPage(cPage);
apiUtils = new ApiUtils(await request.newContext());
});

test.afterAll(async () => {
await dbUtils.updateOptionValue(dbData.dokan.optionName.privacyPolicy, { enable_privacy: 'on' });
await dbUtils.updateOptionValue(dbData.dokan.optionName.appearance, { contact_seller: 'on' });
await dbUtils.setOptionValue('sidebars_widgets', dbData.widget.emptySideBarsWidgets);
await cPage.close();
await apiUtils.dispose();
});

test('customer can contact vendor', { tag: ['@lite', '@customer'] }, async () => {
await dbUtils.updateOptionValue('sidebars_widgets', { sidebars_widgets: [] });
await customer.contactVendor(data.predefined.vendorStores.vendor1, data.storeContactData);
});

Expand Down
3 changes: 3 additions & 0 deletions tests/pw/tests/e2e/productAdvertising.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,20 +86,23 @@ test.describe('Product Advertising test (vendor)', () => {
// vendor

test('vendor can buy product advertising (product list page)', { tag: ['@pro', '@vendor'] }, async () => {
test.slow();
const [, , productName] = await apiUtils.createProduct(payloads.createProduct(), payloads.vendorAuth);
const orderId = await vendor.buyProductAdvertising(productName, 'simple');
await apiUtils.updateOrderStatus(orderId, 'wc-completed', payloads.adminAuth);
await vendor.assertProductAdvertisementIsBought(productName, 'simple');
});

test('vendor can buy booking product advertising', { tag: ['@pro', '@vendor'] }, async () => {
test.slow();
const [, , productName] = await apiUtils.createBookableProduct(payloads.createBookableProduct(), payloads.vendorAuth);
const orderId = await vendor.buyProductAdvertising(productName, 'booking', BookingPage);
await apiUtils.updateOrderStatus(orderId, 'wc-completed', payloads.adminAuth);
await vendor.assertProductAdvertisementIsBought(productName, 'booking', BookingPage);
});

test('vendor can buy auction product advertising', { tag: ['@pro', '@vendor'] }, async () => {
test.slow();
const [, , productName] = await apiUtils.createProduct(payloads.createAuctionProduct(), payloads.vendorAuth);
const orderId = await vendor.buyProductAdvertising(productName, 'auction', AuctionsPage);
await apiUtils.updateOrderStatus(orderId, 'wc-completed', payloads.adminAuth);
Expand Down
2 changes: 1 addition & 1 deletion tests/pw/tests/e2e/settings.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ test.describe('Settings test', () => {
});

test('admin can set Dokan menu manager settings', { tag: ['@pro', '@admin'] }, async () => {
await admin.setDokanMenuManagerSettings(data.dokanSettings.menuManager);
await admin.setDokanMenuManagerSettings(data.dokanSettings.menuManager.menus);
});

test('admin can set Dokan privacy policy settings', { tag: ['@lite', '@admin'] }, async () => {
Expand Down
3 changes: 1 addition & 2 deletions tests/pw/tests/e2e/singleStore.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ test.describe('Single store functionality test', () => {
await customer.singleStoreSortProducts(data.predefined.vendorStores.vendor1, 'price');
});

test.skip('customer can view store terms and conditions', { tag: ['@lite', '@customer'] }, async () => {
// todo: pre need toc on store and admin settings
test('customer can view store terms and conditions', { tag: ['@lite', '@customer'] }, async () => {
await customer.storeTermsAndCondition(data.predefined.vendorStores.vendor1, data.vendor.toc);
});

Expand Down
11 changes: 7 additions & 4 deletions tests/pw/utils/dbData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -753,7 +753,7 @@ export const dbData = {
},
privacyPolicySettings: {
enable_privacy: 'on',
privacy_page: '2',
privacy_page: '',
privacy_policy: '<p>Your personal data will be used to support your experience throughout this website, to manage access to your account, and for other purposes described in our [dokan_privacy_policy]</p>',
},

Expand Down Expand Up @@ -1327,9 +1327,11 @@ export const dbData = {
},
_multiwidget: 1,
},

// 'dokan-store-contact-widget-2', 'dokan-best-selling-widget-2', 'dokan-category-menu-2', 'dokan-filter-product-2', 'dokan-store-location-2', 'dokan-store-menu-2', 'dokan-store-open-close-widget-2', 'dokan-top-rated-2',
sideBarsWidgets: {
wp_inactive_widgets: ['block-8', 'block-2', 'block-3', 'block-4', 'block-5', 'block-6'],
'sidebar-store': ['dokan-category-menu-2', 'dokan-store-location-2', 'dokan-store-contact-widget-2'],
wp_inactive_widgets: [],
'sidebar-store': ['dokan-store-contact-widget-2'],
'sidebar-1': [],
'header-1': [],
'footer-1': [],
Expand All @@ -1338,7 +1340,8 @@ export const dbData = {
'footer-4': [],
array_version: 3,
},
multiwidget: { _multiwidget: 1 },

emptySideBarsWidgets: { wp_inactive_widgets: [] },
},

// test db data
Expand Down
23 changes: 23 additions & 0 deletions tests/pw/utils/testData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1963,6 +1963,29 @@ export const data = {

// menuManager
menuManager: {
menus: [
'Products',
'Orders',
'Request Quotes',
'Coupons',
'Reports',
'Delivery Time',
'Reviews',
'Withdraw',
'Reverse Withdrawal',
'Badge',
'Product Q&A',
'Return Request',
'Staff',
'Followers',
// 'Subscription',
'Booking',
'Announcements',
'Analytics',
'Tools',
'Auction',
'Support',
],
settingTitle: 'Menu Manager Settings',
saveSuccessMessage: 'Setting has been saved successfully.',
},
Expand Down

0 comments on commit e73c5df

Please sign in to comment.