2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-07-05 05:00:58 +00:00

API date filter updates (#8544)

* Add 'stocktake_before' and 'stocktake_after' filters for StockItem API

* Enable new filters for StockItemTable

* Update CUI table filters

* Add more date filter options for orders

* Add date filters to BuildList

* Update BuildOrderTable filters

* Add more order date filters

* Cleanup PurchaseOrderFilter code

* Implement more PUI table filters

* Add "Completion Date" column to PurchaseOrderTable

* Update ReturnOrderTable

* Add 'text' option for TableFilter

* filter state management

* Bump API version

* Sorting for table filters

* Add playwright tests for stock table filtering

* Playwright updates

- Add some helper functions for common operations

* Refactoring for Playwright tests
This commit is contained in:
Oliver
2024-11-25 21:36:31 +11:00
committed by GitHub
parent 5e762bc7f7
commit 809a978f7d
22 changed files with 586 additions and 124 deletions

View File

@ -0,0 +1,46 @@
/**
* Open the filter drawer for the currently visible table
* @param page - The page object
*/
export const openFilterDrawer = async (page) => {
await page.getByLabel('table-select-filters').click();
};
/**
* Close the filter drawer for the currently visible table
* @param page - The page object
*/
export const closeFilterDrawer = async (page) => {
await page.getByLabel('filter-drawer-close').click();
};
/**
* Click the specified button (if it is visible)
* @param page - The page object
* @param name - The name of the button to click
*/
export const clickButtonIfVisible = async (page, name, timeout = 500) => {
await page.waitForTimeout(timeout);
if (await page.getByRole('button', { name }).isVisible()) {
await page.getByRole('button', { name }).click();
}
};
/**
* Clear all filters from the currently visible table
* @param page - The page object
*/
export const clearTableFilters = async (page) => {
await openFilterDrawer(page);
await clickButtonIfVisible(page, 'Clear Filters');
await page.getByLabel('filter-drawer-close').click();
};
/**
* Return the parent 'row' element for a given 'cell' element
* @param cell - The cell element
*/
export const getRowFromCell = async (cell) => {
return cell.locator('xpath=ancestor::tr').first();
};

View File

@ -1,8 +1,13 @@
import { test } from '../baseFixtures.ts';
import { baseUrl } from '../defaults.ts';
import {
clickButtonIfVisible,
getRowFromCell,
openFilterDrawer
} from '../helpers.ts';
import { doQuickLogin } from '../login.ts';
test('Pages - Build Order', async ({ page }) => {
test('Build Order - Basic Tests', async ({ page }) => {
await doQuickLogin(page);
await page.goto(`${baseUrl}/part/`);
@ -82,7 +87,7 @@ test('Pages - Build Order', async ({ page }) => {
.waitFor();
});
test('Pages - Build Order - Build Outputs', async ({ page }) => {
test('Build Order - Build Outputs', async ({ page }) => {
await doQuickLogin(page);
await page.goto(`${baseUrl}/part/`);
@ -140,7 +145,7 @@ test('Pages - Build Order - Build Outputs', async ({ page }) => {
// Cancel one of the newly created outputs
const cell = await page.getByRole('cell', { name: `# ${sn}` });
const row = await cell.locator('xpath=ancestor::tr').first();
const row = await getRowFromCell(cell);
await row.getByLabel(/row-action-menu-/i).click();
await page.getByRole('menuitem', { name: 'Cancel' }).click();
await page.getByRole('button', { name: 'Submit' }).click();
@ -148,7 +153,7 @@ test('Pages - Build Order - Build Outputs', async ({ page }) => {
// Complete the other output
const cell2 = await page.getByRole('cell', { name: `# ${sn + 1}` });
const row2 = await cell2.locator('xpath=ancestor::tr').first();
const row2 = await getRowFromCell(cell2);
await row2.getByLabel(/row-action-menu-/i).click();
await page.getByRole('menuitem', { name: 'Complete' }).click();
await page.getByLabel('related-field-location').click();
@ -158,7 +163,7 @@ test('Pages - Build Order - Build Outputs', async ({ page }) => {
await page.getByText('Build outputs have been completed').waitFor();
});
test('Pages - Build Order - Allocation', async ({ page }) => {
test('Build Order - Allocation', async ({ page }) => {
await doQuickLogin(page);
await page.goto(`${baseUrl}/manufacturing/build-order/1/line-items`);
@ -170,7 +175,7 @@ test('Pages - Build Order - Allocation', async ({ page }) => {
// The capacitor stock should be fully allocated
const cell = await page.getByRole('cell', { name: /C_1uF_0805/ });
const row = await cell.locator('xpath=ancestor::tr').first();
const row = await getRowFromCell(cell);
await row.getByText(/150 \/ 150/).waitFor();
@ -237,7 +242,7 @@ test('Pages - Build Order - Allocation', async ({ page }) => {
const item = data[idx];
const cell = await page.getByRole('cell', { name: item.name });
const row = await cell.locator('xpath=ancestor::tr').first();
const row = await getRowFromCell(cell);
const progress = `${item.allocated} / ${item.required}`;
await row.getByRole('cell', { name: item.ipn }).first().waitFor();
@ -257,3 +262,14 @@ test('Pages - Build Order - Allocation', async ({ page }) => {
.getByRole('menuitem', { name: 'Deallocate Stock', exact: true })
.waitFor();
});
test('Build Order - Filters', async ({ page }) => {
await doQuickLogin(page);
await page.goto(`${baseUrl}/manufacturing/index/buildorders`);
await openFilterDrawer(page);
await clickButtonIfVisible(page, 'Clear Filters');
await page.waitForTimeout(2500);
});

View File

@ -2,7 +2,7 @@ import { test } from '../baseFixtures.js';
import { doQuickLogin } from '../login.js';
import { setPluginState } from '../settings.js';
test('Pages - Dashboard - Basic', async ({ page }) => {
test('Dashboard - Basic', async ({ page }) => {
await doQuickLogin(page);
await page.getByText('Use the menu to add widgets').waitFor();
@ -35,7 +35,7 @@ test('Pages - Dashboard - Basic', async ({ page }) => {
await page.getByLabel('dashboard-accept-layout').click();
});
test('Pages - Dashboard - Plugins', async ({ page, request }) => {
test('Dashboard - Plugins', async ({ page, request }) => {
// Ensure that the "SampleUI" plugin is enabled
await setPluginState({
request,

View File

@ -1,5 +1,6 @@
import { test } from '../baseFixtures';
import { baseUrl } from '../defaults';
import { getRowFromCell } from '../helpers';
import { doQuickLogin } from '../login';
/**
@ -129,9 +130,7 @@ test('Parts - Allocations', async ({ page }) => {
// Check "progress" bar of BO0001
const build_order_cell = await page.getByRole('cell', { name: 'BO0001' });
const build_order_row = await build_order_cell
.locator('xpath=ancestor::tr')
.first();
const build_order_row = await getRowFromCell(build_order_cell);
await build_order_row.getByText('11 / 75').waitFor();
// Expand allocations against BO0001
@ -147,9 +146,7 @@ test('Parts - Allocations', async ({ page }) => {
// Check "progress" bar of SO0025
const sales_order_cell = await page.getByRole('cell', { name: 'SO0025' });
const sales_order_row = await sales_order_cell
.locator('xpath=ancestor::tr')
.first();
const sales_order_row = await getRowFromCell(sales_order_cell);
await sales_order_row.getByText('3 / 10').waitFor();
// Expand allocations against SO0025

View File

@ -1,4 +1,5 @@
import { test } from '../baseFixtures.ts';
import { clickButtonIfVisible, openFilterDrawer } from '../helpers.ts';
import { doQuickLogin } from '../login.ts';
test('Purchase Orders - General', async ({ page }) => {
@ -51,6 +52,30 @@ test('Purchase Orders - General', async ({ page }) => {
await page.getByRole('tab', { name: 'Details' }).waitFor();
});
test('Purchase Orders - Filters', async ({ page }) => {
await doQuickLogin(page, 'reader', 'readonly');
await page.getByRole('tab', { name: 'Purchasing' }).click();
await page.getByRole('tab', { name: 'Purchase Orders' }).click();
// Open filters drawer
await openFilterDrawer(page);
await clickButtonIfVisible(page, 'Clear Filters');
await page.getByRole('button', { name: 'Add Filter' }).click();
// Check for expected filter options
await page.getByPlaceholder('Select filter').fill('before');
await page.getByRole('option', { name: 'Created Before' }).waitFor();
await page.getByRole('option', { name: 'Completed Before' }).waitFor();
await page.getByRole('option', { name: 'Target Date Before' }).waitFor();
await page.getByPlaceholder('Select filter').fill('after');
await page.getByRole('option', { name: 'Created After' }).waitFor();
await page.getByRole('option', { name: 'Completed After' }).waitFor();
await page.getByRole('option', { name: 'Target Date After' }).waitFor();
});
/**
* Tests for receiving items against a purchase order
*/

View File

@ -1,8 +1,9 @@
import { test } from '../baseFixtures.js';
import { baseUrl } from '../defaults.js';
import { clickButtonIfVisible, openFilterDrawer } from '../helpers.js';
import { doQuickLogin } from '../login.js';
test('Stock', async ({ page }) => {
test('Stock - Basic Tests', async ({ page }) => {
await doQuickLogin(page);
await page.goto(`${baseUrl}/stock/location/index/`);
@ -49,6 +50,45 @@ test('Stock - Location Tree', async ({ page }) => {
await page.getByRole('cell', { name: 'Factory' }).first().waitFor();
});
test('Stock - Filters', async ({ page }) => {
await doQuickLogin(page, 'steven', 'wizardstaff');
await page.goto(`${baseUrl}/stock/location/index/`);
await page.getByRole('tab', { name: 'Stock Items' }).click();
await openFilterDrawer(page);
await clickButtonIfVisible(page, 'Clear Filters');
// Filter by updated date
await page.getByRole('button', { name: 'Add Filter' }).click();
await page.getByPlaceholder('Select filter').fill('updated');
await page.getByText('Updated After').click();
await page.getByPlaceholder('Select date value').fill('2010-01-01');
await page.getByText('Show items updated after this date').waitFor();
// Filter by batch code
await page.getByRole('button', { name: 'Add Filter' }).click();
await page.getByPlaceholder('Select filter').fill('batch');
await page
.getByRole('option', { name: 'Batch Code', exact: true })
.locator('span')
.click();
await page.getByPlaceholder('Enter filter value').fill('TABLE-B02');
await page.getByLabel('apply-text-filter').click();
// Close dialog
await page.keyboard.press('Escape');
// Ensure correct result is displayed
await page
.getByRole('cell', { name: 'A round table - with blue paint' })
.waitFor();
// Clear filters (ready for next set of tests)
await openFilterDrawer(page);
await clickButtonIfVisible(page, 'Clear Filters');
});
test('Stock - Serial Numbers', async ({ page }) => {
await doQuickLogin(page);

View File

@ -1,23 +1,23 @@
import { test } from './baseFixtures.js';
import { baseUrl } from './defaults.js';
import {
clearTableFilters,
closeFilterDrawer,
openFilterDrawer
} from './helpers.js';
import { doQuickLogin } from './login.js';
// Helper function to set the value of a specific table filter
const setFilter = async (page, name: string, value: string) => {
await page.getByLabel('table-select-filters').click();
await openFilterDrawer(page);
await page.getByRole('button', { name: 'Add Filter' }).click();
await page.getByPlaceholder('Select filter').click();
await page.getByRole('option', { name: name, exact: true }).click();
await page.getByPlaceholder('Select filter value').click();
await page.getByRole('option', { name: value, exact: true }).click();
await page.getByLabel('filter-drawer-close').click();
};
// Helper function to clear table filters
const clearFilters = async (page) => {
await page.getByLabel('table-select-filters').click();
await page.getByRole('button', { name: 'Clear Filters' }).click();
await page.getByLabel('filter-drawer-close').click();
await closeFilterDrawer(page);
};
test('Tables - Filters', async ({ page }) => {
@ -30,14 +30,14 @@ test('Tables - Filters', async ({ page }) => {
await setFilter(page, 'Responsible', 'allaccess');
await setFilter(page, 'Project Code', 'PRJ-NIM');
await clearFilters(page);
await clearTableFilters(page);
// Head to the "part list" page
await page.goto(`${baseUrl}/part/category/index/parts/`);
await setFilter(page, 'Assembly', 'Yes');
await clearFilters(page);
await clearTableFilters(page);
// Head to the "purchase order list" page
await page.goto(`${baseUrl}/purchasing/index/purchaseorders/`);
@ -47,7 +47,7 @@ test('Tables - Filters', async ({ page }) => {
await setFilter(page, 'Assigned to me', 'No');
await setFilter(page, 'Project Code', 'PRO-ZEN');
await clearFilters(page);
await clearTableFilters(page);
});
test('Tables - Columns', async ({ page }) => {