Skip to content

Commit 522fad4

Browse files
authored
OBPIH-7035 Export stock movements from inbound list (#57)
* add test for export inbound stock movements * add selectors to inbound list page * add test for my stock movements filter and click on stocklist header should not remove table content * add assertion for date creadd to inbound stock movement show page * add elements to page * add test for edit destination in shipped inbound * add elements to stock movement show page
1 parent 0af9292 commit 522fad4

8 files changed

Lines changed: 375 additions & 0 deletions

File tree

src/pages/inbound/list/InboundListPage.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ class InboundListPage extends BasePageModel {
2525
return this.page.getByRole('link', { name: 'Export all incoming items' });
2626
}
2727

28+
get exportStockMovementsButton() {
29+
return this.page.getByRole('button', { name: 'Export Stock Movements' });
30+
}
31+
32+
get myStockMovementsButton() {
33+
return this.page.getByRole('button', { name: 'My Stock Movements' });
34+
}
35+
2836
async goToPage() {
2937
await this.page.goto('./stockMovement/list?direction=INBOUND');
3038
}
@@ -57,6 +65,13 @@ class InboundListPage extends BasePageModel {
5765
await this.exportAllIncomingItemsButton.click();
5866
return await this.fileHandler.saveFile();
5967
}
68+
69+
async exportStockMovements() {
70+
await this.fileHandler.onDownload();
71+
await this.exportDropdownButton.click();
72+
await this.exportStockMovementsButton.click();
73+
return await this.fileHandler.saveFile();
74+
}
6075
}
6176

6277
export default InboundListPage;

src/pages/inbound/list/InboundStockMovementTable.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ class InboundStockMovementTable extends BasePageModel {
3030
get emptyInboundList() {
3131
return this.table.locator('.rt-noData');
3232
}
33+
34+
get stocklistColumnHeader() {
35+
return this.table.getByRole('button', { name: 'Stocklist' });
36+
}
3337
}
3438

