[PUI] Test for errors in console (#7114)

* ensure no errors are thrown in the console

* fix key issue

* add missing keys

* fix table order

* fix wrong imports

* add missing key

* fix accessor ref

* fix style

* mark internal fetching errors and ignore them

* do not raise internal errors

* ignore barcode api calls

* style fix

* do not raise on chrome errors

* refactor url

* more exclusion

* remove duplicate assertation
This commit is contained in:
Matthias Mair 2024-04-25 11:26:04 +02:00 committed by GitHub
parent 47c797db88
commit b5b0ff2666
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 62 additions and 27 deletions

View File

@ -5,7 +5,6 @@ export type DetailsBadgeProps = {
label: string;
size?: string;
visible?: boolean;
key?: any;
};
export default function DetailsBadge(props: DetailsBadgeProps) {
@ -14,12 +13,7 @@ export default function DetailsBadge(props: DetailsBadgeProps) {
}
return (
<Badge
key={props.key}
color={props.color}
variant="filled"
size={props.size ?? 'lg'}
>
<Badge color={props.color} variant="filled" size={props.size ?? 'lg'}>
{props.label}
</Badge>
);

View File

@ -1,7 +1,6 @@
import { Group, Paper, Space, Stack, Text } from '@mantine/core';
import { Fragment, ReactNode } from 'react';
import DetailsBadge, { DetailsBadgeProps } from '../details/DetailsBadge';
import { ApiImage } from '../images/ApiImage';
import { StylishText } from '../items/StylishText';
import { Breadcrumb, BreadcrumbList } from './BreadcrumbList';
@ -60,7 +59,9 @@ export function PageDetail({
<Space />
{detail}
<Group position="right" spacing="xs" noWrap>
{badges}
{badges?.map((badge, idx) => (
<Fragment key={idx}>{badge}</Fragment>
))}
</Group>
<Space />
{actions && (

View File

@ -448,7 +448,11 @@ export default function PartDetail() {
<Grid.Col span={8}>
<Stack spacing="xs">
<table>
<PartIcons part={part} />
<tbody>
<tr>
<PartIcons part={part} />
</tr>
</tbody>
</table>
<DetailsTable fields={tl} item={part} />
</Stack>
@ -642,23 +646,32 @@ export default function PartDetail() {
label={t`In Stock` + `: ${part.in_stock}`}
color={part.in_stock >= part.minimum_stock ? 'green' : 'orange'}
visible={part.in_stock > 0}
key="in_stock"
/>,
<DetailsBadge
label={t`No Stock`}
color="red"
visible={part.in_stock == 0}
key="no_stock"
/>,
<DetailsBadge
label={t`On Order` + `: ${part.ordering}`}
color="blue"
visible={part.on_order > 0}
key="on_order"
/>,
<DetailsBadge
label={t`In Production` + `: ${part.building}`}
color="blue"
visible={part.building > 0}
key="in_production"
/>,
<DetailsBadge label={t`Inactive`} color="red" visible={!part.active} />
<DetailsBadge
label={t`Inactive`}
color="red"
visible={!part.active}
key="inactive"
/>
];
}, [part, instanceQuery]);
@ -706,6 +719,7 @@ export default function PartDetail() {
hidden: !part?.barcode_hash || !user.hasChangeRole(UserRoles.part)
})
]}
key="action_dropdown"
/>,
<ActionDropdown
key="stock"

View File

@ -186,7 +186,11 @@ export default function PricingOverviewPanel({
</Alert>
</Paper>
)}
<DataTable records={overviewData} columns={columns} />
<DataTable
idAccessor="name"
records={overviewData}
columns={columns}
/>
</Stack>
<ResponsiveContainer width="100%" height={500}>
<BarChart data={overviewData} id="pricing-overview-chart">

View File

@ -322,6 +322,7 @@ export default function SalesOrderDetail() {
status={order.status}
type={ModelType.salesorder}
options={{ size: 'lg' }}
key={order.pk}
/>
];
}, [order, instanceQuery]);

View File

