2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-08-07 04:12:11 +00:00

Updated playwright testing

This commit is contained in:
Oliver Walters
2024-12-28 16:33:16 +11:00
parent 26f1792940
commit 1568dc29f7
7 changed files with 69 additions and 58 deletions

View File

@@ -574,7 +574,9 @@ class BuildOutputCompleteSerializer(serializers.Serializer):
) )
status_custom_key = serializers.ChoiceField( status_custom_key = serializers.ChoiceField(
choices=StockStatus.items(), default=StockStatus.OK.value, label=_('Status') choices=StockStatus.items(custom=True),
default=StockStatus.OK.value,
label=_('Status'),
) )
accept_incomplete_allocation = serializers.BooleanField( accept_incomplete_allocation = serializers.BooleanField(

View File

@@ -158,7 +158,7 @@ class StatusCode(BaseEnum):
return re.sub(r'(?<!^)(?=[A-Z])', '_', ref_name).lower() return re.sub(r'(?<!^)(?=[A-Z])', '_', ref_name).lower()
@classmethod @classmethod
def items(cls, custom=True): def items(cls, custom=False):
"""All status code items.""" """All status code items."""
data = [(x.value, x.label) for x in cls.values()] data = [(x.value, x.label) for x in cls.values()]

View File

@@ -769,7 +769,9 @@ class PurchaseOrderLineItemReceiveSerializer(serializers.Serializer):
) )
status = serializers.ChoiceField( status = serializers.ChoiceField(
choices=StockStatus.items(), default=StockStatus.OK.value, label=_('Status') choices=StockStatus.items(custom=True),
default=StockStatus.OK.value,
label=_('Status'),
) )
packaging = serializers.CharField( packaging = serializers.CharField(
@@ -1935,7 +1937,7 @@ class ReturnOrderLineItemReceiveSerializer(serializers.Serializer):
) )
status = serializers.ChoiceField( status = serializers.ChoiceField(
choices=stock.status_codes.StockStatus.items(), choices=stock.status_codes.StockStatus.items(custom=True),
default=None, default=None,
label=_('Status'), label=_('Status'),
help_text=_('Stock item status code'), help_text=_('Stock item status code'),

View File

@@ -980,7 +980,7 @@ class ReturnStockItemSerializer(serializers.Serializer):
) )
status = serializers.ChoiceField( status = serializers.ChoiceField(
choices=stock.status_codes.StockStatus.items(), choices=stock.status_codes.StockStatus.items(custom=True),
default=None, default=None,
label=_('Status'), label=_('Status'),
help_text=_('Stock item status code'), help_text=_('Stock item status code'),
@@ -996,7 +996,7 @@ class ReturnStockItemSerializer(serializers.Serializer):
) )
def save(self): def save(self):
"""Save the serialzier to return the item into stock.""" """Save the serializer to return the item into stock."""
item = self.context['item'] item = self.context['item']
request = self.context['request'] request = self.context['request']
@@ -1037,7 +1037,7 @@ class StockChangeStatusSerializer(serializers.Serializer):
return items return items
status = serializers.ChoiceField( status = serializers.ChoiceField(
choices=stock.status_codes.StockStatus.items(), choices=stock.status_codes.StockStatus.items(custom=True),
default=stock.status_codes.StockStatus.OK.value, default=stock.status_codes.StockStatus.OK.value,
label=_('Status'), label=_('Status'),
) )
@@ -1533,11 +1533,11 @@ def stock_item_adjust_status_options():
In particular, include a Null option for the status field. In particular, include a Null option for the status field.
""" """
return [(None, _('No Change')), *stock.status_codes.StockStatus.items()] return [(None, _('No Change')), *stock.status_codes.StockStatus.items(custom=True)]
class StockAdjustmentItemSerializer(serializers.Serializer): class StockAdjustmentItemSerializer(serializers.Serializer):
"""Serializer for a single StockItem within a stock adjument request. """Serializer for a single StockItem within a stock adjustment request.
Required Fields: Required Fields:
- item: StockItem object - item: StockItem object

View File

