diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000000000..3d00e47e6b4da --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "prestashop", + "lockfileVersion": 2, + "requires": true, + "packages": {} +} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Payment/PaymentMethods/Blocks/payment_modules_list.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Payment/PaymentMethods/Blocks/payment_modules_list.html.twig index e2d49f1af5360..a5cc2b1985807 100644 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Payment/PaymentMethods/Blocks/payment_modules_list.html.twig +++ b/src/PrestaShopBundle/Resources/views/Admin/Improve/Payment/PaymentMethods/Blocks/payment_modules_list.html.twig @@ -28,7 +28,7 @@ {% if paymentModules|length > 0 %}
{% for module in paymentModules %} -
+
{{ module.attributes.displayName }} diff --git a/tests/UI/campaigns/functional/BO/10_payment/01_paymentMethods/01_configureModuleLink.ts b/tests/UI/campaigns/functional/BO/10_payment/01_paymentMethods/01_configureModuleLink.ts new file mode 100644 index 0000000000000..7aecc0e253708 --- /dev/null +++ b/tests/UI/campaigns/functional/BO/10_payment/01_paymentMethods/01_configureModuleLink.ts @@ -0,0 +1,147 @@ +// Import utils +import testContext from '@utils/testContext'; + +// Import commonTests +import loginCommon from '@commonTests/BO/loginBO'; +import {resetModule} from '@commonTests/BO/modules/moduleManager'; + +// Import pages +// Import BO pages +import boPaymentMethodsPage from '@pages/BO/payment/paymentMethods'; +import psCheckPayment from '@pages/BO/modules/psCheckPayment'; +import psWirePayment from '@pages/BO/modules/psWirePayment'; + +import { + boDashboardPage, + dataModules, + dataPaymentMethods, + utilsPlaywright, +} from '@prestashop-core/ui-testing'; + +import {expect} from 'chai'; +import type {BrowserContext, Page} from 'playwright'; + +const baseContext: string = 'functional_BO_payment_paymentMethods_configureModuleLink'; + +describe('BO - Payments - Payment methods: Configure module link', async () => { + let browserContext: BrowserContext; + let page: Page; + + describe('Configure module link', async () => { + before(async function () { + browserContext = await utilsPlaywright.createBrowserContext(this.browser); + page = await utilsPlaywright.newTab(browserContext); + }); + + after(async () => { + await utilsPlaywright.closeBrowserContext(browserContext); + }); + + it('should login in BO', async function () { + await loginCommon.loginBO(this, page); + }); + + it('should go to \'Payment > Payment Methods\' page', async function () { + await testContext.addContextItem(this, 'testIdentifier', 'goToPaymentMethodsPage', baseContext); + + await boDashboardPage.goToSubMenu( + page, + boDashboardPage.paymentParentLink, + boDashboardPage.paymentMethodsLink, + ); + await boPaymentMethodsPage.closeSfToolBar(page); + + const pageTitle = await boPaymentMethodsPage.getPageTitle(page); + expect(pageTitle).to.contains(boPaymentMethodsPage.pageTitle); + + const numActivePayments = await boPaymentMethodsPage.getCountActivePayments(page); + expect(numActivePayments).to.equal(Object.keys(dataPaymentMethods).length); + }); + + it(`should click on the Configure button for "${dataPaymentMethods.wirePayment.displayName}"`, async function () { + await testContext.addContextItem(this, 'testIdentifier', 'clickConfigureButtonWirePayment', baseContext); + + const hasConfigureButton = await boPaymentMethodsPage.hasConfigureButton(page, dataModules.psWirePayment); + expect(hasConfigureButton).to.equal(true); + + await boPaymentMethodsPage.clickConfigureButton(page, dataModules.psWirePayment); + + const pageTitle = await psWirePayment.getPageSubTitle(page); + expect(pageTitle).to.contains(psWirePayment.pageTitle); + }); + + it(`should fill required fields for "${dataPaymentMethods.wirePayment.displayName}"`, async function () { + await testContext.addContextItem(this, 'testIdentifier', 'fillRequiredFieldsWirePayment', baseContext); + + await psWirePayment.setAccountOwner(page, 'Account Owner'); + await psWirePayment.setAccountDetails(page, 'Account Details'); + await psWirePayment.setBankAddress(page, 'Bank Address'); + + const result = await psWirePayment.saveFormContactDetails(page); + expect(result).to.contains(psWirePayment.successfulUpdateMessage); + }); + + it('should return to \'Payment > Payment Methods\' page', async function () { + await testContext.addContextItem(this, 'testIdentifier', 'returnToPaymentMethodsPage', baseContext); + + await boDashboardPage.goToSubMenu( + page, + boDashboardPage.paymentParentLink, + boDashboardPage.paymentMethodsLink, + ); + await boPaymentMethodsPage.closeSfToolBar(page); + + const pageTitle = await boPaymentMethodsPage.getPageTitle(page); + expect(pageTitle).to.equal(boPaymentMethodsPage.pageTitle); + + const numActivePayments = await boPaymentMethodsPage.getCountActivePayments(page); + expect(numActivePayments).to.equal(Object.keys(dataPaymentMethods).length); + }); + + it(`should click on the Configure button for "${dataPaymentMethods.checkPayment.displayName}"`, async function () { + await testContext.addContextItem(this, 'testIdentifier', 'clickConfigureButtonCheckPayment', baseContext); + + const hasConfigureButton = await boPaymentMethodsPage.hasConfigureButton(page, dataModules.psCheckPayment); + expect(hasConfigureButton).to.equal(true); + + await boPaymentMethodsPage.clickConfigureButton(page, dataModules.psCheckPayment); + + const pageTitle = await psCheckPayment.getPageSubTitle(page); + expect(pageTitle).to.equal(psCheckPayment.pageTitle); + }); + + it(`should fill required fields for "${dataPaymentMethods.checkPayment.displayName}"`, async function () { + await testContext.addContextItem(this, 'testIdentifier', 'fillRequiredFieldsCheckPayment', baseContext); + + await psCheckPayment.setPayee(page, 'Payee'); + await psCheckPayment.setAddress(page, 'Address'); + + const result = await psCheckPayment.saveFormContactDetails(page); + expect(result).to.contains(psCheckPayment.successfulUpdateMessage); + }); + + it('should return to \'Payment > Payment Methods\' page', async function () { + await testContext.addContextItem(this, 'testIdentifier', 'returnFinalPaymentMethodsPage', baseContext); + + await boDashboardPage.goToSubMenu( + page, + boDashboardPage.paymentParentLink, + boDashboardPage.paymentMethodsLink, + ); + await boPaymentMethodsPage.closeSfToolBar(page); + + const pageTitle = await boPaymentMethodsPage.getPageTitle(page); + expect(pageTitle).to.equal(boPaymentMethodsPage.pageTitle); + + const numActivePayments = await boPaymentMethodsPage.getCountActivePayments(page); + expect(numActivePayments).to.equal(Object.keys(dataPaymentMethods).length); + + const hasConfigureButton = await boPaymentMethodsPage.hasConfigureButton(page, dataModules.psCashOnDelivery); + expect(hasConfigureButton).to.equal(false); + }); + }); + + resetModule(dataModules.psWirePayment, `${baseContext}_postTest_0`); + + resetModule(dataModules.psCheckPayment, `${baseContext}_postTest_1`); +}); diff --git a/tests/UI/pages/BO/modules/psCheckPayment/index.ts b/tests/UI/pages/BO/modules/psCheckPayment/index.ts new file mode 100644 index 0000000000000..3864c49ef6ae1 --- /dev/null +++ b/tests/UI/pages/BO/modules/psCheckPayment/index.ts @@ -0,0 +1,72 @@ +import {ModuleConfiguration} from '@pages/BO/modules/moduleConfiguration'; + +import {type Page} from 'playwright'; + +/** + * Module configuration page for module : ps_checkpayment, contains selectors and functions for the page + * @class + * @extends ModuleConfiguration + */ +class PsCheckPaymentPage extends ModuleConfiguration { + public readonly pageTitle: string; + + private readonly configurationForm: string; + + private readonly payeeInput: string; + + private readonly addressInput: string; + + private readonly submitContactDetails: string; + + /** + * @constructs + * Setting up titles and selectors to use on page + */ + constructor() { + super(); + this.pageTitle = 'Payments by check'; + this.successfulUpdateMessage = 'Settings updated'; + + // Selectors + // Customer Notifications + this.configurationForm = '#configuration_form'; + this.payeeInput = `${this.configurationForm} #CHEQUE_NAME`; + this.addressInput = `${this.configurationForm} #CHEQUE_ADDRESS`; + this.submitContactDetails = `${this.configurationForm} button[name="btnSubmit"]`; + } + + /* Methods */ + + /** + * Define the field "Payee" + * @param page {Page} Browser tab + * @param payee {string} + * @returns {Promise} + */ + async setPayee(page: Page, payee: string): Promise { + return this.setInputValue(page, this.payeeInput, payee); + } + + /** + * Define the field "Address" + * @param page {Page} Browser tab + * @param address {string} + * @returns {Promise} + */ + async setAddress(page: Page, address: string): Promise { + return this.setInputValue(page, this.addressInput, address); + } + + /** + * Save the "Contact details" form + * @param page {Page} Browser tab + * @returns {Promise} + */ + async saveFormContactDetails(page: Page): Promise { + await page.locator(this.submitContactDetails).click(); + + return this.getAlertSuccessBlockContent(page); + } +} + +export default new PsCheckPaymentPage(); diff --git a/tests/UI/pages/BO/modules/psWirePayment/index.ts b/tests/UI/pages/BO/modules/psWirePayment/index.ts new file mode 100644 index 0000000000000..5f18f1ed7b725 --- /dev/null +++ b/tests/UI/pages/BO/modules/psWirePayment/index.ts @@ -0,0 +1,85 @@ +import {ModuleConfiguration} from '@pages/BO/modules/moduleConfiguration'; + +import {type Page} from 'playwright'; + +/** + * Module configuration page for module : ps_wirepayment, contains selectors and functions for the page + * @class + * @extends ModuleConfiguration + */ +class PsWirePaymentPage extends ModuleConfiguration { + public readonly pageTitle: string; + + private readonly accountDetailsForm: string; + + private readonly accountOwnerInput: string; + + private readonly accountDetailsInput: string; + + private readonly bankAddresInput: string; + + private readonly submitAccountDetails: string; + + /** + * @constructs + * Setting up titles and selectors to use on page + */ + constructor() { + super(); + this.pageTitle = 'Bank transfer'; + this.successfulUpdateMessage = 'Settings updated'; + + // Selectors + // Customer Notifications + this.accountDetailsForm = '#module_form'; + this.accountOwnerInput = `${this.accountDetailsForm} #BANK_WIRE_OWNER`; + this.accountDetailsInput = `${this.accountDetailsForm} #BANK_WIRE_DETAILS`; + this.bankAddresInput = `${this.accountDetailsForm} #BANK_WIRE_ADDRESS`; + this.submitAccountDetails = `${this.accountDetailsForm} button#module_form_submit_btn`; + } + + /* Methods */ + + /** + * Define the field "Account Owner" + * @param page {Page} Browser tab + * @param accountOwner {string} + * @returns {Promise} + */ + async setAccountOwner(page: Page, accountOwner: string): Promise { + return this.setInputValue(page, this.accountOwnerInput, accountOwner); + } + + /** + * Define the field "Account Details" + * @param page {Page} Browser tab + * @param accountDetails {string} + * @returns {Promise} + */ + async setAccountDetails(page: Page, accountDetails: string): Promise { + return this.setInputValue(page, this.accountDetailsInput, accountDetails); + } + + /** + * Define the field "Bank Address" + * @param page {Page} Browser tab + * @param bankAddress {string} + * @returns {Promise} + */ + async setBankAddress(page: Page, bankAddress: string): Promise { + return this.setInputValue(page, this.bankAddresInput, bankAddress); + } + + /** + * Save the "Contact details" form + * @param page {Page} Browser tab + * @returns {Promise} + */ + async saveFormContactDetails(page: Page): Promise { + await page.locator(this.submitAccountDetails).click(); + + return this.getAlertSuccessBlockContent(page); + } +} + +export default new PsWirePaymentPage(); diff --git a/tests/UI/pages/BO/payment/paymentMethods/index.ts b/tests/UI/pages/BO/payment/paymentMethods/index.ts new file mode 100644 index 0000000000000..b55d3d1613734 --- /dev/null +++ b/tests/UI/pages/BO/payment/paymentMethods/index.ts @@ -0,0 +1,71 @@ +import BOBasePage from '@pages/BO/BObasePage'; +import { + type FakerModule, +} from '@prestashop-core/ui-testing'; + +import type {Page} from 'playwright'; + +/** + * BO Payment preferences page, contains texts, selectors and functions to use on the page. + * @class + * @extends BOBasePage + */ +class PaymentMethodsPage extends BOBasePage { + public readonly pageTitle: string; + + private readonly tablePayments: string; + + private readonly tablePaymentsRow: string; + + private readonly tablePaymentsRowName: (name: string) => string; + + private readonly tablePaymentsBtnConfigure: (name: string) => string; + + /** + * @constructs + * Setting up texts and selectors to use + */ + constructor() { + super(); + + this.pageTitle = `Payment methods • ${global.INSTALL.SHOP_NAME}`; + this.tablePayments = '.card-body .module-item-list'; + this.tablePaymentsRow = `${this.tablePayments} div.row`; + this.tablePaymentsRowName = (name: string) => `${this.tablePaymentsRow}[data-name="${name}"]`; + this.tablePaymentsBtnConfigure = (name: string) => `${this.tablePaymentsRowName(name)} div:nth-child(3) a.btn`; + } + + /* + Methods + */ + /** + * Returns the number of active payments + * @param page {Page} Browser tab + * @returns {Promise} + */ + async getCountActivePayments(page: Page): Promise { + return page.locator(this.tablePaymentsRow).count(); + } + + /** + * Returns if the active payment has a "Configure" button + * @param page {Page} Browser tab + * @param module {FakerModule} Module + * @returns {Promise} + */ + async hasConfigureButton(page: Page, module: FakerModule): Promise { + return (await page.locator(this.tablePaymentsBtnConfigure(module.tag)).count()) === 1; + } + + /** + * Click on the "Configure" button + * @param page {Page} Browser tab + * @param module {FakerModule} Module + * @returns {Promise} + */ + async clickConfigureButton(page: Page, module: FakerModule): Promise { + await page.locator(this.tablePaymentsBtnConfigure(module.tag)).click(); + } +} + +export default new PaymentMethodsPage();