mirror of
https://github.com/inventree/InvenTree.git
synced 2026-02-14 02:07:13 +00:00
[UI] Barcode form inputs (#10973)
* Add barcode buttons to related fields - Only field types which support barcodes * Add per-user settings for barcode support * Fill form field with scanned data * Updated docs * Fix duplicate setting * Add playwright tests * Fix duplicate setting in docs * Fix broken link * Fix memo deps * Fix typo * Remove setting * Updated playwright tests * Improved typing
This commit is contained in:
@@ -54,7 +54,11 @@ export const clearTableFilters = async (page: Page) => {
|
||||
await page.waitForLoadState('networkidle');
|
||||
};
|
||||
|
||||
export const setTableChoiceFilter = async (page: Page, filter, value) => {
|
||||
export const setTableChoiceFilter = async (
|
||||
page: Page,
|
||||
filter: string,
|
||||
value: string
|
||||
) => {
|
||||
await openFilterDrawer(page);
|
||||
|
||||
await page.getByRole('button', { name: 'Add Filter' }).click();
|
||||
@@ -116,7 +120,7 @@ export const navigate = async (
|
||||
/**
|
||||
* CLick on the 'tab' element with the provided name
|
||||
*/
|
||||
export const loadTab = async (page: Page, tabName, exact?) => {
|
||||
export const loadTab = async (page: Page, tabName: string, exact?: boolean) => {
|
||||
await page
|
||||
.getByLabel(/panel-tabs-/)
|
||||
.getByRole('tab', { name: tabName, exact: exact ?? false })
|
||||
@@ -140,7 +144,7 @@ export const activateCalendarView = async (page: Page) => {
|
||||
/**
|
||||
* Perform a 'global search' on the provided page, for the provided query text
|
||||
*/
|
||||
export const globalSearch = async (page: Page, query) => {
|
||||
export const globalSearch = async (page: Page, query: string) => {
|
||||
await page.getByLabel('open-search').click();
|
||||
await page.getByLabel('global-search-input').clear();
|
||||
await page.getByPlaceholder('Enter search text').fill(query);
|
||||
|
||||
@@ -14,7 +14,7 @@ interface LoginOptions {
|
||||
/*
|
||||
* Perform form based login operation from the "login" URL
|
||||
*/
|
||||
export const doLogin = async (page, options?: LoginOptions) => {
|
||||
export const doLogin = async (page: Page, options?: LoginOptions) => {
|
||||
const username: string = options?.username ?? user.username;
|
||||
const password: string = options?.password ?? user.password;
|
||||
|
||||
|
||||
@@ -225,7 +225,9 @@ test('Purchase Orders - Barcodes', async ({ browser }) => {
|
||||
// Ensure we can scan back to this page, with the associated barcode
|
||||
await page.getByRole('tab', { name: 'Sales' }).click();
|
||||
await page.waitForTimeout(250);
|
||||
await page.getByRole('button', { name: 'Open Barcode Scanner' }).click();
|
||||
|
||||
await page.getByRole('button', { name: 'barcode-scan-button-any' }).click();
|
||||
|
||||
await page.getByPlaceholder('Enter barcode data').fill('1234567890');
|
||||
await page.getByRole('button', { name: 'Scan', exact: true }).click();
|
||||
|
||||
|
||||
@@ -1,24 +1,37 @@
|
||||
import type { Page } from '@playwright/test';
|
||||
import { test } from '../baseFixtures';
|
||||
import { doCachedLogin } from '../login';
|
||||
|
||||
const scan = async (page, barcode) => {
|
||||
const scan = async (page: Page, barcode: string) => {
|
||||
await page.getByLabel('barcode-input-scanner').click();
|
||||
await page.getByLabel('barcode-scan-keyboard-input').fill(barcode);
|
||||
await page.getByRole('button', { name: 'Scan', exact: true }).click();
|
||||
};
|
||||
|
||||
test('Scanning - Dialog', async ({ browser }) => {
|
||||
test('Barcode Scanning - Dialog', async ({ browser }) => {
|
||||
const page = await doCachedLogin(browser);
|
||||
|
||||
await page.getByRole('button', { name: 'Open Barcode Scanner' }).click();
|
||||
// Attempt scan with invalid data
|
||||
await page.getByRole('button', { name: 'barcode-scan-button-any' }).click();
|
||||
await scan(page, 'invalid-barcode-123');
|
||||
await page.getByText('No match found for barcode').waitFor();
|
||||
|
||||
// Attempt scan with "legacy" barcode format
|
||||
await scan(page, '{"part": 15}');
|
||||
|
||||
await page.getByText('Part: R_550R_0805_1%', { exact: true }).waitFor();
|
||||
await page.getByText('Available:').waitFor();
|
||||
await page.getByText('Required:').waitFor();
|
||||
|
||||
// Attempt scan with "modern" barcode format
|
||||
await page.getByRole('button', { name: 'barcode-scan-button-any' }).click();
|
||||
await scan(page, 'INV-BO0010');
|
||||
|
||||
await page.getByText('Build Order: BO0010').waitFor();
|
||||
await page.getByText('Making a high level assembly part').waitFor();
|
||||
});
|
||||
|
||||
test('Scanning - Basic', async ({ browser }) => {
|
||||
test('Barcode Scanning - Basic', async ({ browser }) => {
|
||||
const page = await doCachedLogin(browser);
|
||||
|
||||
// Navigate to the 'scan' page
|
||||
@@ -39,7 +52,7 @@ test('Scanning - Basic', async ({ browser }) => {
|
||||
await page.getByText('No match found for barcode').waitFor();
|
||||
});
|
||||
|
||||
test('Scanning - Part', async ({ browser }) => {
|
||||
test('Barcode Scanning - Part', async ({ browser }) => {
|
||||
const page = await doCachedLogin(browser, { url: 'scan/' });
|
||||
|
||||
await scan(page, '{"part": 1}');
|
||||
@@ -49,7 +62,7 @@ test('Scanning - Part', async ({ browser }) => {
|
||||
await page.getByRole('cell', { name: 'part', exact: true }).waitFor();
|
||||
});
|
||||
|
||||
test('Scanning - Stockitem', async ({ browser }) => {
|
||||
test('Barcode Scanning - Stockitem', async ({ browser }) => {
|
||||
const page = await doCachedLogin(browser, { url: 'scan/' });
|
||||
await scan(page, '{"stockitem": 408}');
|
||||
|
||||
@@ -58,7 +71,7 @@ test('Scanning - Stockitem', async ({ browser }) => {
|
||||
await page.getByRole('cell', { name: 'Quantity: 100' }).waitFor();
|
||||
});
|
||||
|
||||
test('Scanning - StockLocation', async ({ browser }) => {
|
||||
test('Barcode Scanning - StockLocation', async ({ browser }) => {
|
||||
const page = await doCachedLogin(browser, { url: 'scan/' });
|
||||
|
||||
await scan(page, '{"stocklocation": 3}');
|
||||
@@ -71,7 +84,7 @@ test('Scanning - StockLocation', async ({ browser }) => {
|
||||
.waitFor();
|
||||
});
|
||||
|
||||
test('Scanning - SupplierPart', async ({ browser }) => {
|
||||
test('Barcode Scanning - SupplierPart', async ({ browser }) => {
|
||||
const page = await doCachedLogin(browser, { url: 'scan/' });
|
||||
await scan(page, '{"supplierpart": 204}');
|
||||
|
||||
@@ -80,7 +93,7 @@ test('Scanning - SupplierPart', async ({ browser }) => {
|
||||
await page.getByRole('cell', { name: 'supplierpart', exact: true }).waitFor();
|
||||
});
|
||||
|
||||
test('Scanning - PurchaseOrder', async ({ browser }) => {
|
||||
test('Barcode Scanning - PurchaseOrder', async ({ browser }) => {
|
||||
const page = await doCachedLogin(browser, { url: 'scan/' });
|
||||
await scan(page, '{"purchaseorder": 12}');
|
||||
|
||||
@@ -92,7 +105,7 @@ test('Scanning - PurchaseOrder', async ({ browser }) => {
|
||||
.waitFor();
|
||||
});
|
||||
|
||||
test('Scanning - SalesOrder', async ({ browser }) => {
|
||||
test('Barcode Scanning - SalesOrder', async ({ browser }) => {
|
||||
const page = await doCachedLogin(browser, { url: 'scan/' });
|
||||
|
||||
await scan(page, '{"salesorder": 6}');
|
||||
@@ -103,7 +116,7 @@ test('Scanning - SalesOrder', async ({ browser }) => {
|
||||
await page.getByRole('cell', { name: 'salesorder', exact: true }).waitFor();
|
||||
});
|
||||
|
||||
test('Scanning - Build', async ({ browser }) => {
|
||||
test('Barcode Scanning - Build', async ({ browser }) => {
|
||||
const page = await doCachedLogin(browser, { url: 'scan/' });
|
||||
await scan(page, '{"build": 8}');
|
||||
|
||||
@@ -112,3 +125,32 @@ test('Scanning - Build', async ({ browser }) => {
|
||||
await page.getByText('PCBA build').waitFor();
|
||||
await page.getByRole('cell', { name: 'build', exact: true }).waitFor();
|
||||
});
|
||||
|
||||
test('Barcode Scanning - Forms', async ({ browser }) => {
|
||||
const page = await doCachedLogin(browser, {
|
||||
url: '/stock/location/index/stock-items'
|
||||
});
|
||||
|
||||
// Open the "Add Stock Item" form
|
||||
await page
|
||||
.getByRole('button', { name: 'action-button-add-stock-item' })
|
||||
.click();
|
||||
|
||||
// Fill out the "part" data
|
||||
await page.getByRole('button', { name: 'barcode-scan-button-part' }).click();
|
||||
await page
|
||||
.getByRole('textbox', { name: 'barcode-scan-keyboard-input' })
|
||||
.fill('INV-PA99');
|
||||
await page.getByRole('button', { name: 'Scan', exact: true }).click();
|
||||
await page.getByText('Red Round Table').waitFor();
|
||||
|
||||
// Fill out the "location" data
|
||||
await page
|
||||
.getByRole('button', { name: 'barcode-scan-button-stocklocation' })
|
||||
.click();
|
||||
await page
|
||||
.getByRole('textbox', { name: 'barcode-scan-keyboard-input' })
|
||||
.fill('INV-SL37');
|
||||
await page.getByRole('button', { name: 'Scan', exact: true }).click();
|
||||
await page.getByText('Offsite Storage').waitFor();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user