Skip to content

Commit

Permalink
OBPIH-6695 Add test for edit bin location in the middle of receipt (#40)
Browse files Browse the repository at this point in the history
* OBPIH-6695 add bin location tab and dialog to create location page

* OBPIH-6695 add locators to receiving table

* OBPIH-6695 add in stock tab to product page

* OBPIH-6695 add test for edit bin location in the middle of receipt

* OBPIH-6695 fix import on create location page

* OBPIH-6695 fix another import
  • Loading branch information
kkrawczyk123 authored Jan 28, 2025
1 parent ba1b581 commit 6045702
Show file tree
Hide file tree
Showing 7 changed files with 285 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/pages/location/createLocation/CreateLocationPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,21 @@ import { expect } from '@/fixtures/fixtures';
import BasePageModel from '@/pages/BasePageModel';
import LocationConfigurationTabSection from '@/pages/location/createLocation/tabs/LocationConfigurationTabSection';
import LocationDetailsTabSection from '@/pages/location/createLocation/tabs/LocationDetailsTabSection';
import BinLocationsTabSection from '@/pages/location/createLocation/tabs/BinLocationsTabSection';


class CreateLocationPage extends BasePageModel {
locationDetailsTabSection: LocationDetailsTabSection;
locationConfigurationTabSection: LocationConfigurationTabSection;
binLocationTabSection: BinLocationsTabSection;

constructor(page: Page) {
super(page);
this.locationDetailsTabSection = new LocationDetailsTabSection(page);
this.locationConfigurationTabSection = new LocationConfigurationTabSection(
page
);
this.binLocationTabSection = new BinLocationsTabSection(page);
}

async gotToPage() {
Expand All @@ -29,6 +33,10 @@ class CreateLocationPage extends BasePageModel {
return this.page.getByRole('link', { name: 'Configuration' });
}

get binLocationTab() {
return this.page.getByRole('link', { name: 'Bin Locations' });
}

get actionButton() {
return this.page.getByRole('button', { name: 'action' });
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import BasePageModel from '@/pages/BasePageModel';

class AddBinLocationDialog extends BasePageModel {
get binLocationNameField() {
return this.page.locator('#dlgAddBinLocation').locator('#name');
}

get saveButton() {
return this.page.getByRole('button', { name: 'Save' });
}
}

export default AddBinLocationDialog;
36 changes: 36 additions & 0 deletions src/pages/location/createLocation/tabs/BinLocationsTabSection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import BasePageModel from '@/pages/BasePageModel';
import { expect, Page } from '@playwright/test';
import AddBinLocationDialog from '@/pages/location/createLocation/components/AddBinLocationDialog';

class BinLocationsTabSection extends BasePageModel {
addBinLocationDialog: AddBinLocationDialog;

constructor(page: Page) {
super(page);
this.addBinLocationDialog = new AddBinLocationDialog(page);
}

get section() {
return this.page.getByRole('region', { name: 'Bin Locations' });
}

async isLoaded() {
await expect(
this.page.locator('.box').getByText('Bin Locations')
).toBeVisible();
}

get addBinLocationButton() {
return this.page.getByRole('button', { name: 'Add Bin Location' });
}

get searchField() {
return this.page.getByRole('textbox', { name: 'Search:' });
}

get deleteBinButton() {
return this.page.getByRole('link', { name: 'Delete' });
}
}

export default BinLocationsTabSection;
11 changes: 11 additions & 0 deletions src/pages/product/productShow/ProductShowPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@ import { Page } from '@playwright/test';

import BasePageModel from '@/pages/BasePageModel';
import RecordStockSection from '@/pages/product/productShow/sections/RecordStockSection';
import InStockTabSection from './tabs/InStockTabSection';

class ProductShowPage extends BasePageModel {
recordStock: RecordStockSection;
inStockTabSection: InStockTabSection;

constructor(page: Page) {
super(page);
this.recordStock = new RecordStockSection(page);
this.inStockTabSection = new InStockTabSection(page);
}

async goToPage(id: string) {
Expand All @@ -22,6 +25,14 @@ class ProductShowPage extends BasePageModel {
get recordStockButton() {
return this.page.getByRole('link', { name: 'Record stock' });
}

get inStockTab() {
return this.page.getByRole('link', { name: 'In Stock' });
}

get stockHistoryTab() {
return this.page.getByRole('link', { name: 'Stock History' });
}
}

export default ProductShowPage;
44 changes: 44 additions & 0 deletions src/pages/product/productShow/tabs/InStockTabSection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import BasePageModel from '@/pages/BasePageModel';
import { expect, Locator, Page } from '@playwright/test';

class InStockTabSection extends BasePageModel {
constructor(page: Page) {
super(page);
}

async isLoaded() {
await expect(
this.page.getByRole('heading').getByText('Current stock')
).toBeVisible();
}

get table() {
return this.page.locator('#ui-tabs-1').getByRole('table');
}

get rows() {
return this.table.getByRole('row');
}

row(index: number) {
return new Row(this.page, this.rows.nth(index));
}
}

class Row extends BasePageModel {
row: Locator;
constructor(page: Page, row: Locator) {
super(page);
this.row = row;
}

get actionsButton() {
return this.row.locator('.action-menu').getByRole('button');
}

get binLocation() {
return this.row.locator('.line').getByRole('link');
}
}

export default InStockTabSection;
11 changes: 11 additions & 0 deletions src/pages/receiving/components/ReceivingTable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,17 @@ class Row extends BasePageModel {
getItem(name: string) {
return this.row.getByTestId('label-field').getByText(name);
}

get binLocationSelect() {
return this.row.getByRole('cell', { name: 'Bin Location' });
}

getBinLocation(binLocation: string) {
return this.page
.getByTestId('custom-select-dropdown-menu')
.getByRole('listitem')
.getByText(binLocation, { exact: true });
}
}

export default ReceivingTable;
162 changes: 162 additions & 0 deletions src/tests/receiving/editBinLocationWhenReceive.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
import { ShipmentType } from '@/constants/ShipmentType';
import { expect, test } from '@/fixtures/fixtures';
import { StockMovementResponse } from '@/types';
import { getToday } from '@/utils/DateUtils';
import UniqueIdentifier from '@/utils/UniqueIdentifier';

test.describe('Edit Bin Location when receive inbound stock movement', () => {
let STOCK_MOVEMENT: StockMovementResponse;
const description = 'some description';
const dateRequested = getToday();
const uniqueIdentifier = new UniqueIdentifier();
const binLocationName = uniqueIdentifier.generateUniqueString('bin');

test.beforeEach(
async ({
supplierLocationService,
mainLocationService,
stockMovementService,
mainProductService,
otherProductService,
page,
locationListPage,
createLocationPage,
}) => {
const supplierLocation = await supplierLocationService.getLocation();
const mainLocation = await mainLocationService.getLocation();
const PRODUCT_ONE = await mainProductService.getProduct();
const PRODUCT_TWO = await otherProductService.getProduct();

STOCK_MOVEMENT = await stockMovementService.createInbound({
originId: supplierLocation.id,
description,
dateRequested,
});

await stockMovementService.addItemsToInboundStockMovement(
STOCK_MOVEMENT.id,
[
{ productId: PRODUCT_ONE.id, quantity: 20 },
{ productId: PRODUCT_TWO.id, quantity: 10 },
]
);

await stockMovementService.sendInboundStockMovement(STOCK_MOVEMENT.id, {
shipmentType: ShipmentType.AIR,
});

await test.step('Create bin location for location', async () => {
await page.goto('./location/list');
await locationListPage.searchByLocationNameField.fill(
mainLocation.name
);
await locationListPage.findButton.click();
await expect(
locationListPage.getLocationEditButton(mainLocation.name)
).toBeVisible();
await locationListPage.getLocationEditButton(mainLocation.name).click();
await createLocationPage.binLocationTab.click();
await createLocationPage.binLocationTabSection.isLoaded();
await createLocationPage.binLocationTabSection.addBinLocationButton.click();
await createLocationPage.binLocationTabSection.addBinLocationDialog.binLocationNameField.fill(
binLocationName
);
await createLocationPage.binLocationTabSection.addBinLocationDialog.saveButton.click();
});
}
);

test.afterEach(
async ({
stockMovementShowPage,
stockMovementService,
page,
locationListPage,
mainLocationService,
createLocationPage,
}) => {
await stockMovementShowPage.goToPage(STOCK_MOVEMENT.id);
await stockMovementShowPage.rollbackLastReceiptButton.click();
await stockMovementShowPage.rollbackButton.click();
await stockMovementService.deleteStockMovement(STOCK_MOVEMENT.id);

await test.step('Delete created bin location', async () => {
const mainLocation = await mainLocationService.getLocation();
await page.goto('./location/list');
await locationListPage.searchByLocationNameField.fill(
mainLocation.name
);
await locationListPage.findButton.click();
await expect(
locationListPage.getLocationEditButton(mainLocation.name)
).toBeVisible();
await locationListPage.getLocationEditButton(mainLocation.name).click();
await createLocationPage.binLocationTab.click();
await createLocationPage.binLocationTabSection.isLoaded();
await createLocationPage.binLocationTabSection.searchField.fill(
binLocationName
);
await createLocationPage.binLocationTabSection.searchField.press(
'Enter'
);
await createLocationPage.binLocationTabSection.isLoaded();
await createLocationPage.binLocationTabSection.deleteBinButton.click();
await createLocationPage.binLocationTabSection.isLoaded();
});
}
);

test('Edit Bin location when receive', async ({
stockMovementShowPage,
receivingPage,
productShowPage,
}) => {
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('Edit bin when receive item', async () => {
await receivingPage.receivingStep.isLoaded();
await receivingPage.receivingStep.table.row(1).binLocationSelect.click();
await receivingPage.receivingStep.table
.row(1)
.getBinLocation(binLocationName)
.click();
await receivingPage.receivingStep.table
.row(1)
.receivingNowField.textbox.fill('10');
});

await test.step('Go to check page', async () => {
await receivingPage.nextButton.click();
await receivingPage.checkStep.isLoaded();
});

await test.step('Finish receipt of item', async () => {
await receivingPage.checkStep.isLoaded();
await receivingPage.checkStep.receiveShipmentButton.click();
await stockMovementShowPage.isLoaded();
});

await test.step('Assert edited bin on Packing list', async () => {
await expect(
stockMovementShowPage.packingListTable.row(1).binLocation
).toHaveText(binLocationName);
});

await test.step('Go to product page and assert bin location', async () => {
await stockMovementShowPage.packingListTable.row(1).product.click();
await productShowPage.inStockTab.click();
await productShowPage.inStockTabSection.isLoaded();
await expect(
productShowPage.inStockTabSection.row(2).binLocation
).toHaveText(binLocationName);
});
});
});

0 comments on commit 6045702

Please sign in to comment.