mirror of
https://github.com/n8n-io/n8n.git
synced 2026-05-12 16:10:30 +02:00
152 lines
4.6 KiB
TypeScript
152 lines
4.6 KiB
TypeScript
import type { Locator, Page } from '@playwright/test';
|
|
|
|
export class NotificationsPage {
|
|
readonly page: Page;
|
|
|
|
constructor(page: Page) {
|
|
this.page = page;
|
|
}
|
|
|
|
/**
|
|
* Gets the main container locator for a notification by searching in its title text.
|
|
* @param text The text or a regular expression to find within the notification's title.
|
|
* @returns A Locator for the notification container element.
|
|
*/
|
|
getNotificationByTitle(text: string | RegExp): Locator {
|
|
return this.page.getByRole('alert').filter({
|
|
has: this.page.locator('.el-notification__title').filter({ hasText: text }),
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Gets the main container locator for a notification by searching in its content/body text.
|
|
* This is useful for finding notifications where the detailed message is in the content
|
|
* rather than the title (e.g., error messages with detailed descriptions).
|
|
* @param text The text or a regular expression to find within the notification's content.
|
|
* @returns A Locator for the notification container element.
|
|
*/
|
|
getNotificationByContent(text: string | RegExp): Locator {
|
|
return this.page.getByRole('alert').filter({
|
|
has: this.page.locator('.el-notification__content').filter({ hasText: text }),
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Gets the main container locator for a notification by searching in both title and content.
|
|
* This is the most flexible method as it will find notifications regardless of whether
|
|
* the text appears in the title or content section.
|
|
* @param text The text or a regular expression to find within the notification's title or content.
|
|
* @returns A Locator for the notification container element.
|
|
*/
|
|
getNotificationByTitleOrContent(text: string | RegExp): Locator {
|
|
return this.page.getByRole('alert').filter({ hasText: text });
|
|
}
|
|
|
|
/**
|
|
* Clicks the close button on the FIRST notification matching the text.
|
|
* Fast execution with short timeouts for snappy notifications.
|
|
* @param text The text of the notification to close.
|
|
* @param options Optional configuration
|
|
*/
|
|
async closeNotificationByText(
|
|
text: string | RegExp,
|
|
options: { timeout?: number } = {},
|
|
): Promise<boolean> {
|
|
const { timeout = 2000 } = options;
|
|
|
|
try {
|
|
const notification = this.getNotificationByTitle(text).first();
|
|
await notification.waitFor({ state: 'visible', timeout });
|
|
|
|
const closeBtn = notification.locator('.el-notification__closeBtn');
|
|
await closeBtn.click({ timeout: 500 });
|
|
|
|
// Quick check that it's gone - don't wait long
|
|
await notification.waitFor({ state: 'hidden', timeout: 1000 });
|
|
return true;
|
|
} catch (error) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Wait for a notification to appear with specific text.
|
|
* Reasonable timeout for waiting, but still faster than before.
|
|
* @param text The text to search for in notification title.
|
|
* @param options Optional configuration
|
|
*/
|
|
async waitForNotification(
|
|
text: string | RegExp,
|
|
options: { timeout?: number } = {},
|
|
): Promise<boolean> {
|
|
const { timeout = 5000 } = options;
|
|
|
|
try {
|
|
const notification = this.getNotificationByTitle(text).first();
|
|
await notification.waitFor({ state: 'visible', timeout });
|
|
return true;
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Wait for notification and then close it
|
|
async waitForNotificationAndClose(
|
|
text: string | RegExp,
|
|
options: { timeout?: number } = {},
|
|
): Promise<boolean> {
|
|
const { timeout = 3000 } = options;
|
|
const isVisible = await this.waitForNotification(text, { timeout });
|
|
if (!isVisible) {
|
|
return false;
|
|
}
|
|
return await this.closeNotificationByText(text, { timeout });
|
|
}
|
|
|
|
/**
|
|
* Get all visible notification texts.
|
|
* @returns Array of notification title texts
|
|
*/
|
|
async getAllNotificationTexts(): Promise<string[]> {
|
|
try {
|
|
const titles = this.page.getByRole('alert').locator('.el-notification__title');
|
|
return await titles.allTextContents();
|
|
} catch {
|
|
return [];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Nuclear option: Close everything as fast as possible.
|
|
* No waiting, no error handling, just close and move on.
|
|
*/
|
|
async quickCloseAll(): Promise<void> {
|
|
try {
|
|
const closeButtons = this.page.locator('.el-notification__closeBtn');
|
|
const count = await closeButtons.count();
|
|
|
|
for (let i = 0; i < count; i++) {
|
|
try {
|
|
await closeButtons.nth(i).click({ timeout: 100 });
|
|
} catch {
|
|
// Continue silently
|
|
}
|
|
}
|
|
} catch {
|
|
// Silent fail
|
|
}
|
|
}
|
|
|
|
getErrorNotifications(): Locator {
|
|
return this.page.locator('.el-notification:has(.el-notification--error)');
|
|
}
|
|
|
|
getSuccessNotifications(): Locator {
|
|
return this.page.locator('.el-notification:has(.el-notification--success)');
|
|
}
|
|
|
|
getWarningNotifications(): Locator {
|
|
return this.page.locator('.el-notification:has(.el-notification--warning)');
|
|
}
|
|
}
|