From bf4ab3d8ba7ccdab6aafdadb4895b563089d0d19 Mon Sep 17 00:00:00 2001 From: Progi1984 Date: Thu, 23 Jan 2025 17:04:48 +0100 Subject: [PATCH] Migrate `'@pages/BO/customers/view` from Core --- src/index.ts | 1 + src/interfaces/BO/customers/view.ts | 20 + src/pages/BO/customers/view.ts | 9 + .../develop/pages/BO/customers/view.ts | 374 ++++++++++++++++++ 4 files changed, 404 insertions(+) create mode 100644 src/interfaces/BO/customers/view.ts create mode 100644 src/pages/BO/customers/view.ts create mode 100644 src/versions/develop/pages/BO/customers/view.ts diff --git a/src/index.ts b/src/index.ts index 83e20759..6509bd02 100644 --- a/src/index.ts +++ b/src/index.ts @@ -208,6 +208,7 @@ export {default as boCurrenciesCreatePage} from '@pages/BO/international/localiz export {default as boCurrenciesPage} from '@pages/BO/international/localization/currencies'; export {default as boCustomersPage} from '@pages/BO/customers'; export {default as boCustomersCreatePage} from '@pages/BO/customers/create'; +export {default as boCustomersViewPage} from '@pages/BO/customers/view'; export {default as boCustomerServicePage} from '@pages/BO/customerService/customerService'; export {default as boDashboardPage} from '@pages/BO/dashboard'; export {default as boDbBackupPage} from '@pages/BO/advancedParameters/database/dbBackup'; diff --git a/src/interfaces/BO/customers/view.ts b/src/interfaces/BO/customers/view.ts new file mode 100644 index 00000000..02e66ebc --- /dev/null +++ b/src/interfaces/BO/customers/view.ts @@ -0,0 +1,20 @@ +import {BOBasePagePageInterface} from '@interfaces/BO'; +import {type Frame, type Page} from '@playwright/test'; + +export interface BOCustomersViewPageInterface extends BOBasePagePageInterface { + readonly pageTitle: (customerName: string) => string; + readonly updateSuccessfulMessage: string; + + clickOnTransformToCustomerAccount(page: Page): Promise; + deleteVoucher(page: Page, row: number): Promise; + getNumberOfElementFromTitle(page: Frame | Page, cardTitle: string): Promise; + getPersonalInformationTitle(page: Page | Frame): Promise; + getTextColumnFromTableCarts(page: Page, column: string, row?: number): Promise; + getTextColumnFromTableLastConnections(page: Page, column: string, row?: number): Promise; + getTextFromElement(page: Page, element: string): Promise; + goToEditCustomerPage(page: Page): Promise; + goToPage(page: Page, cardTitle: string, row?: number): Promise; + isPrivateNoteBlockVisible(page: Frame | Page): Promise; + isTransformToCustomerAccountButtonVisible(page: Page): Promise; + setPrivateNote(page: Page, note: string): Promise; +} diff --git a/src/pages/BO/customers/view.ts b/src/pages/BO/customers/view.ts new file mode 100644 index 00000000..7c31640a --- /dev/null +++ b/src/pages/BO/customers/view.ts @@ -0,0 +1,9 @@ +import {type BOCustomersViewPageInterface} from '@interfaces/BO/customers/view'; + +/* eslint-disable global-require, @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires */ +function requirePage(): BOCustomersViewPageInterface { + return require('@versions/develop/pages/BO/customers/view'); +} +/* 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/customers/view.ts b/src/versions/develop/pages/BO/customers/view.ts new file mode 100644 index 00000000..a62d5317 --- /dev/null +++ b/src/versions/develop/pages/BO/customers/view.ts @@ -0,0 +1,374 @@ +import {type BOCustomersViewPageInterface} from '@interfaces/BO/customers/view'; +import BOBasePage from '@pages/BO/BOBasePage'; +import {type Frame, type Page} from '@playwright/test'; + +/** + * View customer page, contains functions that can be used on the page + * @class + * @extends BOBasePage + */ +class BOCustomersViewPage extends BOBasePage implements BOCustomersViewPageInterface { + public readonly pageTitle: (customerName: string) => string; + + public readonly updateSuccessfulMessage: string; + + private readonly personalInformationDiv: string; + + private readonly personalInformationEditButton: string; + + private readonly transformCustomerAccountButton: string; + + private readonly ordersDiv: string; + + private readonly ordersViewButton: (row: number) => string; + + private readonly cartsDiv: string; + + private readonly cartsTableRow: (row: number) => string; + + private readonly cartsTableColumn: (row: number, column: string) => string; + + private readonly cartsViewButton: (row: number) => string; + + private readonly viewedProductsDiv: string; + + private readonly privateNoteDiv: string; + + private readonly privateNoteTextArea: string; + + private readonly privateNoteSaveButton: string; + + private readonly messagesDiv: string; + + private readonly vouchersDiv: string; + + private readonly voucherEditButton: (row: number) => string; + + private readonly voucherToggleDropdown: (row: number) => string; + + private readonly voucherDeleteButton: string; + + private readonly voucherDeleteConfirmButton: string; + + private readonly voucherDeleteModal: string; + + private readonly lastEmailsDiv: string; + + private readonly lastConnectionsDiv: string; + + private readonly lastConnectionTableRow: (row: number) => string; + + private readonly lastConnectionTableColumn: (row: number, column: string) => string; + + private readonly groupsDiv: string; + + private readonly addressesDiv: string; + + private readonly addressesEditButton: (row: number) => string; + + private readonly purchasedProductsDiv: string; + + /** + * @constructs + * Setting up texts and selectors to use on view customer page + */ + constructor() { + super(); + + this.pageTitle = (customerName: string) => `Customer ${customerName} • ${global.INSTALL.SHOP_NAME}`; + this.updateSuccessfulMessage = 'Update successful'; + + // Selectors + // Personnel information + this.personalInformationDiv = '.customer-personal-informations-card'; + this.personalInformationEditButton = `${this.personalInformationDiv} a.edit-link`; + this.transformCustomerAccountButton = '#transfer_guest_account_transfer_guest_account'; + + // Orders + this.ordersDiv = '.customer-orders-card'; + this.ordersViewButton = (row: number) => `${this.ordersDiv} tr:nth-child(${row}) a.grid-view-row-link i`; + + // Carts + this.cartsDiv = '.customer-carts-card'; + this.cartsViewButton = (row: number) => `${this.cartsDiv} tr:nth-child(${row}) a.grid-view-row-link i`; + this.cartsTableRow = (row: number) => `.customer-carts-card tr:nth-child(${row})`; + this.cartsTableColumn = (row: number, column: string) => `${this.cartsTableRow(row)} td.column-${column}`; + + // Viewed products + this.viewedProductsDiv = '.customer-viewed-products-card'; + + // Private note + this.privateNoteDiv = '.customer-private-note-card'; + this.privateNoteTextArea = '#private_note_note'; + this.privateNoteSaveButton = '#save-private-note'; + + // Messages + this.messagesDiv = '.customer-messages-card'; + + // Vouchers + this.vouchersDiv = '.customer-discounts-card'; + this.voucherEditButton = (row: number) => `${this.vouchersDiv} tr:nth-child(${row}) a.grid-edit-row-link`; + this.voucherToggleDropdown = (row: number) => `${this.vouchersDiv} tr:nth-child(${row}) a[data-toggle='dropdown']`; + this.voucherDeleteButton = `${this.vouchersDiv} .dropdown-menu button.grid-delete-row-link`; + this.voucherDeleteModal = '#customer_discount-grid-confirm-modal'; + this.voucherDeleteConfirmButton = `${this.voucherDeleteModal} button.btn-confirm-submit`; + + // Last emails + this.lastEmailsDiv = '.customer-sent-emails-card'; + + // Last connections + this.lastConnectionsDiv = '.customer-last-connections-card'; + this.lastConnectionTableRow = (row: number) => `tr.customer-last-connection:nth-child(${row})`; + this.lastConnectionTableColumn = (row: number, column: string) => `${this.lastConnectionTableRow(row)} ` + + `td.customer-last-connection-${column}`; + + // Groups + this.groupsDiv = '.customer-groups-card'; + + // Addresses + this.addressesDiv = '.customer-addresses-card'; + this.addressesEditButton = (row: number) => `${this.addressesDiv} tr:nth-child(${row}) a.grid-edit-row-link i`; + + // Purchased products + this.purchasedProductsDiv = '.customer-bought-products-card'; + } + + /* + Methods + */ + + /** + * Get number of element from title + * @param page {Frame|Page} Browser tab + * @param cardTitle {string} Value of card title to get number of elements + * @returns {Promise} + */ + async getNumberOfElementFromTitle(page: Frame | Page, cardTitle: string): Promise { + let selector: string; + + switch (cardTitle) { + case 'Orders': + selector = this.ordersDiv; + break; + case 'Carts': + selector = this.cartsDiv; + break; + case 'Viewed products': + selector = this.viewedProductsDiv; + break; + case 'Messages': + selector = this.messagesDiv; + break; + case 'Vouchers': + selector = this.vouchersDiv; + break; + case 'Last emails': + selector = this.lastEmailsDiv; + break; + case 'Last connections': + selector = this.lastConnectionsDiv; + break; + case 'Groups': + selector = this.groupsDiv; + break; + case 'Addresses': + selector = this.addressesDiv; + break; + case 'Purchased products': + selector = this.purchasedProductsDiv; + break; + default: + throw new Error(`${cardTitle} was not found`); + } + + return this.getTextContent(page, `${selector} .card-header span`); + } + + /** + * Get personal information title + * @param page {Page|Frame} Browser tab + * @returns {Promise} + */ + async getPersonalInformationTitle(page: Page | Frame): Promise { + return this.getTextContent(page, this.personalInformationDiv); + } + + /** + * Get text from element + * @param page {Page} Browser tab + * @param element {string} Value of element to get text content + * @returns {Promise} + */ + async getTextFromElement(page: Page, element: string): Promise { + let selector: string; + + switch (element) { + case 'Personal information': + selector = this.personalInformationDiv; + break; + case 'Orders': + selector = this.ordersDiv; + break; + case 'Carts': + selector = this.cartsDiv; + break; + case 'Viewed products': + selector = this.viewedProductsDiv; + break; + case 'Addresses': + selector = this.addressesDiv; + break; + case 'Messages': + selector = this.messagesDiv; + break; + case 'Vouchers': + selector = this.vouchersDiv; + break; + case 'Last emails': + selector = this.lastEmailsDiv; + break; + case 'Last connections': + selector = this.lastConnectionsDiv; + break; + case 'Groups': + selector = this.groupsDiv; + break; + case 'Purchased products': + selector = this.purchasedProductsDiv; + break; + default: + throw new Error(`${element} was not found`); + } + + return this.getTextContent(page, `${selector} .card-body`); + } + + /** + * Get text column from table last connection + * @param page {Page} Browser tab + * @param column {string} Column name in table last connections + * @param row {number} Row number in table Last connections + * @returns {Promise} + */ + async getTextColumnFromTableLastConnections(page: Page, column: string, row: number = 1): Promise { + return this.getTextContent(page, this.lastConnectionTableColumn(row, column)); + } + + /** + * Get text column from carts table + * @param page {Page} Browser tab + * @param column {string} Column name in table carts + * @param row {number} Row number in table carts + * @returns {Promise} + */ + async getTextColumnFromTableCarts(page: Page, column: string, row: number = 1): Promise { + return this.getTextContent(page, this.cartsTableColumn(row, column)); + } + + /** + * Is private note block visible + * @param page {Frame|Page} Browser tab + * @returns {Promise} + */ + async isPrivateNoteBlockVisible(page: Frame | Page): Promise { + return this.elementVisible(page, this.privateNoteDiv, 1000); + } + + /** + * Set private note + * @param page {Page} Browser tab + * @param note {string} Value of private note to set + * @returns {Promise} + */ + async setPrivateNote(page: Page, note: string): Promise { + await this.setValue(page, this.privateNoteTextArea, note); + await page.locator(this.privateNoteSaveButton).click(); + + return this.getAlertSuccessBlockParagraphContent(page); + } + + /** + * Go to edit customer page + * @param page {Page} Browser tab + * @returns {Promise} + */ + async goToEditCustomerPage(page: Page): Promise { + await this.clickAndWaitForURL(page, this.personalInformationEditButton); + } + + /** + * Go to view/edit page + * @param page {Page} Browser tab + * @param cardTitle {string} Value of page title to go + * @param row {number} Row on table where to click + * @returns {Promise} + */ + async goToPage(page: Page, cardTitle: string, row: number = 1): Promise { + let selector: (row: number) => string; + + switch (cardTitle) { + case 'Orders': + selector = this.ordersViewButton; + break; + case 'Carts': + selector = this.cartsViewButton; + break; + case 'Addresses': + selector = this.addressesEditButton; + break; + case 'Vouchers': + selector = this.voucherEditButton; + break; + default: + throw new Error(`${cardTitle} was not found`); + } + + return this.clickAndWaitForURL(page, selector(row)); + } + + /** + * Delete voucher + * @param page {Page} Browser tab + * @param row {number} Row in vouchers table + * @returns {Promise} + */ + async deleteVoucher(page: Page, row: number): Promise { + await page.locator(this.voucherToggleDropdown(row)).click(); + await page.locator(this.voucherDeleteButton).click(); + await this.waitForVisibleSelector(page, this.voucherDeleteModal); + await page.locator(this.voucherDeleteConfirmButton).click(); + + return this.getTextContent(page, `${this.alertSuccessBlock}[role='alert']`); + } + + /** + * Get customer ID + * @param page {Page} Browser tab + * @returns {Promise} + */ + async getCustomerID(page: Page): Promise { + return this.getNumberFromText(page, this.personalInformationDiv); + } + + /** + * Click on transform to customer account + * @param page {Page} Browser tab + * @returns {Promise} + */ + async clickOnTransformToCustomerAccount(page: Page): Promise { + await this.clickAndWaitForURL(page, this.transformCustomerAccountButton); + + return this.getTextContent(page, `${this.alertSuccessBlock}[role='alert']`); + } + + /** + * Is transform to customer account button visible + * @param page {Page} Browser tab + * @returns {Promise} + */ + async isTransformToCustomerAccountButtonVisible(page: Page): Promise { + return this.elementVisible(page, this.transformCustomerAccountButton, 1000); + } +} + +module.exports = new BOCustomersViewPage();