Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 18:17:04 +08:00
commit e758c0ab84
56 changed files with 9997 additions and 0 deletions

View File

@@ -0,0 +1,91 @@
import { Page, Locator } from '@playwright/test';
/**
* HomePage Page Object Model
*
* Example POM for a React + Vite application homepage
* Demonstrates best practices for locator selection
*/
export class HomePage {
readonly page: Page;
// Locators - Using semantic selectors (priority: getByRole > getByLabel > getByText > getByTestId)
readonly welcomeMessage: Locator;
readonly aboutLink: Locator;
readonly contactLink: Locator;
readonly navbar: Locator;
readonly heroSection: Locator;
readonly ctaButton: Locator;
readonly featureCards: Locator;
constructor(page: Page) {
this.page = page;
// Initialize locators with semantic selectors
this.navbar = page.getByRole('navigation');
this.welcomeMessage = page.getByRole('heading', { name: /welcome/i });
this.aboutLink = page.getByRole('link', { name: /about/i });
this.contactLink = page.getByRole('link', { name: /contact/i });
this.heroSection = page.getByRole('banner');
this.ctaButton = page.getByRole('button', { name: /get started/i });
this.featureCards = page.getByRole('article');
}
/**
* Navigate to homepage
*/
async goto() {
await this.page.goto('/');
await this.page.waitForLoadState('networkidle');
}
/**
* Wait for page to be fully loaded and ready
*/
async waitForReady() {
await this.welcomeMessage.waitFor({ state: 'visible' });
await this.navbar.waitFor({ state: 'visible' });
}
/**
* Navigate to About page
*/
async goToAbout() {
await this.aboutLink.click();
await this.page.waitForURL('**/about');
}
/**
* Navigate to Contact page
*/
async goToContact() {
await this.contactLink.click();
await this.page.waitForURL('**/contact');
}
/**
* Click the main CTA button
*/
async clickCTA() {
await this.ctaButton.click();
}
/**
* Get count of feature cards
*/
async getFeatureCardCount(): Promise<number> {
return await this.featureCards.count();
}
/**
* Take screenshot of homepage
*/
async screenshot(name: string = 'homepage') {
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
await this.page.screenshot({
path: `screenshots/current/${name}-${timestamp}.png`,
fullPage: true,
});
}
}