@@ -113,8 +113,6 @@ export default function StockDetail() {
data.available_stock = Math.max(0, data.quantity - data.allocated); data.available_stock = Math.max(0, data.quantity - data.allocated);
data.stock_status = data.status_custom_key || data.status;
if (instanceQuery.isFetching) { if (instanceQuery.isFetching) {
return <Skeleton />; return <Skeleton />;
} }
@@ -136,12 +134,22 @@ export default function StockDetail() {
hidden: !part.IPN hidden: !part.IPN
}, },
{ {
name: 'status_custom_key', name: 'status',
type: 'status', type: 'status',
label: t`Stock Status`, label: t`Status`,
model: ModelType.stockitem, model: ModelType.stockitem,
icon: 'status' icon: 'status'
}, },
{
name: 'status_custom_key',
type: 'status',
label: t`Custom Status`,
model: ModelType.stockitem,
icon: 'status',
hidden:
!stockitem.status_custom_key ||
stockitem.status_custom_key == stockitem.status
},
{ {
type: 'text', type: 'text',
name: 'tests', name: 'tests',

View File

@@ -169,56 +169,58 @@ test('Stock - Serial Numbers', async ({ page }) => {
test('Stock - Stock Actions', async ({ page }) => { test('Stock - Stock Actions', async ({ page }) => {
await doQuickLogin(page); await doQuickLogin(page);
// Find an in-stock, untracked item await page.goto(`${baseUrl}/stock/item/1225/details`);
await page.goto(
`${baseUrl}/stock/location/index/stock-items?in_stock=1&serialized=0`
);
await page.getByText('530470210').first().click();
await page
.locator('div')
.filter({ hasText: /^Quantity: 270$/ })
.first()
.waitFor();
// Check for expected action sections
await page.getByLabel('action-menu-barcode-actions').click();
await page.getByLabel('action-menu-barcode-actions-link-barcode').click();
await page.getByRole('banner').getByRole('button').click();
await page.getByLabel('action-menu-printing-actions').click();
await page.getByLabel('action-menu-printing-actions-print-labels').click();
await page.getByRole('button', { name: 'Cancel' }).click();
// Helper function to launch a stock action
const launchStockAction = async (action: string) => {
await page.getByLabel('action-menu-stock-operations').click(); await page.getByLabel('action-menu-stock-operations').click();
await page.getByLabel('action-menu-stock-operations-count').waitFor(); await page.getByLabel(`action-menu-stock-operations-${action}`).click();
await page.getByLabel('action-menu-stock-operations-add').waitFor(); };
await page.getByLabel('action-menu-stock-operations-remove').waitFor();
await page.getByLabel('action-menu-stock-operations-transfer').click(); const setStockStatus = async (status: string) => {
await page.getByLabel('text-field-notes').fill('test notes');
await page.getByRole('button', { name: 'Submit' }).click();
await page.getByText('This field is required.').first().waitFor();
// Set the status field
await page.getByLabel('action-button-change-status').click(); await page.getByLabel('action-button-change-status').click();
await page.getByLabel('choice-field-status').click(); await page.getByLabel('choice-field-status').click();
await page.getByText('Attention needed').click(); await page.getByRole('option', { name: status }).click();
};
// Set the packaging field // Check for required values
await page.getByLabel('action-button-adjust-packaging').click(); await page.getByText('Status', { exact: true }).waitFor();
await page.getByLabel('text-field-packaging').fill('test packaging'); await page.getByText('Custom Status', { exact: true }).waitFor();
await page.getByText('Attention needed').waitFor();
await page
.getByLabel('Stock Details')
.getByText('Incoming goods inspection')
.waitFor();
await page.getByText('123').first().waitFor();
// Close the dialog // Add stock, and change status
await page.getByRole('button', { name: 'Cancel' }).click(); await launchStockAction('add');
await page.getByLabel('number-field-quantity').fill('12');
await setStockStatus('Lost');
await page.getByRole('button', { name: 'Submit' }).click();
// Find an item which has been sent to a customer await page.getByText('Lost').first().waitFor();
await page.goto(`${baseUrl}/stock/item/1014/details`); await page.getByText('Unavailable').first().waitFor();
await page.getByText('Batch Code: 2022-11-12').waitFor(); await page.getByText('135').first().waitFor();
await page.getByText('Unavailable').waitFor();
await page.getByLabel('action-menu-stock-operations').click();
await page.getByLabel('action-menu-stock-operations-return').click();
await page.waitForTimeout(2500); // Remove stock, and change status
await launchStockAction('remove');
await page.getByLabel('number-field-quantity').fill('99');
await setStockStatus('Damaged');
await page.getByRole('button', { name: 'Submit' }).click();
await page.getByText('36').first().waitFor();
await page.getByText('Damaged').first().waitFor();
// Count stock and change status (reverting to original value)
await launchStockAction('count');
await page.getByLabel('number-field-quantity').fill('123');
await setStockStatus('Incoming goods inspection');
await page.getByRole('button', { name: 'Submit' }).click();
await page.getByText('123').first().waitFor();
await page.getByText('Custom Status').first().waitFor();
await page.getByText('Incoming goods inspection').first().waitFor();
}); });
test('Stock - Tracking', async ({ page }) => { test('Stock - Tracking', async ({ page }) => {
@@ -233,7 +235,4 @@ test('Stock - Tracking', async ({ page }) => {
await page.getByText('- - Factory/Office Block/Room').first().waitFor(); await page.getByText('- - Factory/Office Block/Room').first().waitFor();
await page.getByRole('link', { name: 'Widget Assembly' }).waitFor(); await page.getByRole('link', { name: 'Widget Assembly' }).waitFor();
await page.getByRole('cell', { name: 'Installed into assembly' }).waitFor(); await page.getByRole('cell', { name: 'Installed into assembly' }).waitFor();
await page.waitForTimeout(1500);
return;
}); });

View File

@@ -153,7 +153,7 @@ test('Settings - Admin - Barcode History', async ({ page, request }) => {
await page.getByRole('menuitem', { name: 'Admin Center' }).click(); await page.getByRole('menuitem', { name: 'Admin Center' }).click();
await page.getByRole('tab', { name: 'Barcode Scans' }).click(); await page.getByRole('tab', { name: 'Barcode Scans' }).click();
await page.waitForTimeout(2000); await page.waitForTimeout(500);
// Barcode history is displayed in table // Barcode history is displayed in table
barcodes.forEach(async (barcode) => { barcodes.forEach(async (barcode) => {