mirror of
https://github.com/inventree/InvenTree.git
synced 2025-06-15 19:45:46 +00:00
* Add builtin plugin for auto-issuing orders * Add plugin to auto-issue orders * Add placeholder documentation * Fix typo * Adds image macro - To replace img.html - includes checking if file exists * Fix tooltips * More docs * Adjust plugin settings filters * docs * More docs * More docs * Updates * Less restrictive URL checking * Refactor build order page * Fix typo * Allow 429 * Debug output * More debug * Construct assets dir * Cleanup * Update docs README * Refactoring more pages * Fix image link * Fix SSO settings * Add hook to check for missing settings - Ensure that all settings are documented! * Add missing user settings * Update docstring * Tweak SSO.md * Image updates * More updates * Tweaks * Exclude orders without a target_date * Fix for issuing build orders * Further refactoring * Fixes * Image refactoring * More refactoring * More refactoring * Refactor app images * Fix pathing issues * Suppress some openapidocs warnings in logs (much easier to debug docs build issues) * Fix image reference * Reduce error messages * Fix image links * Fix image links * Reduce docs log output * Ensure settings are loaded before displaying them * Fix for UI test * Fix unit test * Test tweaks
227 lines
6.6 KiB
TypeScript
227 lines
6.6 KiB
TypeScript
import test from 'playwright/test';
|
|
|
|
import {
|
|
clearTableFilters,
|
|
clickOnRowMenu,
|
|
loadTab,
|
|
navigate,
|
|
setTableChoiceFilter
|
|
} from './helpers.js';
|
|
import { doCachedLogin } from './login.js';
|
|
import { setPluginState, setSettingState } from './settings.js';
|
|
|
|
// Unit test for plugin settings
|
|
test('Plugins - Settings', async ({ browser, request }) => {
|
|
const page = await doCachedLogin(browser, {
|
|
username: 'admin',
|
|
password: 'inventree'
|
|
});
|
|
|
|
// Ensure that the SampleIntegration plugin is enabled
|
|
await setPluginState({
|
|
request,
|
|
plugin: 'sample',
|
|
state: true
|
|
});
|
|
|
|
// Navigate and select the plugin
|
|
await navigate(page, 'settings/admin/plugin/');
|
|
await clearTableFilters(page);
|
|
await page.getByLabel('table-search-input').fill('integration');
|
|
|
|
await page
|
|
.getByRole('row', { name: 'SampleIntegrationPlugin' })
|
|
.getByRole('paragraph')
|
|
.click();
|
|
await page.getByRole('button', { name: 'Plugin Information' }).click();
|
|
await page
|
|
.getByLabel('Plugin Detail -')
|
|
.getByRole('button', { name: 'Plugin Settings' })
|
|
.waitFor();
|
|
|
|
// Edit numerical value
|
|
await page.getByLabel('edit-setting-NUMERICAL_SETTING').click();
|
|
const originalValue = await page
|
|
.getByLabel('number-field-value')
|
|
.inputValue();
|
|
|
|
await page
|
|
.getByLabel('number-field-value')
|
|
.fill(originalValue == '999' ? '1000' : '999');
|
|
await page.getByRole('button', { name: 'Submit' }).click();
|
|
|
|
await page.waitForTimeout(500);
|
|
|
|
// Change it back
|
|
await page.getByLabel('edit-setting-NUMERICAL_SETTING').click();
|
|
await page.getByLabel('number-field-value').fill(originalValue);
|
|
await page.getByRole('button', { name: 'Submit' }).click();
|
|
|
|
// Select supplier
|
|
await page.getByLabel('edit-setting-SELECT_COMPANY').click();
|
|
await page.getByLabel('related-field-value').fill('mouser');
|
|
await page.getByText('Mouser Electronics').click();
|
|
});
|
|
|
|
// Test base plugin functionality
|
|
test('Plugins - Functionality', async ({ browser }) => {
|
|
// Navigate and select the plugin
|
|
const page = await doCachedLogin(browser, {
|
|
username: 'admin',
|
|
password: 'inventree',
|
|
url: 'settings/admin/plugin/'
|
|
});
|
|
|
|
// Filter plugins first
|
|
await clearTableFilters(page);
|
|
await setTableChoiceFilter(page, 'Sample', 'Yes');
|
|
await setTableChoiceFilter(page, 'Builtin', 'No');
|
|
|
|
// Activate the plugin
|
|
const cell = await page.getByText('Sample API Caller', { exact: true });
|
|
await clickOnRowMenu(cell);
|
|
|
|
// Activate the plugin (unless already activated)
|
|
if ((await page.getByRole('menuitem', { name: 'Deactivate' }).count()) == 0) {
|
|
await page.getByRole('menuitem', { name: 'Activate' }).click();
|
|
await page.getByRole('button', { name: 'Submit' }).click();
|
|
await page.getByText('The plugin was activated').waitFor();
|
|
await page.waitForTimeout(250);
|
|
}
|
|
|
|
// Deactivate the plugin again
|
|
await clickOnRowMenu(cell);
|
|
await page.getByRole('menuitem', { name: 'Deactivate' }).click();
|
|
await page.getByRole('button', { name: 'Submit' }).click();
|
|
await page.getByText('The plugin was deactivated').waitFor();
|
|
});
|
|
|
|
test('Plugins - Panels', async ({ browser, request }) => {
|
|
const page = await doCachedLogin(browser, {
|
|
username: 'admin',
|
|
password: 'inventree'
|
|
});
|
|
|
|
// Ensure that UI plugins are enabled
|
|
await setSettingState({
|
|
request,
|
|
setting: 'ENABLE_PLUGINS_INTERFACE',
|
|
value: true
|
|
});
|
|
|
|
await page.waitForTimeout(500);
|
|
|
|
// Ensure that the SampleUI plugin is enabled
|
|
await setPluginState({
|
|
request,
|
|
plugin: 'sampleui',
|
|
state: true
|
|
});
|
|
|
|
await page.waitForTimeout(500);
|
|
|
|
// Navigate to the "part" page
|
|
await navigate(page, 'part/69/');
|
|
|
|
// Ensure basic part tab is available
|
|
await loadTab(page, 'Part Details');
|
|
|
|
// Allow time for the plugin panels to load (they are loaded asynchronously)
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
// Check out each of the plugin panels
|
|
await loadTab(page, 'Broken Panel');
|
|
await page.waitForTimeout(500);
|
|
|
|
await page.getByText('Error occurred while loading plugin content').waitFor();
|
|
|
|
await loadTab(page, 'Dynamic Panel');
|
|
await page.waitForTimeout(500);
|
|
|
|
await page.getByText('Instance ID: 69');
|
|
await page
|
|
.getByText('This panel has been dynamically rendered by the plugin system')
|
|
.waitFor();
|
|
|
|
await loadTab(page, 'Part Panel');
|
|
await page.waitForTimeout(500);
|
|
await page.getByText('This content has been rendered by a custom plugin');
|
|
|
|
// Disable the plugin, and ensure it is no longer visible
|
|
await setPluginState({
|
|
request,
|
|
plugin: 'sampleui',
|
|
state: false
|
|
});
|
|
});
|
|
|
|
/**
|
|
* Unit test for custom admin integration for plugins
|
|
*/
|
|
test('Plugins - Custom Admin', async ({ browser, request }) => {
|
|
const page = await doCachedLogin(browser, {
|
|
username: 'admin',
|
|
password: 'inventree'
|
|
});
|
|
|
|
// Ensure that the SampleUI plugin is enabled
|
|
await setPluginState({
|
|
request,
|
|
plugin: 'sampleui',
|
|
state: true
|
|
});
|
|
|
|
// Navigate to the "admin" page
|
|
await navigate(page, 'settings/admin/plugin/');
|
|
|
|
// Open the plugin drawer, and ensure that the custom admin elements are visible
|
|
await page.getByText('SampleUI').click();
|
|
await page.getByRole('button', { name: 'Plugin Information' }).click();
|
|
await page
|
|
.getByLabel('Plugin Detail')
|
|
.getByRole('button', { name: 'Plugin Settings' })
|
|
.click();
|
|
await page.getByRole('button', { name: 'Plugin Configuration' }).click();
|
|
|
|
// Check for expected custom elements
|
|
await page
|
|
.getByRole('heading', { name: 'Custom Plugin Configuration Content' })
|
|
.waitFor();
|
|
await page.getByText('apple: banana').waitFor();
|
|
await page.getByText('foo: bar').waitFor();
|
|
await page.getByText('hello: world').waitFor();
|
|
});
|
|
|
|
test('Plugins - Locate Item', async ({ browser, request }) => {
|
|
const page = await doCachedLogin(browser, {
|
|
username: 'admin',
|
|
password: 'inventree'
|
|
});
|
|
|
|
// Ensure that the sample location plugin is enabled
|
|
await setPluginState({
|
|
request,
|
|
plugin: 'samplelocate',
|
|
state: true
|
|
});
|
|
|
|
await page.waitForTimeout(500);
|
|
|
|
// Navigate to the "stock item" page
|
|
await navigate(page, 'stock/item/287/');
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
// "Locate" this item
|
|
await page.getByLabel('action-button-locate-item').click();
|
|
await page.getByRole('button', { name: 'Submit' }).click();
|
|
await page.getByText('Item location requested').waitFor();
|
|
|
|
// Show the location
|
|
await page.getByLabel('breadcrumb-1-factory').click();
|
|
await page.waitForTimeout(500);
|
|
|
|
await page.getByLabel('action-button-locate-item').click();
|
|
await page.getByRole('button', { name: 'Submit' }).click();
|
|
await page.getByText('Item location requested').waitFor();
|
|
});
|