From 6c944c73dd2ab5b858ce12290db7217b302161cd Mon Sep 17 00:00:00 2001 From: Matthias Mair Date: Tue, 7 May 2024 09:36:35 +0200 Subject: [PATCH] [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. --- src/frontend/playwright.config.ts | 1 + src/frontend/src/pages/Index/Scan.tsx | 70 +++++++----- src/frontend/tests/pages/pui_scan.spec.ts | 132 ++++++++++++++++++++++ 3 files changed, 176 insertions(+), 27 deletions(-) create mode 100644 src/frontend/tests/pages/pui_scan.spec.ts diff --git a/src/frontend/playwright.config.ts b/src/frontend/playwright.config.ts index 91e32c27ca..f24b94d323 100644 --- a/src/frontend/playwright.config.ts +++ b/src/frontend/playwright.config.ts @@ -3,6 +3,7 @@ import { defineConfig, devices } from '@playwright/test'; export default defineConfig({ testDir: './tests', fullyParallel: true, + timeout: 60000, forbidOnly: !!process.env.CI, retries: process.env.CI ? 1 : 0, workers: process.env.CI ? 2 : undefined, diff --git a/src/frontend/src/pages/Index/Scan.tsx b/src/frontend/src/pages/Index/Scan.tsx index 82c1e23637..bfa329fff8 100644 --- a/src/frontend/src/pages/Index/Scan.tsx +++ b/src/frontend/src/pages/Index/Scan.tsx @@ -42,7 +42,7 @@ import { } from '@tabler/icons-react'; import { Html5Qrcode } from 'html5-qrcode'; import { CameraDevice } from 'html5-qrcode/camera/core'; -import { useEffect, useState } from 'react'; +import { ReactNode, useEffect, useState } from 'react'; import { api } from '../../App'; import { DocInfo } from '../../components/items/DocInfo'; @@ -169,15 +169,17 @@ export default function Scan() { .get(url) .then((response) => { item.instance = response.data; + const list_idx = history.findIndex((i) => i.id === id); + historyHandlers.setItem(list_idx, item); }) .catch((err) => { console.error('error while fetching instance data at', url); console.info(err); }); } + } else { + historyHandlers.setState(history); } - - historyHandlers.setState(history); }) .catch((err) => { // 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.`} /> - @@ -364,7 +371,11 @@ export default function Scan() { > History - + @@ -398,30 +409,35 @@ function HistoryTable({ setSelection((current) => current.length === data.length ? [] : data.map((item) => item.id) ); + const [rows, setRows] = useState(); - const rows = data.map((item) => { - return ( - - - toggleRow(item.id)} - transitionDuration={0} - /> - - - {item.pk && item.model && item.instance ? ( - - ) : ( - item.ref - )} - - {item.model} - {item.source} - {item.timestamp?.toString()} - + useEffect(() => { + setRows( + data.map((item) => { + return ( + + + toggleRow(item.id)} + transitionDuration={0} + /> + + + {item.pk && item.model && item.instance ? ( + + ) : ( + item.ref + )} + + {item.model} + {item.source} + {item.timestamp?.toString()} + + ); + }) ); - }); + }, [data, selection]); // rendering if (data.length === 0) diff --git a/src/frontend/tests/pages/pui_scan.spec.ts b/src/frontend/tests/pages/pui_scan.spec.ts new file mode 100644 index 0000000000..66acaf514b --- /dev/null +++ b/src/frontend/tests/pages/pui_scan.spec.ts @@ -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); +});