2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-04-30 20:46:47 +00:00

[PUI] Add testing for Scanning page (#7165)

* use state to handle rerenders

* use setItem to cause rerenders on point

* add scan tests

* increase timeout

* fix name for test file

* renmae testcases

* Add ADA texts to help with testins / screen readers

* Add general function tests for scan page

* more coverage

* Revert "more coverage"

This reverts commit 67f600fb5e06da3c90bb0569ddaa395848a2cb0e.
This commit is contained in:
Matthias Mair 2024-05-07 09:36:35 +02:00 committed by GitHub
parent ecc3b25464
commit 6c944c73dd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 176 additions and 27 deletions

View File

@ -3,6 +3,7 @@ import { defineConfig, devices } from '@playwright/test';
export default defineConfig({ export default defineConfig({
testDir: './tests', testDir: './tests',
fullyParallel: true, fullyParallel: true,
timeout: 60000,
forbidOnly: !!process.env.CI, forbidOnly: !!process.env.CI,
retries: process.env.CI ? 1 : 0, retries: process.env.CI ? 1 : 0,
workers: process.env.CI ? 2 : undefined, workers: process.env.CI ? 2 : undefined,

View File

@ -42,7 +42,7 @@ import {
} from '@tabler/icons-react'; } from '@tabler/icons-react';
import { Html5Qrcode } from 'html5-qrcode'; import { Html5Qrcode } from 'html5-qrcode';
import { CameraDevice } from 'html5-qrcode/camera/core'; import { CameraDevice } from 'html5-qrcode/camera/core';
import { useEffect, useState } from 'react'; import { ReactNode, useEffect, useState } from 'react';
import { api } from '../../App'; import { api } from '../../App';
import { DocInfo } from '../../components/items/DocInfo'; import { DocInfo } from '../../components/items/DocInfo';
@ -169,15 +169,17 @@ export default function Scan() {
.get(url) .get(url)
.then((response) => { .then((response) => {
item.instance = response.data; item.instance = response.data;
const list_idx = history.findIndex((i) => i.id === id);
historyHandlers.setItem(list_idx, item);
}) })
.catch((err) => { .catch((err) => {
console.error('error while fetching instance data at', url); console.error('error while fetching instance data at', url);
console.info(err); console.info(err);
}); });
} }
} } else {
historyHandlers.setState(history); historyHandlers.setState(history);
}
}) })
.catch((err) => { .catch((err) => {
// 400 and no plugin means no match // 400 and no plugin means no match
@ -280,7 +282,12 @@ export default function Scan() {
text={t`This page can be used for continuously scanning items and taking actions on them.`} text={t`This page can be used for continuously scanning items and taking actions on them.`}
/> />
</Group> </Group>
<Button onClick={toggleFullscreen} size="sm" variant="subtle"> <Button
onClick={toggleFullscreen}
size="sm"
variant="subtle"
title={t`Toggle Fullscreen`}
>
{fullscreen ? <IconArrowsMaximize /> : <IconArrowsMinimize />} {fullscreen ? <IconArrowsMaximize /> : <IconArrowsMinimize />}
</Button> </Button>
</Group> </Group>
@ -364,7 +371,11 @@ export default function Scan() {
> >
<Trans>History</Trans> <Trans>History</Trans>
</TitleWithDoc> </TitleWithDoc>
<ActionIcon color="red" onClick={btnDeleteFullHistory}> <ActionIcon
color="red"
onClick={btnDeleteFullHistory}
title={t`Delete History`}
>
<IconTrash /> <IconTrash />
</ActionIcon> </ActionIcon>
</Group> </Group>
@ -398,8 +409,11 @@ function HistoryTable({
setSelection((current) => setSelection((current) =>
current.length === data.length ? [] : data.map((item) => item.id) current.length === data.length ? [] : data.map((item) => item.id)
); );
const [rows, setRows] = useState<ReactNode>();
const rows = data.map((item) => { useEffect(() => {
setRows(
data.map((item) => {
return ( return (
<tr key={item.id}> <tr key={item.id}>
<td> <td>
@ -421,7 +435,9 @@ function HistoryTable({
<td>{item.timestamp?.toString()}</td> <td>{item.timestamp?.toString()}</td>
</tr> </tr>
); );
}); })
);
}, [data, selection]);
// rendering // rendering
if (data.length === 0) if (data.length === 0)

View File

@ -0,0 +1,132 @@
import { test } from '../baseFixtures';
import { baseUrl } from '../defaults';
import { doQuickLogin } from '../login';
async function defaultScanTest(page, search_text) {
await doQuickLogin(page);
await page.goto(`${baseUrl}/scan`);
await page.getByPlaceholder('Select input method').click();
await page.getByRole('option', { name: 'Manual input' }).click();
await page.getByPlaceholder('Enter item serial or data').click();
// nonsense data
await page.getByPlaceholder('Enter item serial or data').fill('123');
await page.getByPlaceholder('Enter item serial or data').press('Enter');
await page.getByRole('cell', { name: '123' }).click();
await page.getByRole('cell', { name: 'manually' }).click();
await page.getByRole('button', { name: 'Lookup part' }).click();
await page.getByRole('button', { name: 'Delete', exact: true }).click();
await page.getByPlaceholder('Enter item serial or data').fill(search_text);
await page.getByPlaceholder('Enter item serial or data').press('Enter');
await page.getByRole('checkbox').nth(2).check();
await page.getByRole('button', { name: 'Lookup part' }).click();
}
test('PUI - Pages - Index - Scan (Part)', async ({ page }) => {
await defaultScanTest(page, '{"part": 1}');
// part: 1
await page.getByText('R_10R_0402_1%').waitFor();
await page.getByText('Stock:').waitFor();
await page.getByRole('cell', { name: 'part' }).waitFor();
});
test('PUI - Pages - Index - Scan (Stockitem)', async ({ page }) => {
await defaultScanTest(page, '{"stockitem": 408}');
// stockitem: 408
await page.getByText('1551ABK').waitFor();
await page.getByText('Quantity: 145').waitFor();
await page.getByRole('cell', { name: 'Quantity: 145' }).waitFor();
});
test('PUI - Pages - Index - Scan (StockLocation)', async ({ page }) => {
await defaultScanTest(page, '{"stocklocation": 3}');
// stocklocation: 3
await page.getByText('Storage Room B', { exact: true }).waitFor();
await page.getByText('Storage Room B (green door)').waitFor();
await page.getByRole('cell', { name: 'stocklocation' }).waitFor();
});
test('PUI - Pages - Index - Scan (SupplierPart)', async ({ page }) => {
await defaultScanTest(page, '{"supplierpart": 204}');
// supplierpart: 204
await page.waitForTimeout(1000);
await page.getByText('1551ABK').first().waitFor();
await page.getByRole('cell', { name: 'supplierpart' }).waitFor();
});
test('PUI - Pages - Index - Scan (PurchaseOrder)', async ({ page }) => {
await defaultScanTest(page, '{"purchaseorder": 12}');
// purchaseorder: 12
await page.getByText('PO0012').waitFor();
await page.getByText('Wire from Wirey').waitFor();
await page.getByRole('cell', { name: 'purchaseorder' }).waitFor();
});
test('PUI - Pages - Index - Scan (SalesOrder)', async ({ page }) => {
await defaultScanTest(page, '{"salesorder": 6}');
// salesorder: 6
await page.getByText('SO0006').waitFor();
await page.getByText('Selling more stuff to this').waitFor();
await page.getByRole('cell', { name: 'salesorder' }).waitFor();
});
test('PUI - Pages - Index - Scan (Build)', async ({ page }) => {
await defaultScanTest(page, '{"build": 8}');
// build: 8
await page.getByText('BO0008').waitFor();
await page.getByText('PCBA build').waitFor();
await page.getByRole('cell', { name: 'build', exact: true }).waitFor();
});
test('PUI - Pages - Index - Scan (General)', async ({ page }) => {
await defaultScanTest(page, '{"unknown": 312}');
await page.getByText('"unknown": 312').waitFor();
// checkAll
await page.getByRole('checkbox').nth(0).check();
// Delete
await page.getByRole('button', { name: 'Delete', exact: true }).click();
// Reload to check history is working
await page.goto(`${baseUrl}/scan`);
await page.getByText('"unknown": 312').waitFor();
// Clear history
await page.getByRole('button', { name: 'Delete History' }).click();
await page.getByText('No history').waitFor();
// reload again
await page.goto(`${baseUrl}/scan`);
await page.getByText('No history').waitFor();
// Empty dummy input
await page.getByPlaceholder('Enter item serial or data').fill('');
await page.getByPlaceholder('Enter item serial or data').press('Enter');
// Empty add dummy item
await page.getByRole('button', { name: 'Add dummy item' }).click();
// Empty plus sign
await page
.locator('div')
.filter({ hasText: /^InputAdd dummy item$/ })
.getByRole('button')
.first()
.click();
// Toggle fullscreen
await page.getByRole('button', { name: 'Toggle Fullscreen' }).click();
await page.waitForTimeout(1000);
await page.getByRole('button', { name: 'Toggle Fullscreen' }).click();
await page.waitForTimeout(1000);
});