Files
jdescopingtool/TestScripts/deprecated/playwright/helpers/radzen.helper.ts
T

260 lines
8.4 KiB
TypeScript

import { Page, expect, Locator } from '@playwright/test';
/**
* Notification types in Radzen
*/
export type NotificationType = 'success' | 'error' | 'warning' | 'info';
/**
* Badge style types matching Radzen badge styles
*/
export type BadgeStyle = 'danger' | 'success' | 'info' | 'warning' | 'primary' | 'secondary';
/**
* Wait for a notification of a specific type to appear
* @param page - Playwright page object
* @param type - The notification type to wait for
* @param timeout - Maximum time to wait (default: 5000ms)
*/
export async function waitForNotification(
page: Page,
type: NotificationType,
timeout: number = 5000
): Promise<void> {
const notificationClass = `.rz-notification-${type}`;
await page.locator(notificationClass).waitFor({ state: 'visible', timeout });
}
/**
* Wait for any notification to appear
* @param page - Playwright page object
* @param timeout - Maximum time to wait (default: 5000ms)
*/
export async function waitForAnyNotification(
page: Page,
timeout: number = 5000
): Promise<void> {
await page.locator('.rz-notification').waitFor({ state: 'visible', timeout });
}
/**
* Check if an error notification is visible
* @param page - Playwright page object
* @returns true if error notification is visible
*/
export async function hasErrorNotification(page: Page): Promise<boolean> {
return await page.locator('.rz-notification-error').isVisible({ timeout: 2000 }).catch(() => false);
}
/**
* Check if a success notification is visible
* @param page - Playwright page object
* @returns true if success notification is visible
*/
export async function hasSuccessNotification(page: Page): Promise<boolean> {
return await page.locator('.rz-notification-success').isVisible({ timeout: 2000 }).catch(() => false);
}
/**
* Assert that no error notification is visible
* @param page - Playwright page object
* @param timeout - Time to wait before asserting (default: 5000ms)
*/
export async function assertNoErrorNotification(page: Page, timeout: number = 5000): Promise<void> {
const errorNotification = page.locator('.rz-notification-error');
await expect(errorNotification).not.toBeVisible({ timeout });
}
/**
* Get the row count from a data grid
* @param page - Playwright page object
* @param gridLocator - Locator for the specific grid (or defaults to first grid)
* @returns Number of rows in the grid body
*/
export async function getDataGridRowCount(
page: Page,
gridLocator?: Locator
): Promise<number> {
const grid = gridLocator ?? page.locator('.rz-data-grid').first();
// 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();
}
/**
* Double-click a row in a data grid
* @param page - Playwright page object
* @param rowIndex - Zero-based index of the row to double-click
* @param gridLocator - Locator for the specific grid (or defaults to first grid)
*/
export async function doubleClickDataGridRow(
page: Page,
rowIndex: number,
gridLocator?: Locator
): Promise<void> {
const grid = gridLocator ?? page.locator('.rz-data-grid').first();
const rows = grid.locator('tbody tr');
await rows.nth(rowIndex).dblclick();
await page.waitForTimeout(500);
}
/**
* Click a row in a data grid
* @param page - Playwright page object
* @param rowIndex - Zero-based index of the row to click
* @param gridLocator - Locator for the specific grid (or defaults to first grid)
*/
export async function clickDataGridRow(
page: Page,
rowIndex: number,
gridLocator?: Locator
): Promise<void> {
const grid = gridLocator ?? page.locator('.rz-data-grid').first();
const rows = grid.locator('tbody tr');
await rows.nth(rowIndex).click();
await page.waitForTimeout(300);
}
/**
* Get text content from a specific cell in a data grid
* @param page - Playwright page object
* @param rowIndex - Zero-based row index
* @param columnIndex - Zero-based column index
* @param gridLocator - Locator for the specific grid (or defaults to first grid)
* @returns Cell text content
*/
export async function getDataGridCellText(
page: Page,
rowIndex: number,
columnIndex: number,
gridLocator?: Locator
): Promise<string> {
const grid = gridLocator ?? page.locator('.rz-data-grid').first();
const cell = grid.locator(`tbody tr:nth-child(${rowIndex + 1}) td:nth-child(${columnIndex + 1})`);
return await cell.textContent() ?? '';
}
/**
* Check if a data grid shows "No records to display"
* @param page - Playwright page object
* @param gridLocator - Locator for the specific grid (or defaults to first grid)
* @returns true if no records message is visible
*/
export async function dataGridIsEmpty(
page: Page,
gridLocator?: Locator
): Promise<boolean> {
const grid = gridLocator ?? page.locator('.rz-data-grid').first();
const noRecords = grid.locator('text=No records to display');
return await noRecords.isVisible({ timeout: 2000 }).catch(() => false);
}
/**
* Wait for dialog to appear with specific title
* @param page - Playwright page object
* @param title - Dialog title text
* @param timeout - Maximum time to wait (default: 5000ms)
*/
export async function waitForDialog(
page: Page,
title: string,
timeout: number = 5000
): Promise<void> {
await page.locator(`.rz-dialog:has-text("${title}")`).waitFor({ state: 'visible', timeout });
}
/**
* Click OK button in a dialog
* @param page - Playwright page object
*/
export async function clickDialogOk(page: Page): Promise<void> {
await page.locator('.rz-dialog button:has-text("OK")').click();
await page.waitForTimeout(300);
}
/**
* Click Cancel button in a dialog
* @param page - Playwright page object
*/
export async function clickDialogCancel(page: Page): Promise<void> {
await page.locator('.rz-dialog button:has-text("Cancel")').click();
await page.waitForTimeout(300);
}
/**
* Confirm a dialog (waits for dialog and clicks OK)
* @param page - Playwright page object
* @param title - Dialog title to wait for
*/
export async function confirmDialog(page: Page, title: string): Promise<void> {
await waitForDialog(page, title);
await clickDialogOk(page);
}
/**
* Get the badge style from a badge element
* @param badge - Locator for the badge element
* @returns The badge style or null if not found
*/
export async function getBadgeStyle(badge: Locator): Promise<BadgeStyle | null> {
const classes = await badge.getAttribute('class') ?? '';
if (classes.includes('rz-badge-danger')) return 'danger';
if (classes.includes('rz-badge-success')) return 'success';
if (classes.includes('rz-badge-info')) return 'info';
if (classes.includes('rz-badge-warning')) return 'warning';
if (classes.includes('rz-badge-primary')) return 'primary';
if (classes.includes('rz-badge-secondary')) return 'secondary';
return null;
}
/**
* Check if a button is disabled
* @param page - Playwright page object
* @param buttonText - Text content of the button
* @returns true if button is disabled
*/
export async function isButtonDisabled(page: Page, buttonText: string): Promise<boolean> {
const button = page.locator(`button:has-text("${buttonText}")`);
return await button.isDisabled();
}
/**
* Click a button by its text
* @param page - Playwright page object
* @param buttonText - Text content of the button
*/
export async function clickButton(page: Page, buttonText: string): Promise<void> {
await page.locator(`button:has-text("${buttonText}")`).click();
await page.waitForTimeout(300);
}
/**
* Get the text content of a badge by its parent context
* @param page - Playwright page object
* @param contextText - Text near the badge to identify it
* @returns Badge text content
*/
export async function getBadgeText(page: Page, contextText: string): Promise<string> {
const badge = page.locator(`:has-text("${contextText}") .rz-badge`).first();
return await badge.textContent() ?? '';
}
/**
* Status badge style mapping (from Blazor code)
*/
export const StatusBadgeStyles: Record<string, BadgeStyle> = {
'Error': 'danger',
'Ended': 'success',
'Running': 'info',
'Queued': 'warning',
'New': 'secondary',
};