Migrate Playwright suite to .NET UI tests and deprecate TS project
This commit is contained in:
@@ -0,0 +1,237 @@
|
||||
import { Page, Download } from '@playwright/test';
|
||||
import path from 'path';
|
||||
|
||||
/**
|
||||
* Configuration for file upload filter panels
|
||||
*/
|
||||
export interface FileUploadConfig {
|
||||
/** Panel header text to identify the panel */
|
||||
panelHeader: string;
|
||||
/** Template filename (for download verification) */
|
||||
templateFilename: string;
|
||||
/** Expected columns in the template */
|
||||
expectedColumns: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Work Order upload configuration
|
||||
*/
|
||||
export const workOrderConfig: FileUploadConfig = {
|
||||
panelHeader: 'Filter by Work Order',
|
||||
templateFilename: 'WorkOrderTemplate.xlsx',
|
||||
expectedColumns: ['Work Order Number'],
|
||||
};
|
||||
|
||||
/**
|
||||
* Component Lot upload configuration
|
||||
*/
|
||||
export const componentLotConfig: FileUploadConfig = {
|
||||
panelHeader: 'Filter By Component Lot',
|
||||
templateFilename: 'ComponentLotTemplate.xlsx',
|
||||
expectedColumns: ['Lot Number', 'Item Number'],
|
||||
};
|
||||
|
||||
/**
|
||||
* Item Number upload configuration
|
||||
*/
|
||||
export const itemNumberConfig: FileUploadConfig = {
|
||||
panelHeader: 'Filter by Item Number',
|
||||
templateFilename: 'ItemNumberTemplate.xlsx',
|
||||
expectedColumns: ['Item Number'],
|
||||
};
|
||||
|
||||
/**
|
||||
* Part Operation (Item/Operation/MIS) upload configuration
|
||||
*/
|
||||
export const partOperationConfig: FileUploadConfig = {
|
||||
panelHeader: 'Filter By Item/Operation/MIS',
|
||||
templateFilename: 'PartOperationTemplate.xlsx',
|
||||
expectedColumns: ['Item Number', 'Operation Number', 'MIS Number', 'MIS Revision'],
|
||||
};
|
||||
|
||||
/**
|
||||
* Upload a file to a filter panel
|
||||
* @param page - Playwright page object
|
||||
* @param config - File upload configuration
|
||||
* @param filePath - Path to the file to upload
|
||||
*/
|
||||
export async function uploadFile(
|
||||
page: Page,
|
||||
config: FileUploadConfig,
|
||||
filePath: string
|
||||
): Promise<void> {
|
||||
// Find the panel by its header
|
||||
const panel = page.locator(`.rz-card:has-text("${config.panelHeader}")`);
|
||||
|
||||
// Find the file input (RadzenUpload creates a hidden input)
|
||||
const fileInput = panel.locator('input[type="file"]');
|
||||
|
||||
// Set the file
|
||||
await fileInput.setInputFiles(filePath);
|
||||
|
||||
// Wait for upload to complete
|
||||
await page.waitForTimeout(2000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload a file using the global file input (fallback for panels without specific locators)
|
||||
* @param page - Playwright page object
|
||||
* @param filePath - Path to the file to upload
|
||||
*/
|
||||
export async function uploadFileGlobal(page: Page, filePath: string): Promise<void> {
|
||||
const fileInput = page.locator('input[type="file"]');
|
||||
await fileInput.setInputFiles(filePath);
|
||||
await page.waitForTimeout(2000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Download a template file from a filter panel
|
||||
* @param page - Playwright page object
|
||||
* @param config - File upload configuration
|
||||
* @returns The Download object
|
||||
*/
|
||||
export async function downloadTemplate(
|
||||
page: Page,
|
||||
config: FileUploadConfig
|
||||
): Promise<Download> {
|
||||
const panel = page.locator(`.rz-card:has-text("${config.panelHeader}")`);
|
||||
|
||||
// Start waiting for download before clicking
|
||||
const downloadPromise = page.waitForEvent('download');
|
||||
|
||||
// Click the download template button
|
||||
await panel.locator('button:has-text("Download Template")').click();
|
||||
|
||||
// Wait for download to complete
|
||||
const download = await downloadPromise;
|
||||
return download;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear uploaded data from a filter panel
|
||||
* @param page - Playwright page object
|
||||
* @param config - File upload configuration
|
||||
*/
|
||||
export async function clearUploadedData(
|
||||
page: Page,
|
||||
config: FileUploadConfig
|
||||
): Promise<void> {
|
||||
const panel = page.locator(`.rz-card:has-text("${config.panelHeader}")`);
|
||||
const clearButton = panel.locator('button:has-text("Clear Data")');
|
||||
|
||||
if (await clearButton.isVisible({ timeout: 2000 }).catch(() => false)) {
|
||||
await clearButton.click();
|
||||
|
||||
// Wait for and confirm the dialog
|
||||
await page.waitForSelector('text=Confirm Clear', { timeout: 5000 });
|
||||
// Click the Ok button inside the dialog
|
||||
await page.locator('.rz-dialog-wrapper button').getByText('Ok', { exact: true }).click();
|
||||
|
||||
// Wait for the grid to update - either "No records" appears or grid rows are removed
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// Wait for dialog to close
|
||||
await page.waitForSelector('.rz-dialog-wrapper', { state: 'hidden', timeout: 5000 }).catch(() => {});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the count of uploaded items in a filter panel
|
||||
* @param page - Playwright page object
|
||||
* @param config - File upload configuration
|
||||
* @returns Number of items in the grid
|
||||
*/
|
||||
export async function getUploadedItemCount(
|
||||
page: Page,
|
||||
config: FileUploadConfig
|
||||
): Promise<number> {
|
||||
const panel = page.locator(`.rz-card:has-text("${config.panelHeader}")`);
|
||||
const grid = panel.locator('.rz-data-grid');
|
||||
|
||||
// Check for "No records" message
|
||||
const noRecords = grid.locator('text=No records to display');
|
||||
if (await noRecords.isVisible({ timeout: 1000 }).catch(() => false)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const rows = grid.locator('tbody tr');
|
||||
return await rows.count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the file upload panel is visible
|
||||
* @param page - Playwright page object
|
||||
* @param config - File upload configuration
|
||||
* @returns true if panel is visible
|
||||
*/
|
||||
export async function isFileUploadPanelVisible(
|
||||
page: Page,
|
||||
config: FileUploadConfig
|
||||
): Promise<boolean> {
|
||||
const panel = page.locator(`text=${config.panelHeader}`);
|
||||
return await panel.isVisible({ timeout: 2000 }).catch(() => false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the uploaded file shows items in the grid
|
||||
* @param page - Playwright page object
|
||||
* @param config - File upload configuration
|
||||
* @returns true if grid has items
|
||||
*/
|
||||
export async function hasUploadedItems(
|
||||
page: Page,
|
||||
config: FileUploadConfig
|
||||
): Promise<boolean> {
|
||||
const count = await getUploadedItemCount(page, config);
|
||||
return count > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the test data directory path
|
||||
*/
|
||||
export function getTestDataDir(): string {
|
||||
return path.join(__dirname, '..', 'test-data');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the path to a test data file
|
||||
* @param filename - The filename in the test-data directory
|
||||
*/
|
||||
export function getTestDataPath(filename: string): string {
|
||||
return path.join(getTestDataDir(), filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard test files available in test-data directory
|
||||
*/
|
||||
export const TestFiles = {
|
||||
// Work Order files
|
||||
SINGLE_WORKORDER: 'single_workorder.xlsx',
|
||||
MULTIPLE_WORKORDERS: 'multiple_workorders.xlsx',
|
||||
|
||||
// Component Lot files
|
||||
SINGLE_LOT: 'single_lot.xlsx',
|
||||
MULTIPLE_LOTS: 'multiple_lots.xlsx',
|
||||
|
||||
// Item Number files
|
||||
SINGLE_ITEM: 'single_item.xlsx',
|
||||
MULTIPLE_ITEMS: 'multiple_items.xlsx',
|
||||
|
||||
// Part Operation files
|
||||
SINGLE_OPERATION: 'single_operation.xlsx',
|
||||
MULTIPLE_OPERATIONS: 'multiple_operations.xlsx',
|
||||
|
||||
// Invalid files (for negative testing)
|
||||
INVALID_FORMAT: 'invalid_format.txt',
|
||||
EMPTY_FILE: 'empty_file.xlsx',
|
||||
INVALID_WORKORDERS: 'invalid_workorders.xlsx',
|
||||
SPECIAL_CHARS_WORKORDERS: 'special_chars_workorders.xlsx',
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* Get full path to a standard test file
|
||||
* @param testFile - One of the TestFiles constants
|
||||
*/
|
||||
export function getTestFile(testFile: string): string {
|
||||
return getTestDataPath(testFile);
|
||||
}
|
||||
Reference in New Issue
Block a user