3539
class Row extends BasePageModel {

src/pages/stockMovementShow/StockMovementShowPage.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ class StockMovementShowPage extends BasePageModel {
4444
return this.summary.getByTestId('status-tag');
4545
}
4646

47+
get title() {
48+
return this.summary.getByTestId('title');
49+
}
50+
4751
// TABS
4852
get packingListTab() {
4953
return this.page.getByRole('tab', { name: 'Packing List' });

src/pages/stockMovementShow/components/DetailsTable.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@ class DetailsTable extends BasePageModel {
2222
get identifierValue() {
2323
return this.identifierRow.locator('.value');
2424
}
25+
26+
get destinationRow() {
27+
return this.rows.filter({ hasText: 'Destination' });
28+
}
29+
30+
get destinationValue() {
31+
return this.destinationRow.locator('.value');
32+
}
2533
}
2634

2735
export default DetailsTable;

src/tests/inbound/createInbound/createInbound.test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,11 @@ test.describe('Create inbound stock movement', () => {
163163
).toContainText(
164164
`${formatDate(new Date(), 'DD/MMM/YYYY')} by ${USER.name}`
165165
);
166+
await expect(
167+
stockMovementShowPage.auditingTable.dateCreatedRow
168+
).toContainText(
169+
`${formatDate(new Date(), 'DD/MMM/YYYY')} by ${USER.name}`
170+
);
166171
});
167172
});
168173
});
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import AppConfig from '@/config/AppConfig';
2+
import { ShipmentType } from '@/constants/ShipmentType';
3+
import { expect, test } from '@/fixtures/fixtures';
4+
import { StockMovementResponse } from '@/types';
5+
6+
test.describe('Edit destination from send page', () => {
7+
let STOCK_MOVEMENT: StockMovementResponse;
8+
9+
test.beforeEach(
10+
async ({
11+
supplierLocationService,
12+
stockMovementService,
13+
otherProductService,
14+
thirdProductService,
15+
}) => {
16+
const supplierLocation = await supplierLocationService.getLocation();
17+
const PRODUCT_TWO = await otherProductService.getProduct();
18+
const PRODUCT_THREE = await thirdProductService.getProduct();
19+
20+
STOCK_MOVEMENT = await stockMovementService.createInbound({
21+
originId: supplierLocation.id,
22+
});
23+
24+
await stockMovementService.addItemsToInboundStockMovement(
25+
STOCK_MOVEMENT.id,
26+
[
27+
{ productId: PRODUCT_TWO.id, quantity: 100 },
28+
{ productId: PRODUCT_THREE.id, quantity: 200 },
29+
]
30+
);
31+
32+
await stockMovementService.sendInboundStockMovement(STOCK_MOVEMENT.id, {
33+
shipmentType: ShipmentType.AIR,
34+
});
35+
}
36+
);
37+
38+
test.afterEach(
39+
async ({ stockMovementShowPage, stockMovementService, authService }) => {
40+
await authService.changeLocation(AppConfig.instance.locations.depot.id);
41+
await stockMovementShowPage.goToPage(STOCK_MOVEMENT.id);
42+
await stockMovementShowPage.rollbackButton.click();
43+
await stockMovementService.deleteStockMovement(STOCK_MOVEMENT.id);
44+
await authService.changeLocation(AppConfig.instance.locations.main.id);
45+
}
46+
);
47+
48+
test('Edit destination from Send Page', async ({
49+
stockMovementShowPage,
50+
createInboundPage,
51+
depotLocationService,
52+
}) => {
53+
const updatedDestination = await depotLocationService.getLocation();
54+
55+
await test.step('Go to stock movement show page', async () => {
56+
await stockMovementShowPage.goToPage(STOCK_MOVEMENT.id);
57+
await stockMovementShowPage.isLoaded();
58+
});
59+
60+
await test.step('Go to Send page od shipped sm and edit destination', async () => {
61+
await stockMovementShowPage.editButton.click();
62+
await createInboundPage.sendStep.isLoaded();
63+
await createInboundPage.sendStep.destinationSelect.findAndSelectOption(
64+
updatedDestination.name
65+
);
66+
await createInboundPage.sendStep.saveAndExitButton.click();
67+
await stockMovementShowPage.isLoaded();
68+
});
69+
70+
await test.step('Assert edited destination on show page', async () => {
71+
await stockMovementShowPage.isLoaded();
72+
await expect(
73+
stockMovementShowPage.detailsListTable.destinationValue
74+
).toHaveText(updatedDestination.name);
75+
await expect(stockMovementShowPage.title).toContainText(
76+
`${updatedDestination.locationNumber}`
77+
);
78+
});
79+
});
80+
});
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
import { ShipmentType } from '@/constants/ShipmentType';
2+
import { expect, test } from '@/fixtures/fixtures';
3+
import { StockMovementResponse } from '@/types';
4+
import { formatDate, getToday } from '@/utils/DateUtils';
5+
import { WorkbookUtils } from '@/utils/WorkbookUtils';
6+
7+
test.describe('Export stock movements', () => {
8+
let INBOUND1: StockMovementResponse;
9+
let INBOUND2: StockMovementResponse;
10+
const workbooks: WorkbookUtils[] = [];
11+
const TODAY = getToday();
12+
13+
test.beforeEach(
14+
async ({
15+
supplierLocationService,
16+
stockMovementService,
17+
mainProductService,
18+
otherProductService,
19+
}) => {
20+
const supplierLocation = await supplierLocationService.getLocation();
21+
const PRODUCT_ONE = await mainProductService.getProduct();
22+
const PRODUCT_TWO = await otherProductService.getProduct();
23+
24+
INBOUND1 = await stockMovementService.createInbound({
25+
originId: supplierLocation.id,
26+
});
27+
28+
await stockMovementService.addItemsToInboundStockMovement(INBOUND1.id, [
29+
{
30+
productId: PRODUCT_ONE.id,
31+
quantity: 50,
32+
},
33+
{ productId: PRODUCT_TWO.id, quantity: 100 },
34+
]);
35+
36+
await stockMovementService.sendInboundStockMovement(INBOUND1.id, {
37+
shipmentType: ShipmentType.AIR,
38+
});
39+
40+
INBOUND2 = await stockMovementService.createInbound({
41+
originId: supplierLocation.id,
42+
});
43+
44+
await stockMovementService.addItemsToInboundStockMovement(INBOUND2.id, [
45+
{
46+
productId: PRODUCT_ONE.id,
47+
quantity: 50,
48+
},
49+
]);
50+
}
51+
);
52+
53+
test.afterEach(async ({ stockMovementService, stockMovementShowPage }) => {
54+
await stockMovementShowPage.goToPage(INBOUND1.id);
55+
await stockMovementShowPage.isLoaded();
56+
await stockMovementShowPage.rollbackButton.click();
57+
await stockMovementService.deleteStockMovement(INBOUND1.id);
58+
await stockMovementShowPage.goToPage(INBOUND2.id);
59+
await stockMovementShowPage.isLoaded();
60+
await stockMovementService.deleteStockMovement(INBOUND2.id);
61+
62+
for (const workbook of workbooks) {
63+
workbook.delete();
64+
}
65+
});
66+
67+
test('Export Stock Movements', async ({ inboundListPage }) => {
68+
await test.step('Go to inbound list page', async () => {
69+
await inboundListPage.goToPage();
70+
});
71+
72+
let filePath: string;
73+
let exportStockMovements: WorkbookUtils;
74+
75+
const ROWS = [
76+
{
77+
status: 'CHECKING',
78+
receiptStatus: 'PENDING',
79+
identifier: INBOUND2.identifier,
80+
name: INBOUND2.description,
81+
origin: INBOUND2.origin.name,
82+
destination: INBOUND2.destination.name,
83+
stocklist: undefined,
84+
requestedBy: INBOUND2.requestedBy.name,
85+
dateRequested: INBOUND2.dateRequested.replace(/\//g, '-'),
86+
dateCreated: INBOUND2.dateCreated.replace(/\//g, '-'),
87+
dateShipped: formatDate(TODAY, 'MM-DD-YYYY'),
88+
},
89+
{
90+
status: 'ISSUED',
91+
receiptStatus: 'SHIPPED',
92+
identifier: INBOUND1.identifier,
93+
name: INBOUND1.description,
94+
origin: INBOUND1.origin.name,
95+
destination: INBOUND1.destination.name,
96+
stocklist: undefined,
97+
requestedBy: INBOUND1.requestedBy.name,
98+
dateRequested: INBOUND1.dateRequested.replace(/\//g, '-'),
99+
dateCreated: INBOUND1.dateCreated.replace(/\//g, '-'),
100+
dateShipped: formatDate(TODAY, 'MM-DD-YYYY'),
101+
},
102+
];
103+
104+
await test.step('Download file', async () => {
105+
const { fullFilePath } = await inboundListPage.exportStockMovements();
106+
filePath = fullFilePath;
107+
});
108+
109+
let parsedDocumentData: unknown[][];
110+
111+
await test.step('Read file', async () => {
112+
exportStockMovements = WorkbookUtils.read(filePath);
113+
workbooks.push(exportStockMovements);
114+
parsedDocumentData = exportStockMovements.getData();
115+
});
116+
117+
await test.step('Assert template columns', async () => {
118+
expect(exportStockMovements.getHeaders()).toStrictEqual([
119+
'Status',
120+
'Receipt Status',
121+
'Identifier',
122+
'Name',
123+
'Origin',
124+
'Destination',
125+
'Stocklist',
126+
'Requested by',
127+
'Date Requested',
128+
'Date Created',
129+
'Date Shipped',
130+
]);
131+
});
132+
133+
for (let i = 0; i < ROWS.length; i++) {
134+
await test.step(`Assert data of exported template on row: ${i}`, async () => {
135+
const documentRow = parsedDocumentData[i];
136+
const row = ROWS[i];
137+
138+
expect(documentRow[0]).toEqual(row.status);
139+
expect(documentRow[1]).toEqual(row.receiptStatus);
140+
expect(documentRow[2]).toEqual(row.identifier);
141+
expect(documentRow[3]).toEqual(row.name);
142+
expect(documentRow[4]).toEqual(row.origin);
143+
expect(documentRow[5]).toEqual(row.destination);
144+
expect(documentRow[6]).toEqual(row.stocklist);
145+
expect(documentRow[7]).toEqual(row.requestedBy);
146+
expect(documentRow[8]).toEqual(row.dateRequested);
147+
expect(documentRow[9]).toEqual(row.dateCreated);
148+
expect(documentRow[10]).toEqual(row.dateShipped);
149+
});
150+
}
151+
152+
await test.step('Use search bar and apply filtering', async () => {
153+
await inboundListPage.filters.searchField.textbox.fill(
154+
INBOUND2.identifier
155+
);
156+
await inboundListPage.search();
157+
});
158+
159+
await test.step('Download filtered file', async () => {
160+
const { fullFilePath } = await inboundListPage.exportStockMovements();
161+
filePath = fullFilePath;
162+
});
163+
164+
await test.step('Read file', async () => {
165+
exportStockMovements = WorkbookUtils.read(filePath);
166+
workbooks.push(exportStockMovements);
167+
parsedDocumentData = exportStockMovements.getData();
168+
expect(parsedDocumentData).toHaveLength(1);
169+
});
170+
171+
await test.step('Assert filtered file', async () => {
172+
const documentRow = parsedDocumentData[0];
173+
expect(documentRow[2]).toEqual(ROWS[0].identifier);
174+
});
175+
});
176+
});

0 commit comments

Comments
 (0)