From 6b715cbbcec542dddd6de4fa765600dc9b285739 Mon Sep 17 00:00:00 2001 From: Progi1984 Date: Wed, 26 Feb 2025 11:32:59 +0100 Subject: [PATCH] Migrate `@pages/BO/shopParameters/contact` from Core --- src/index.ts | 1 + .../BO/shopParameters/contacts/index.ts | 19 ++ src/pages/BO/shopParameters/contacts/index.ts | 9 + .../pages/BO/shopParameters/contacts/index.ts | 294 ++++++++++++++++++ 4 files changed, 323 insertions(+) create mode 100644 src/interfaces/BO/shopParameters/contacts/index.ts create mode 100644 src/pages/BO/shopParameters/contacts/index.ts create mode 100644 src/versions/develop/pages/BO/shopParameters/contacts/index.ts diff --git a/src/index.ts b/src/index.ts index 73229db9..cf9163cd 100644 --- a/src/index.ts +++ b/src/index.ts @@ -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'; diff --git a/src/interfaces/BO/shopParameters/contacts/index.ts b/src/interfaces/BO/shopParameters/contacts/index.ts new file mode 100644 index 00000000..bc4f4d2a --- /dev/null +++ b/src/interfaces/BO/shopParameters/contacts/index.ts @@ -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; + deleteContactsBulkActions(page: Page): Promise; + filterContacts(page: Page, filterBy: string, value?: string): Promise; + getAllRowsColumnContent(page: Page, column: string): Promise; + getNumberOfElementInGrid(page: Page): Promise; + getTextColumnFromTableContacts(page: Page, row: number, column: string): Promise; + goToAddNewContactPage(page: Page): Promise; + goToEditContactPage(page: Page, row: number): Promise; + goToStoresPage(page: Page): Promise; + resetAndGetNumberOfLines(page: Page): Promise; + resetFilter(page: Page): Promise; + sortTable(page: Page, sortBy: string, sortDirection?: string): Promise; +} diff --git a/src/pages/BO/shopParameters/contacts/index.ts b/src/pages/BO/shopParameters/contacts/index.ts new file mode 100644 index 00000000..288ece00 --- /dev/null +++ b/src/pages/BO/shopParameters/contacts/index.ts @@ -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(); diff --git a/src/versions/develop/pages/BO/shopParameters/contacts/index.ts b/src/versions/develop/pages/BO/shopParameters/contacts/index.ts new file mode 100644 index 00000000..5a2739c9 --- /dev/null +++ b/src/versions/develop/pages/BO/shopParameters/contacts/index.ts @@ -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} + */ + async goToStoresPage(page: Page): Promise { + await this.clickAndWaitForURL(page, this.storesTabLink); + } + + /** + * Reset input filters + * @param page {Page} Browser tab + * @returns {Promise} + */ + async resetFilter(page: Page): Promise { + 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} + */ + async getNumberOfElementInGrid(page: Page): Promise { + return this.getNumberFromText(page, this.contactsGridTitle); + } + + /** + * Reset Filter and get number of elements in list + * @param page {Page} Browser tab + * @return {Promise} + */ + async resetAndGetNumberOfLines(page: Page): Promise { + 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} + */ + async filterContacts(page: Page, filterBy: string, value: string = ''): Promise { + 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} + */ + async getTextColumnFromTableContacts(page: Page, row: number, column: string): Promise { + 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>} + */ + async getAllRowsColumnContent(page: Page, column: string): Promise { + 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} + */ + async goToAddNewContactPage(page: Page): Promise { + await this.clickAndWaitForURL(page, this.addNewContactButton); + } + + /** + * Go to Edit Contact page + * @param page {Page} Browser tab + * @param row {number} Row on table + * @return {Promise} + */ + async goToEditContactPage(page: Page, row: number): Promise { + await this.clickAndWaitForURL(page, this.listTableEditLink(row)); + } + + /** + * Delete Contact + * @param page {Page} Browser tab + * @param row Row on table + * @returns {Promise} + */ + async deleteContact(page: Page, row: number): Promise { + // 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} + */ + async confirmDeleteContact(page: Page): Promise { + await this.clickAndWaitForURL(page, this.confirmDeleteButton); + } + + /** + * Delete all contacts in table with Bulk Actions + * @param page {Page} Browser tab + * @return {Promise} + */ + async deleteContactsBulkActions(page: Page): Promise { + // 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} + */ + async sortTable(page: Page, sortBy: string, sortDirection: string = 'asc'): Promise { + 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();