mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
[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:
parent
47c797db88
commit
b5b0ff2666
@ -5,7 +5,6 @@ export type DetailsBadgeProps = {
|
|||||||
label: string;
|
label: string;
|
||||||
size?: string;
|
size?: string;
|
||||||
visible?: boolean;
|
visible?: boolean;
|
||||||
key?: any;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function DetailsBadge(props: DetailsBadgeProps) {
|
export default function DetailsBadge(props: DetailsBadgeProps) {
|
||||||
@ -14,12 +13,7 @@ export default function DetailsBadge(props: DetailsBadgeProps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Badge
|
<Badge color={props.color} variant="filled" size={props.size ?? 'lg'}>
|
||||||
key={props.key}
|
|
||||||
color={props.color}
|
|
||||||
variant="filled"
|
|
||||||
size={props.size ?? 'lg'}
|
|
||||||
>
|
|
||||||
{props.label}
|
{props.label}
|
||||||
</Badge>
|
</Badge>
|
||||||
);
|
);
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { Group, Paper, Space, Stack, Text } from '@mantine/core';
|
import { Group, Paper, Space, Stack, Text } from '@mantine/core';
|
||||||
import { Fragment, ReactNode } from 'react';
|
import { Fragment, ReactNode } from 'react';
|
||||||
|
|
||||||
import DetailsBadge, { DetailsBadgeProps } from '../details/DetailsBadge';
|
|
||||||
import { ApiImage } from '../images/ApiImage';
|
import { ApiImage } from '../images/ApiImage';
|
||||||
import { StylishText } from '../items/StylishText';
|
import { StylishText } from '../items/StylishText';
|
||||||
import { Breadcrumb, BreadcrumbList } from './BreadcrumbList';
|
import { Breadcrumb, BreadcrumbList } from './BreadcrumbList';
|
||||||
@ -60,7 +59,9 @@ export function PageDetail({
|
|||||||
<Space />
|
<Space />
|
||||||
{detail}
|
{detail}
|
||||||
<Group position="right" spacing="xs" noWrap>
|
<Group position="right" spacing="xs" noWrap>
|
||||||
{badges}
|
{badges?.map((badge, idx) => (
|
||||||
|
<Fragment key={idx}>{badge}</Fragment>
|
||||||
|
))}
|
||||||
</Group>
|
</Group>
|
||||||
<Space />
|
<Space />
|
||||||
{actions && (
|
{actions && (
|
||||||
|
@ -448,7 +448,11 @@ export default function PartDetail() {
|
|||||||
<Grid.Col span={8}>
|
<Grid.Col span={8}>
|
||||||
<Stack spacing="xs">
|
<Stack spacing="xs">
|
||||||
<table>
|
<table>
|
||||||
<PartIcons part={part} />
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<PartIcons part={part} />
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<DetailsTable fields={tl} item={part} />
|
<DetailsTable fields={tl} item={part} />
|
||||||
</Stack>
|
</Stack>
|
||||||
@ -642,23 +646,32 @@ export default function PartDetail() {
|
|||||||
label={t`In Stock` + `: ${part.in_stock}`}
|
label={t`In Stock` + `: ${part.in_stock}`}
|
||||||
color={part.in_stock >= part.minimum_stock ? 'green' : 'orange'}
|
color={part.in_stock >= part.minimum_stock ? 'green' : 'orange'}
|
||||||
visible={part.in_stock > 0}
|
visible={part.in_stock > 0}
|
||||||
|
key="in_stock"
|
||||||
/>,
|
/>,
|
||||||
<DetailsBadge
|
<DetailsBadge
|
||||||
label={t`No Stock`}
|
label={t`No Stock`}
|
||||||
color="red"
|
color="red"
|
||||||
visible={part.in_stock == 0}
|
visible={part.in_stock == 0}
|
||||||
|
key="no_stock"
|
||||||
/>,
|
/>,
|
||||||
<DetailsBadge
|
<DetailsBadge
|
||||||
label={t`On Order` + `: ${part.ordering}`}
|
label={t`On Order` + `: ${part.ordering}`}
|
||||||
color="blue"
|
color="blue"
|
||||||
visible={part.on_order > 0}
|
visible={part.on_order > 0}
|
||||||
|
key="on_order"
|
||||||
/>,
|
/>,
|
||||||
<DetailsBadge
|
<DetailsBadge
|
||||||
label={t`In Production` + `: ${part.building}`}
|
label={t`In Production` + `: ${part.building}`}
|
||||||
color="blue"
|
color="blue"
|
||||||
visible={part.building > 0}
|
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]);
|
}, [part, instanceQuery]);
|
||||||
|
|
||||||
@ -706,6 +719,7 @@ export default function PartDetail() {
|
|||||||
hidden: !part?.barcode_hash || !user.hasChangeRole(UserRoles.part)
|
hidden: !part?.barcode_hash || !user.hasChangeRole(UserRoles.part)
|
||||||
})
|
})
|
||||||
]}
|
]}
|
||||||
|
key="action_dropdown"
|
||||||
/>,
|
/>,
|
||||||
<ActionDropdown
|
<ActionDropdown
|
||||||
key="stock"
|
key="stock"
|
||||||
|
@ -186,7 +186,11 @@ export default function PricingOverviewPanel({
|
|||||||
</Alert>
|
</Alert>
|
||||||
</Paper>
|
</Paper>
|
||||||
)}
|
)}
|
||||||
<DataTable records={overviewData} columns={columns} />
|
<DataTable
|
||||||
|
idAccessor="name"
|
||||||
|
records={overviewData}
|
||||||
|
columns={columns}
|
||||||
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
<ResponsiveContainer width="100%" height={500}>
|
<ResponsiveContainer width="100%" height={500}>
|
||||||
<BarChart data={overviewData} id="pricing-overview-chart">
|
<BarChart data={overviewData} id="pricing-overview-chart">
|
||||||
|
@ -322,6 +322,7 @@ export default function SalesOrderDetail() {
|
|||||||
status={order.status}
|
status={order.status}
|
||||||
type={ModelType.salesorder}
|
type={ModelType.salesorder}
|
||||||
options={{ size: 'lg' }}
|
options={{ size: 'lg' }}
|
||||||
|
key={order.pk}
|
||||||
/>
|
/>
|
||||||
];
|
];
|
||||||
}, [order, instanceQuery]);
|
}, [order, instanceQuery]);
|
||||||
|
@ -473,21 +473,25 @@ export default function StockDetail() {
|
|||||||
color="blue"
|
color="blue"
|
||||||
label={t`Serial Number` + `: ${stockitem.serial}`}
|
label={t`Serial Number` + `: ${stockitem.serial}`}
|
||||||
visible={!!stockitem.serial}
|
visible={!!stockitem.serial}
|
||||||
|
key="serial"
|
||||||
/>,
|
/>,
|
||||||
<DetailsBadge
|
<DetailsBadge
|
||||||
color="blue"
|
color="blue"
|
||||||
label={t`Quantity` + `: ${stockitem.quantity}`}
|
label={t`Quantity` + `: ${stockitem.quantity}`}
|
||||||
visible={!stockitem.serial}
|
visible={!stockitem.serial}
|
||||||
|
key="quantity"
|
||||||
/>,
|
/>,
|
||||||
<DetailsBadge
|
<DetailsBadge
|
||||||
color="blue"
|
color="blue"
|
||||||
label={t`Batch Code` + `: ${stockitem.batch}`}
|
label={t`Batch Code` + `: ${stockitem.batch}`}
|
||||||
visible={!!stockitem.batch}
|
visible={!!stockitem.batch}
|
||||||
|
key="batch"
|
||||||
/>,
|
/>,
|
||||||
<StatusRenderer
|
<StatusRenderer
|
||||||
status={stockitem.status}
|
status={stockitem.status}
|
||||||
type={ModelType.stockitem}
|
type={ModelType.stockitem}
|
||||||
options={{ size: 'lg' }}
|
options={{ size: 'lg' }}
|
||||||
|
key="status"
|
||||||
/>
|
/>
|
||||||
];
|
];
|
||||||
}, [stockitem, instanceQuery]);
|
}, [stockitem, instanceQuery]);
|
||||||
|
@ -26,7 +26,7 @@ export const useServerApiState = create<ServerApiStateProps>()(
|
|||||||
set({ server: response.data });
|
set({ server: response.data });
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
console.error('Error fetching server info');
|
console.error('ERR: Error fetching server info');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Fetch login/SSO behaviour
|
// Fetch login/SSO behaviour
|
||||||
@ -38,7 +38,7 @@ export const useServerApiState = create<ServerApiStateProps>()(
|
|||||||
set({ auth_settings: response.data });
|
set({ auth_settings: response.data });
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
console.error('Error fetching SSO information');
|
console.error('ERR: Error fetching SSO information');
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
status: undefined
|
status: undefined
|
||||||
|
@ -42,7 +42,7 @@ export const useGlobalSettingsState = create<SettingsStateProps>(
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch((_error) => {
|
.catch((_error) => {
|
||||||
console.error('Error fetching global settings');
|
console.error('ERR: Error fetching global settings');
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
getSetting: (key: string, default_value?: string) => {
|
getSetting: (key: string, default_value?: string) => {
|
||||||
@ -76,7 +76,7 @@ export const useUserSettingsState = create<SettingsStateProps>((set, get) => ({
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch((_error) => {
|
.catch((_error) => {
|
||||||
console.error('Error fetching user settings');
|
console.error('ERR: Error fetching user settings');
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
getSetting: (key: string, default_value?: string) => {
|
getSetting: (key: string, default_value?: string) => {
|
||||||
|
@ -39,7 +39,7 @@ export const useGlobalStatusState = create<ServerStateProps>()(
|
|||||||
set({ status: newStatusLookup });
|
set({ status: newStatusLookup });
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
console.error('Error fetching global status information');
|
console.error('ERR: Error fetching global status information');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
@ -57,7 +57,7 @@ export const useUserState = create<UserStateProps>((set, get) => ({
|
|||||||
set({ user: user });
|
set({ user: user });
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Error fetching user data');
|
console.error('ERR: Error fetching user data');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Fetch role data
|
// Fetch role data
|
||||||
@ -75,7 +75,7 @@ export const useUserState = create<UserStateProps>((set, get) => ({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((_error) => {
|
.catch((_error) => {
|
||||||
console.error('Error fetching user roles');
|
console.error('ERR: Error fetching user roles');
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
checkUserRole: (role: UserRoles, permission: UserPermissions) => {
|
checkUserRole: (role: UserRoles, permission: UserPermissions) => {
|
||||||
|
@ -153,6 +153,7 @@ export function BuildOrderTable({
|
|||||||
hidden={!user.hasAddRole(UserRoles.build)}
|
hidden={!user.hasAddRole(UserRoles.build)}
|
||||||
tooltip={t`Add Build Order`}
|
tooltip={t`Add Build Order`}
|
||||||
onClick={() => newBuild.open()}
|
onClick={() => newBuild.open()}
|
||||||
|
key="add-build-order"
|
||||||
/>
|
/>
|
||||||
];
|
];
|
||||||
}, [user]);
|
}, [user]);
|
||||||
|
@ -68,7 +68,11 @@ export default function ErrorReportTable() {
|
|||||||
onClose={close}
|
onClose={close}
|
||||||
>
|
>
|
||||||
{error.split('\n').map((line: string) => {
|
{error.split('\n').map((line: string) => {
|
||||||
return <Text size="sm">{line}</Text>;
|
return (
|
||||||
|
<Text key={line} size="sm">
|
||||||
|
{line}
|
||||||
|
</Text>
|
||||||
|
);
|
||||||
})}
|
})}
|
||||||
</Drawer>
|
</Drawer>
|
||||||
<InvenTreeTable
|
<InvenTreeTable
|
||||||
|
@ -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([]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -4,11 +4,6 @@ import { doQuickLogin } from './login.js';
|
|||||||
test('PUI - Modals as admin', async ({ page }) => {
|
test('PUI - Modals as admin', async ({ page }) => {
|
||||||
await doQuickLogin(page, 'admin', 'inventree');
|
await doQuickLogin(page, 'admin', 'inventree');
|
||||||
|
|
||||||
// Fail on console error
|
|
||||||
await page.on('console', (msg) => {
|
|
||||||
if (msg.type() === 'error') test.fail();
|
|
||||||
});
|
|
||||||
|
|
||||||
// use server info
|
// use server info
|
||||||
await page.getByRole('button', { name: 'Open spotlight' }).click();
|
await page.getByRole('button', { name: 'Open spotlight' }).click();
|
||||||
await page
|
await page
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { test } from '@playwright/test';
|
import { test } from '../baseFixtures';
|
||||||
|
|
||||||
import { baseUrl } from '../defaults';
|
import { baseUrl } from '../defaults';
|
||||||
import { doQuickLogin } from '../login';
|
import { doQuickLogin } from '../login';
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user