99 lines
3.5 KiB
TypeScript
99 lines
3.5 KiB
TypeScript
import { Page, Locator } from '@playwright/test';
|
|
import { TestConfig } from '../types';
|
|
import { defaultConfig } from '../config/base.config';
|
|
|
|
export class BasePage {
|
|
readonly page: Page;
|
|
readonly config: TestConfig;
|
|
readonly url: string;
|
|
|
|
constructor(page: Page, url: string, config?: TestConfig) {
|
|
this.page = page;
|
|
this.url = url;
|
|
this.config = config || defaultConfig;
|
|
}
|
|
|
|
async navigate(): Promise<void> {
|
|
await this.page.goto(this.url, { waitUntil: 'networkidle', timeout: this.config.timeout });
|
|
}
|
|
|
|
async waitForLoadState(state: 'load' | 'domcontentloaded' | 'networkidle' = 'load'): Promise<void> {
|
|
await this.page.waitForLoadState(state, { timeout: this.config.timeout });
|
|
}
|
|
|
|
async click(locator: Locator | string): Promise<void> {
|
|
const element = typeof locator === 'string' ? this.page.locator(locator) : locator;
|
|
await element.click({ timeout: this.config.timeout });
|
|
}
|
|
|
|
async fill(locator: Locator | string, value: string): Promise<void> {
|
|
const element = typeof locator === 'string' ? this.page.locator(locator) : locator;
|
|
await element.fill(value);
|
|
}
|
|
|
|
async getText(locator: Locator | string): Promise<string> {
|
|
const element = typeof locator === 'string' ? this.page.locator(locator) : locator;
|
|
return await element.textContent() || '';
|
|
}
|
|
|
|
async isVisible(locator: Locator | string): Promise<boolean> {
|
|
const element = typeof locator === 'string' ? this.page.locator(locator) : locator;
|
|
return await element.isVisible();
|
|
}
|
|
|
|
async waitForElement(locator: Locator | string, timeout?: number): Promise<void> {
|
|
const element = typeof locator === 'string' ? this.page.locator(locator) : locator;
|
|
await element.waitFor({ state: 'visible', timeout: timeout || this.config.timeout });
|
|
}
|
|
|
|
async scrollToElement(locator: Locator | string): Promise<void> {
|
|
const element = typeof locator === 'string' ? this.page.locator(locator) : locator;
|
|
await element.scrollIntoViewIfNeeded();
|
|
}
|
|
|
|
async takeScreenshot(filename: string): Promise<void> {
|
|
const screenshotDir = 'test-framework/reports/screenshots';
|
|
await this.page.screenshot({ path: `${screenshotDir}/${filename}` });
|
|
}
|
|
|
|
async hover(locator: Locator | string): Promise<void> {
|
|
const element = typeof locator === 'string' ? this.page.locator(locator) : locator;
|
|
await element.hover();
|
|
}
|
|
|
|
async getCurrentURL(): Promise<string> {
|
|
return this.page.url();
|
|
}
|
|
|
|
async getTitle(): Promise<string> {
|
|
return await this.page.title();
|
|
}
|
|
|
|
async getAttribute(locator: Locator | string, attribute: string): Promise<string | null> {
|
|
const element = typeof locator === 'string' ? this.page.locator(locator) : locator;
|
|
return await element.getAttribute(attribute);
|
|
}
|
|
|
|
async measurePerformance(): Promise<{
|
|
loadTime: number;
|
|
domContentLoaded: number;
|
|
firstPaint: number;
|
|
firstContentfulPaint: number;
|
|
}> {
|
|
const metrics = await this.page.evaluate(() => {
|
|
const performance = window.performance;
|
|
const timing = performance.timing;
|
|
const navigation = performance.getEntriesByType('navigation')[0] as PerformanceNavigationTiming;
|
|
|
|
return {
|
|
loadTime: timing.loadEventEnd - timing.navigationStart,
|
|
domContentLoaded: timing.domContentLoadedEventEnd - timing.navigationStart,
|
|
firstPaint: navigation ? navigation.loadEventEnd - navigation.fetchStart : 0,
|
|
firstContentfulPaint: navigation ? navigation.domContentLoadedEventEnd - navigation.fetchStart : 0,
|
|
};
|
|
});
|
|
|
|
return metrics;
|
|
}
|
|
}
|