Skip to content

Commit

Permalink
Merge pull request #440 from Progi1984/boContactsPage
Browse files Browse the repository at this point in the history
Migrate `@pages/BO/shopParameters/contact` from Core
  • Loading branch information
Progi1984 authored Feb 26, 2025
2 parents b215200 + 6b715cb commit d776ccd
Show file tree
Hide file tree
Showing 4 changed files with 323 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ export {default as boCatalogPriceRulesPage} from '@pages/BO/catalog/discounts/ca
export {default as boCatalogPriceRulesCreatePage} from '@pages/BO/catalog/discounts/catalogPriceRules/create';
export {default as boCategoriesPage} from '@pages/BO/catalog/categories';
export {default as boCategoriesCreatePage} from '@pages/BO/catalog/categories/create';
export {default as boContactsPage} from '@pages/BO/shopParameters/contacts';
export {default as boCountriesPage} from '@pages/BO/international/locations/countries';
export {default as boCountriesCreatePage} from '@pages/BO/international/locations/countries/create';
export {default as boCMSPageCategoriesCreatePage} from '@pages/BO/design/pages/category/create';
Expand Down
19 changes: 19 additions & 0 deletions src/interfaces/BO/shopParameters/contacts/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {BOBasePagePageInterface} from '@interfaces/BO';
import {type Page} from '@playwright/test';

export interface BOContactsPageInterface extends BOBasePagePageInterface {
readonly pageTitle: string;

deleteContact(page: Page, row: number): Promise<string>;
deleteContactsBulkActions(page: Page): Promise<string>;
filterContacts(page: Page, filterBy: string, value?: string): Promise<void>;
getAllRowsColumnContent(page: Page, column: string): Promise<string[]>;
getNumberOfElementInGrid(page: Page): Promise<number>;
getTextColumnFromTableContacts(page: Page, row: number, column: string): Promise<string>;
goToAddNewContactPage(page: Page): Promise<void>;
goToEditContactPage(page: Page, row: number): Promise<void>;
goToStoresPage(page: Page): Promise<void>;
resetAndGetNumberOfLines(page: Page): Promise<number>;
resetFilter(page: Page): Promise<void>;
sortTable(page: Page, sortBy: string, sortDirection?: string): Promise<void>;
}
9 changes: 9 additions & 0 deletions src/pages/BO/shopParameters/contacts/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type {BOContactsPageInterface} from '@interfaces/BO/shopParameters/contacts';

/* eslint-disable global-require, @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires */
function requirePage(): BOContactsPageInterface {
return require('@versions/develop/pages/BO/shopParameters/contacts');
}
/* eslint-enable global-require, @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires */

export default requirePage();
294 changes: 294 additions & 0 deletions src/versions/develop/pages/BO/shopParameters/contacts/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,294 @@
import {type BOContactsPageInterface} from '@interfaces/BO/shopParameters/contacts';
import BOBasePage from '@pages/BO/BOBasePage';
import {type Page} from '@playwright/test';

