diff --git a/src/components/DatePicker.ts b/src/components/DatePicker.ts index 2a6028c..b20b126 100644 --- a/src/components/DatePicker.ts +++ b/src/components/DatePicker.ts @@ -14,6 +14,14 @@ class DatePicker extends FormField { await this.textbox.fill(formatDate(date)); await this.page.keyboard.press('Enter'); } + + async fillWithFormat(date: Date, format: string) { + // TODO: This is temporary solution until we figure out the sluggishness of the date picker + await this.page.waitForTimeout(1000); + await this.textbox.fill(formatDate(date, format)); + await this.page.keyboard.press('Enter'); + await this.page.waitForTimeout(1000); + } } export default DatePicker; diff --git a/src/pages/receiving/steps/CheckStep.ts b/src/pages/receiving/steps/CheckStep.ts index 8dcc014..a5f0721 100644 --- a/src/pages/receiving/steps/CheckStep.ts +++ b/src/pages/receiving/steps/CheckStep.ts @@ -2,13 +2,16 @@ import { expect, Page } from '@playwright/test'; import BasePageModel from '@/pages/BasePageModel'; import CheckTable from '@/pages/receiving/components/CheckTable'; - +import DatePicker from '@/components/DatePicker'; class CheckStep extends BasePageModel { table: CheckTable; + deliveredOnDateField: DatePicker; + constructor(page: Page) { super(page); this.table = new CheckTable(page); + this.deliveredOnDateField = new DatePicker(page, 'Delivered on'); } async isLoaded() { @@ -35,13 +38,15 @@ class CheckStep extends BasePageModel { return this.page.getByRole('textbox', { name: 'Shipped on' }); } - get deliveredOnField() { - return this.page.getByRole('textbox', { name: 'Delivered on' }); - } - get cancelAllRemainingButton() { return this.page.getByRole('button', { name: 'Cancel all remaining' }); } + + get validationOnDeliveredOnPastDatePopup() { + return this.page + .locator('.s-alert-box-inner') + .getByText('Must occur on or after Actual Shipping Date'); + } } export default CheckStep; diff --git a/src/pages/receiving/steps/ReceivingStep.ts b/src/pages/receiving/steps/ReceivingStep.ts index caea6e8..f8d5f40 100644 --- a/src/pages/receiving/steps/ReceivingStep.ts +++ b/src/pages/receiving/steps/ReceivingStep.ts @@ -42,6 +42,14 @@ class ReceivingStep extends BasePageModel { get acceptConfirmReceivingDialog() { return this.confirmReceivingDialog.getByRole('button', { name: 'Yes' }); } + + get saveButton() { + return this.page.getByRole('button', { name: 'Save', exact: true }); + } + + get saveAndExitButton() { + return this.page.getByRole('button').getByText('Save and Exit'); + } } export default ReceivingStep; diff --git a/src/tests/receiving/receiveInbound.test.ts b/src/tests/receiving/receiveInbound.test.ts index ee36f79..a28fede 100644 --- a/src/tests/receiving/receiveInbound.test.ts +++ b/src/tests/receiving/receiveInbound.test.ts @@ -239,6 +239,75 @@ test.describe('Receive inbound stock movement', () => { }); }); + test('Use Save button in receiving and assert saved qty', async ({ + stockMovementShowPage, + receivingPage, + }) => { + await test.step('Go to stock movement show page', async () => { + await stockMovementShowPage.goToPage(STOCK_MOVEMENT.id); + await stockMovementShowPage.isLoaded(); + }); + + await test.step('Go to shipment receiving page', async () => { + await stockMovementShowPage.receiveButton.click(); + await receivingPage.receivingStep.isLoaded(); + }); + + await test.step('Check first item to be received', async () => { + await receivingPage.receivingStep.table + .row(1) + .receivingNowField.textbox.fill('8'); + }); + + await test.step('Click on Save button', async () => { + await receivingPage.receivingStep.saveButton.click(); + await stockMovementShowPage.goToPage(STOCK_MOVEMENT.id); + await stockMovementShowPage.isLoaded(); + }); + + await test.step('Return to receive page and assert qty input', async () => { + await stockMovementShowPage.receiveButton.click(); + await receivingPage.receivingStep.isLoaded(); + await expect( + receivingPage.receivingStep.table.row(1).receivingNowField.textbox + ).toHaveValue('8'); + }); + }); + + test('Use Save and Exit button in receiving and assert saved qty', async ({ + stockMovementShowPage, + receivingPage, + }) => { + await test.step('Go to stock movement show page', async () => { + await stockMovementShowPage.goToPage(STOCK_MOVEMENT.id); + await stockMovementShowPage.isLoaded(); + }); + + await test.step('Go to shipment receiving page', async () => { + await stockMovementShowPage.receiveButton.click(); + await receivingPage.receivingStep.isLoaded(); + }); + + await test.step('Check first item to be received', async () => { + await receivingPage.receivingStep.table + .row(1) + .receivingNowField.textbox.fill('2'); + }); + + await test.step('Click on Save and Exit button', async () => { + await receivingPage.receivingStep.saveAndExitButton.click(); + await stockMovementShowPage.isLoaded(); + }); + + await test.step('Return to receive page and assert qty input', async () => { + await stockMovementShowPage.receiveButton.click(); + await receivingPage.receivingStep.isLoaded(); + await expect( + receivingPage.receivingStep.table.row(1).receivingNowField.textbox + ).toHaveValue('2'); + }); + }); + test.describe('Receive from different locations', () => { test.afterEach(async ({ authService }) => { await authService.changeLocation(AppConfig.instance.locations.main.id); diff --git a/src/tests/receiving/validationsOnDeliverOnDate.test.ts b/src/tests/receiving/validationsOnDeliverOnDate.test.ts new file mode 100644 index 0000000..1f31e21 --- /dev/null +++ b/src/tests/receiving/validationsOnDeliverOnDate.test.ts @@ -0,0 +1,103 @@ +import { ShipmentType } from '@/constants/ShipmentType'; +import { expect, test } from '@/fixtures/fixtures'; +import { StockMovementResponse } from '@/types'; +import { getDateByOffset } from '@/utils/DateUtils'; + +test.describe('Validations on edit Deliver On Date when receiving shipment', () => { + let STOCK_MOVEMENT: StockMovementResponse; + + test.beforeEach( + async ({ + supplierLocationService, + stockMovementService, + mainProductService, + }) => { + const supplierLocation = await supplierLocationService.getLocation(); + STOCK_MOVEMENT = await stockMovementService.createInbound({ + originId: supplierLocation.id, + }); + + const product = await mainProductService.getProduct(); + + await stockMovementService.addItemsToInboundStockMovement( + STOCK_MOVEMENT.id, + [{ productId: product.id, quantity: 50 }] + ); + + await stockMovementService.sendInboundStockMovement(STOCK_MOVEMENT.id, { + shipmentType: ShipmentType.AIR, + }); + } + ); + + test.afterEach(async ({ stockMovementShowPage, stockMovementService }) => { + await stockMovementShowPage.goToPage(STOCK_MOVEMENT.id); + await stockMovementShowPage.rollbackButton.click(); + await stockMovementService.deleteStockMovement(STOCK_MOVEMENT.id); + }); + + test('Assert validation on try to edit Delivered on Date to future date', async ({ + stockMovementShowPage, + receivingPage, + }) => { + await test.step('Go to stock movement show page', async () => { + await stockMovementShowPage.goToPage(STOCK_MOVEMENT.id); + await stockMovementShowPage.isLoaded(); + }); + + await test.step('Go to shipment receiving page', async () => { + await stockMovementShowPage.receiveButton.click(); + await receivingPage.receivingStep.isLoaded(); + }); + + await test.step('Autofill qty and go to check page', async () => { + await receivingPage.receivingStep.autofillQuantitiesButton.click(); + await receivingPage.nextButton.click(); + }); + + await test.step('Edit Delivered on Date on check page to future date', async () => { + await receivingPage.checkStep.isLoaded(); + await receivingPage.checkStep.deliveredOnDateField.fillWithFormat( + getDateByOffset(new Date(), 1), + 'MM/DD/YYYY HH:mm:ss Z' + ); + await receivingPage.checkStep.deliveredOnDateField.assertHasError(); + await expect( + receivingPage.checkStep.deliveredOnDateField.errorMessage + ).toContainText('The date cannot be in the future'); + }); + }); + + test('Assert validation on try to edit Delivered on Date to past date', async ({ + stockMovementShowPage, + receivingPage, + }) => { + await test.step('Go to stock movement show page', async () => { + await stockMovementShowPage.goToPage(STOCK_MOVEMENT.id); + await stockMovementShowPage.isLoaded(); + }); + + await test.step('Go to shipment receiving page', async () => { + await stockMovementShowPage.receiveButton.click(); + await receivingPage.receivingStep.isLoaded(); + }); + + await test.step('Autofill qty and go to check page', async () => { + await receivingPage.receivingStep.autofillQuantitiesButton.click(); + await receivingPage.nextButton.click(); + }); + + await test.step('Edit Delivered on Date on check page to past date', async () => { + await receivingPage.checkStep.isLoaded(); + await receivingPage.checkStep.deliveredOnDateField.fillWithFormat( + getDateByOffset(new Date(), -1), + 'MM/DD/YYYY HH:mm:ss Z' + ); + await receivingPage.checkStep.isLoaded(); + await receivingPage.checkStep.receiveShipmentButton.click(); + await expect( + receivingPage.checkStep.validationOnDeliveredOnPastDatePopup + ).toBeVisible(); + }); + }); +});