Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OBPIH-6695 Add test for edit bin location in the middle of receipt #40

Merged
merged 6 commits into from
Jan 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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');
}
kkrawczyk123 marked this conversation as resolved.
Show resolved Hide resolved

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' });
}
kkrawczyk123 marked this conversation as resolved.
Show resolved Hide resolved
}

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 @@ -46,6 +46,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);
});
});
});