/**
* Contacts page, contains functions that can be used on the page
* @class
* @extends BOBasePage
*/
class BOContactsPage extends BOBasePage implements BOContactsPageInterface {
public readonly pageTitle: string;

private readonly storesTabLink: string;

private readonly addNewContactButton: string;

private readonly contactsGridPanel: string;

private readonly contactsGridTitle: string;

private readonly contactsListForm: string;

private readonly contactsListTableRow: (row: number) => string;

private readonly contactsListTableColumn: (row: number, column: string) => string;

private readonly contactFilterInput: (filterBy: string) => string;

private readonly filterSearchButton: string;

private readonly filterResetButton: string;

private readonly contactsListTableActionsColumn: (row: number) => string;

private readonly listTableToggleDropDown: (row: number) => string;

private readonly listTableEditLink: (row: number) => string;

private readonly deleteRowLink: (row: number) => string;

private readonly selectAllRowsLabel: string;

private readonly bulkActionsToggleButton: string;

private readonly bulkActionsDeleteButton: string;

private readonly tableHead: string;

private readonly sortColumnDiv: (column: string) => string;

private readonly sortColumnSpanButton: (column: string) => string;

private readonly confirmDeleteModal: string;

private readonly confirmDeleteButton: string;

/**
* @constructs
* Setting up texts and selectors to use on contacts page
*/
constructor() {
super();

this.pageTitle = 'Contacts';

// Selectors
// Header selectors
this.storesTabLink = '#subtab-AdminStores';
this.addNewContactButton = '#page-header-desc-configuration-add';

// List of contacts
this.contactsGridPanel = '#contact_grid_panel';
this.contactsGridTitle = `${this.contactsGridPanel} h3.card-header-title`;
this.contactsListForm = '#contact_grid';
this.contactsListTableRow = (row: number) => `${this.contactsListForm} tbody tr:nth-child(${row})`;
this.contactsListTableColumn = (row: number, column: string) => `${this.contactsListTableRow(row)} td.column-${column}`;

// Filters
this.contactFilterInput = (filterBy: string) => `${this.contactsListForm} #contact_${filterBy}`;
this.filterSearchButton = `${this.contactsListForm} .grid-search-button`;
this.filterResetButton = `${this.contactsListForm} .grid-reset-button`;

// Actions buttons in Row
this.contactsListTableActionsColumn = (row: number) => this.contactsListTableColumn(row, 'actions');
this.listTableToggleDropDown = (row: number) => `${this.contactsListTableActionsColumn(row)} a[data-toggle='dropdown']`;
this.listTableEditLink = (row: number) => `${this.contactsListTableActionsColumn(row)} a.grid-edit-row-link`;
this.deleteRowLink = (row: number) => `${this.contactsListTableActionsColumn(row)} a.grid-delete-row-link`;

// Bulk Actions
this.selectAllRowsLabel = `${this.contactsGridPanel} tr.column-filters .grid_bulk_action_select_all`;
this.bulkActionsToggleButton = `${this.contactsGridPanel} button.js-bulk-actions-btn`;
this.bulkActionsDeleteButton = '#contact_grid_bulk_action_delete_selection';

// Sort Selectors
this.tableHead = `${this.contactsGridPanel} thead`;
this.sortColumnDiv = (column: string) => `${this.tableHead} div.ps-sortable-column[data-sort-col-name='${column}']`;
this.sortColumnSpanButton = (column: string) => `${this.sortColumnDiv(column)} span.ps-sort`;

// Delete modal
this.confirmDeleteModal = '#contact-grid-confirm-modal';
this.confirmDeleteButton = `${this.confirmDeleteModal} button.btn-confirm-submit`;
}

/*
Methods
*/

/**
* Click on tab stores
* @param page {Page} Browser tab
* @return {Promise<void>}
*/
async goToStoresPage(page: Page): Promise<void> {
await this.clickAndWaitForURL(page, this.storesTabLink);
}

/**
* Reset input filters
* @param page {Page} Browser tab
* @returns {Promise<void>}
*/
async resetFilter(page: Page): Promise<void> {
if (await this.elementVisible(page, this.filterResetButton, 2000)) {
await page.locator(this.filterResetButton).click();
await page.mouse.move(0, 0);
await this.waitForHiddenSelector(page, this.filterResetButton, 2000);
}
}

/**
* Get number of elements in grid
* @param page {Page} Browser tab
* @return {Promise<number>}
*/
async getNumberOfElementInGrid(page: Page): Promise<number> {
return this.getNumberFromText(page, this.contactsGridTitle);
}

/**
* Reset Filter and get number of elements in list
* @param page {Page} Browser tab
* @return {Promise<number>}
*/
async resetAndGetNumberOfLines(page: Page): Promise<number> {
await this.resetFilter(page);
return this.getNumberOfElementInGrid(page);
}

/**
* Filter list of contacts
* @param page {Page} Browser tab
* @param filterBy {string} Column to filter with
* @param value {string} value to filter with
* @return {Promise<void>}
*/
async filterContacts(page: Page, filterBy: string, value: string = ''): Promise<void> {
await this.setValue(page, this.contactFilterInput(filterBy), value.toString());
// click on search
await page.locator(this.filterSearchButton).click();
await this.waitForVisibleSelector(page, this.filterResetButton);
}

/**
* Get text from a column
* @param page {Page} Browser tab
* @param row {number} Row on table
* @param column {string} Column name to get
* @returns {Promise<string>}
*/
async getTextColumnFromTableContacts(page: Page, row: number, column: string): Promise<string> {
return this.getTextContent(page, this.contactsListTableColumn(row, column));
}

/**
* Get content from all rows
* @param page {Page} Browser tab
* @param column {string} Column name to get
* @return {Promise<Array<string>>}
*/
async getAllRowsColumnContent(page: Page, column: string): Promise<string[]> {
const rowsNumber = await this.getNumberOfElementInGrid(page);
const allRowsContentTable: string[] = [];

for (let i = 1; i <= rowsNumber; i++) {
const rowContent = await this.getTextColumnFromTableContacts(page, i, column);
allRowsContentTable.push(rowContent);
}

return allRowsContentTable;
}

/**
* Go to new Contact page
* @param page {Page} Browser tab
* @return {Promise<void>}
*/
async goToAddNewContactPage(page: Page): Promise<void> {
await this.clickAndWaitForURL(page, this.addNewContactButton);
}

/**
* Go to Edit Contact page
* @param page {Page} Browser tab
* @param row {number} Row on table
* @return {Promise<void>}
*/
async goToEditContactPage(page: Page, row: number): Promise<void> {
await this.clickAndWaitForURL(page, this.listTableEditLink(row));
}

/**
* Delete Contact
* @param page {Page} Browser tab
* @param row Row on table
* @returns {Promise<string>}
*/
async deleteContact(page: Page, row: number): Promise<string> {
// Click on dropDown
await Promise.all([
page.locator(this.listTableToggleDropDown(row)).click(),
this.waitForVisibleSelector(
page,
`${this.listTableToggleDropDown(row)}[aria-expanded='true']`,
),
]);

// Click on delete
await Promise.all([
page.locator(this.deleteRowLink(row)).click(),
this.waitForVisibleSelector(page, `${this.confirmDeleteModal}.show`),
]);
await this.confirmDeleteContact(page);
return this.getAlertSuccessBlockParagraphContent(page);
}

/**
* Confirm delete with in modal
* @param page {Page} Browser tab
* @return {Promise<void>}
*/
async confirmDeleteContact(page: Page): Promise<void> {
await this.clickAndWaitForURL(page, this.confirmDeleteButton);
}

/**
* Delete all contacts in table with Bulk Actions
* @param page {Page} Browser tab
* @return {Promise<string>}
*/
async deleteContactsBulkActions(page: Page): Promise<string> {
// Click on Select All
await Promise.all([
page.locator(this.selectAllRowsLabel).evaluate((el: HTMLElement) => el.click()),
this.waitForVisibleSelector(page, `${this.bulkActionsToggleButton}:not([disabled])`),
]);
// Click on Button Bulk actions
await Promise.all([
page.locator(this.bulkActionsToggleButton).click(),
this.waitForVisibleSelector(page, this.bulkActionsToggleButton),
]);

// Click on delete and wait for modal
await Promise.all([
page.locator(this.bulkActionsDeleteButton).click(),
this.waitForVisibleSelector(page, `${this.confirmDeleteModal}.show`),
]);

await this.confirmDeleteContact(page);
return this.getAlertSuccessBlockParagraphContent(page);
}

/* Sort methods */
/**
* Sort table by clicking on column name
* @param page {Page} Browser tab
* @param sortBy {string} Column name to sort with
* @param sortDirection {string} Sort direction by asc or desc
* @return {Promise<void>}
*/
async sortTable(page: Page, sortBy: string, sortDirection: string = 'asc'): Promise<void> {
const sortColumnDiv = `${this.sortColumnDiv(sortBy)}[data-sort-direction='${sortDirection}']`;
const sortColumnSpanButton = this.sortColumnSpanButton(sortBy);

let i = 0;
while (await this.elementNotVisible(page, sortColumnDiv, 2000) && i < 2) {
await this.clickAndWaitForURL(page, sortColumnSpanButton);
i += 1;
}

await this.waitForVisibleSelector(page, sortColumnDiv, 20000);
}
}

module.exports = new BOContactsPage();

0 comments on commit d776ccd

Please sign in to comment.