@ -473,21 +473,25 @@ export default function StockDetail() {
color="blue"
label={t`Serial Number` + `: ${stockitem.serial}`}
visible={!!stockitem.serial}
key="serial"
/>,
<DetailsBadge
color="blue"
label={t`Quantity` + `: ${stockitem.quantity}`}
visible={!stockitem.serial}
key="quantity"
/>,
<DetailsBadge
color="blue"
label={t`Batch Code` + `: ${stockitem.batch}`}
visible={!!stockitem.batch}
key="batch"
/>,
<StatusRenderer
status={stockitem.status}
type={ModelType.stockitem}
options={{ size: 'lg' }}
key="status"
/>
];
}, [stockitem, instanceQuery]);

View File

@ -26,7 +26,7 @@ export const useServerApiState = create<ServerApiStateProps>()(
set({ server: response.data });
})
.catch(() => {
console.error('Error fetching server info');
console.error('ERR: Error fetching server info');
});
// Fetch login/SSO behaviour
@ -38,7 +38,7 @@ export const useServerApiState = create<ServerApiStateProps>()(
set({ auth_settings: response.data });
})
.catch(() => {
console.error('Error fetching SSO information');
console.error('ERR: Error fetching SSO information');
});
},
status: undefined

View File

@ -42,7 +42,7 @@ export const useGlobalSettingsState = create<SettingsStateProps>(
});
})
.catch((_error) => {
console.error('Error fetching global settings');
console.error('ERR: Error fetching global settings');
});
},
getSetting: (key: string, default_value?: string) => {
@ -76,7 +76,7 @@ export const useUserSettingsState = create<SettingsStateProps>((set, get) => ({
});
})
.catch((_error) => {
console.error('Error fetching user settings');
console.error('ERR: Error fetching user settings');
});
},
getSetting: (key: string, default_value?: string) => {

View File

@ -39,7 +39,7 @@ export const useGlobalStatusState = create<ServerStateProps>()(
set({ status: newStatusLookup });
})
.catch(() => {
console.error('Error fetching global status information');
console.error('ERR: Error fetching global status information');
});
}
}),

View File

@ -57,7 +57,7 @@ export const useUserState = create<UserStateProps>((set, get) => ({
set({ user: user });
})
.catch((error) => {
console.error('Error fetching user data');
console.error('ERR: Error fetching user data');
});
// Fetch role data
@ -75,7 +75,7 @@ export const useUserState = create<UserStateProps>((set, get) => ({
}
})
.catch((_error) => {
console.error('Error fetching user roles');
console.error('ERR: Error fetching user roles');
});
},
checkUserRole: (role: UserRoles, permission: UserPermissions) => {

View File

@ -153,6 +153,7 @@ export function BuildOrderTable({
hidden={!user.hasAddRole(UserRoles.build)}
tooltip={t`Add Build Order`}
onClick={() => newBuild.open()}
key="add-build-order"
/>
];
}, [user]);

View File

@ -68,7 +68,11 @@ export default function ErrorReportTable() {
onClose={close}
>
{error.split('\n').map((line: string) => {
return <Text size="sm">{line}</Text>;
return (
<Text key={line} size="sm">
{line}
</Text>
);
})}
</Drawer>
<InvenTreeTable

View File

@ -50,6 +50,24 @@ export const test = baseTest.extend({
)
);
}
},
// Ensure no errors are thrown in the console
page: async ({ baseURL, page }, use) => {
const messages = [];
page.on('console', (msg) => {
const url = msg.location().url;
if (
msg.type() === 'error' &&
!msg.text().startsWith('ERR: ') &&
url != 'http://localhost:8000/api/barcode/' &&
url != 'http://localhost:8000/api/news/?search=&offset=0&limit=25' &&
url != 'https://docs.inventree.org/en/versions.json' &&
!url.startsWith('chrome://')
)
messages.push(msg);
});
await use(page);
expect(messages).toEqual([]);
}
});

View File

@ -4,11 +4,6 @@ import { doQuickLogin } from './login.js';
test('PUI - Modals as admin', async ({ page }) => {
await doQuickLogin(page, 'admin', 'inventree');
// Fail on console error
await page.on('console', (msg) => {
if (msg.type() === 'error') test.fail();
});
// use server info
await page.getByRole('button', { name: 'Open spotlight' }).click();
await page

View File

@ -1,5 +1,4 @@
import { test } from '@playwright/test';
import { test } from '../baseFixtures';
import { baseUrl } from '../defaults';
import { doQuickLogin } from '../login';