2
0
mirror of https://github.com/inventree/InvenTree.git synced 2026-04-15 07:48:51 +00:00

[API] Monitor task (#11527)

* Enhance docstring

* Return the ID of an offloaded task

* Add API endpoint for background task detail

* Add UI hook for monitoring background task  progress

* Handle queued tasks (not yet started)

* Improve UX

* Update frontend lib version

* Bump API version

* Fix notification

* Simplify UI interface

* Implement internal hook

* Fix API path sequence

* Add unit tests for task detail endpoint

* Refactor code into reusable model

* Explicit operation_id for API endpoints

* Further refactoring

* Use 200 response code

- axios does not like 202, simplify it

* Return task response for validation of part BOM

* Fix schema

* Cleanup

* Run background worker during playwright tests

- For full e2e integration testing

* Improve hooks and unit testing

* Rename custom hooks to meet react naming requirements
This commit is contained in:
Oliver
2026-03-15 14:11:22 +11:00
committed by GitHub
parent 133d254ba7
commit 6830ba5efe
20 changed files with 482 additions and 54 deletions

View File

@@ -140,6 +140,44 @@ test('Parts - BOM', async ({ browser }) => {
await page.getByRole('button', { name: 'Close' }).click();
});
/**
* Perform BOM validation process
* Note that this is a "background task" which is monitored by the "useBackgroundTask" hook
*/
test('Parts - BOM Validation', async ({ browser }) => {
const page = await doCachedLogin(browser, { url: 'part/107/bom' });
// Run BOM validation step
await page
.getByRole('button', { name: 'action-button-validate-bom' })
.click();
await page.getByRole('button', { name: 'Submit' }).click();
// Background task monitoring
await page.getByText('Validating BOM').waitFor();
await page.getByText('BOM validated').waitFor();
await page.getByRole('button', { name: 'bom-validation-info' }).hover();
await page.getByText('Validated By: allaccessAlly').waitFor();
// Edit line item, to ensure BOM is not valid next time around
const cell = await page.getByRole('cell', { name: 'Red paint Red Paint' });
await clickOnRowMenu(cell);
await page.getByRole('menuitem', { name: 'Edit', exact: true }).click();
const input = await page.getByRole('textbox', {
name: 'number-field-quantity'
});
const value = await input.inputValue();
const nextValue = Number.parseFloat(value) + 0.24;
await input.fill(`${nextValue.toFixed(3)}`);
await page.getByRole('button', { name: 'Submit' }).click();
await page.getByText('BOM item updated').waitFor();
});
test('Parts - Editing', async ({ browser }) => {
const page = await doCachedLogin(browser, { url: 'part/104/details' });

View File

@@ -1,3 +1,4 @@
import type { Page } from '@playwright/test';
import { createApi } from './api.js';
import { expect, test } from './baseFixtures.js';
import { adminuser, allaccessuser, stevenuser } from './defaults.js';
@@ -314,6 +315,29 @@ test('Settings - Admin', async ({ browser }) => {
await page.getByRole('button', { name: 'Submit' }).click();
});
test('Settings - Admin - Background Tasks', async ({ browser }) => {
const page = await doCachedLogin(browser, {
user: adminuser,
url: 'settings/admin/background'
});
// Background worker should be running, and idle
await page.getByText('Background worker running').waitFor();
await page.getByText('Failed Tasks0').waitFor();
await page.getByText('Pending Tasks0').waitFor();
// Expand the "scheduled tasks" view
await page.getByRole('button', { name: 'Scheduled Tasks' }).click();
// Check for some expected values
await page
.getByRole('cell', { name: 'InvenTree.tasks.delete_successful_tasks' })
.waitFor();
await page
.getByRole('cell', { name: 'InvenTree.tasks.check_for_migrations' })
.waitFor();
});
test('Settings - Admin - Barcode History', async ({ browser }) => {
// Login with admin credentials
const page = await doCachedLogin(browser, {
@@ -529,7 +553,7 @@ test('Settings - Auth - Email', async ({ browser }) => {
await page.getByText('Currently no email addresses are registered').waitFor();
});
async function testColorPicker(page, ref: string) {
async function testColorPicker(page: Page, ref: string) {
const element = page.getByLabel(ref);
await element.click();
const box = (await element.boundingBox())!;
@@ -539,8 +563,7 @@ async function testColorPicker(page, ref: string) {
test('Settings - Auth - Tokens', async ({ browser }) => {
const page = await doCachedLogin(browser, {
username: 'allaccess',
password: 'nolimits',
user: allaccessuser,
url: 'settings/user/'
});