mirror of
https://github.com/proffesor-for-testing/agentic-qe.git
synced 2026-09-19 08:45:47 +08:00
2777ebab3d
Added complete Playwright-based end-to-end test suite for the Agile Testing Days 2025 conference website (https://agiletestingdays.com/). This test suite enables automated functional testing of critical user journeys including registration, payment processing, navigation, and form submissions. Key components: - Comprehensive test plan with 67 BDD scenarios covering navigation, registration, payment, newsletter, FAQ, Call for Papers, speakers, and external integrations - 78+ Playwright test cases organized by priority (P0/P1/P2) with Page Object Model pattern - Complete test infrastructure with fixtures, utilities, and test data factories - Full documentation including setup guide, test execution instructions, and configuration examples - Support for parallel execution, CI/CD integration, and multiple report formats This test suite was created to validate the conference website functionality and can be shared with the Agile Testing Days team. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
114 lines
3.2 KiB
TypeScript
114 lines
3.2 KiB
TypeScript
import { Page, Locator } from '@playwright/test';
|
|
|
|
/**
|
|
* BasePage - Base class for all Page Objects
|
|
* Provides common functionality used across all pages
|
|
*/
|
|
export class BasePage {
|
|
readonly page: Page;
|
|
|
|
constructor(page: Page) {
|
|
this.page = page;
|
|
}
|
|
|
|
// Navigation
|
|
async goto(path: string = '/'): Promise<void> {
|
|
await this.page.goto(path);
|
|
}
|
|
|
|
async clickLogo(): Promise<void> {
|
|
await this.page.click('a[href="/"] img, .logo, header img');
|
|
}
|
|
|
|
// Common elements
|
|
getNavigationMenu(): Locator {
|
|
return this.page.locator('nav, .navigation, .main-menu, header ul');
|
|
}
|
|
|
|
async clickNavigationItem(itemText: string): Promise<void> {
|
|
const nav = this.getNavigationMenu();
|
|
await nav.locator(`text="${itemText}"`).first().click();
|
|
}
|
|
|
|
async waitForPageLoad(): Promise<void> {
|
|
await this.page.waitForLoadState('networkidle');
|
|
}
|
|
|
|
// Form helpers
|
|
async fillInput(selector: string, value: string): Promise<void> {
|
|
await this.page.fill(selector, value);
|
|
}
|
|
|
|
async selectDropdown(selector: string, value: string): Promise<void> {
|
|
await this.page.selectOption(selector, value);
|
|
}
|
|
|
|
async clickButton(text: string): Promise<void> {
|
|
await this.page.click(`button:has-text("${text}"), input[type="submit"][value*="${text}"]`);
|
|
}
|
|
|
|
async checkCheckbox(selector: string): Promise<void> {
|
|
await this.page.check(selector);
|
|
}
|
|
|
|
async uncheckCheckbox(selector: string): Promise<void> {
|
|
await this.page.uncheck(selector);
|
|
}
|
|
|
|
// Validation helpers
|
|
async getValidationError(fieldName: string): Promise<string | null> {
|
|
const errorSelectors = [
|
|
`[name="${fieldName}"] ~ .error, [name="${fieldName}"] ~ .error-message`,
|
|
`[name="${fieldName}"] + .error, [name="${fieldName}"] + .error-message`,
|
|
`.field-${fieldName} .error, .field-${fieldName} .error-message`,
|
|
`#${fieldName}-error, [data-error-for="${fieldName}"]`,
|
|
];
|
|
|
|
for (const selector of errorSelectors) {
|
|
const errorElement = this.page.locator(selector).first();
|
|
if (await errorElement.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
return await errorElement.textContent();
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
async hasValidationError(): Promise<boolean> {
|
|
const errorElements = this.page.locator('.error, .error-message, [class*="error"]');
|
|
return await errorElements.count() > 0;
|
|
}
|
|
|
|
// URL helpers
|
|
async getCurrentUrl(): Promise<string> {
|
|
return this.page.url();
|
|
}
|
|
|
|
async waitForUrl(pattern: string | RegExp): Promise<void> {
|
|
await this.page.waitForURL(pattern);
|
|
}
|
|
|
|
// Content helpers
|
|
async getPageTitle(): Promise<string> {
|
|
return await this.page.title();
|
|
}
|
|
|
|
async hasText(text: string): Promise<boolean> {
|
|
return await this.page.locator(`text=${text}`).isVisible();
|
|
}
|
|
|
|
// External links
|
|
async clickExternalLink(linkText: string): Promise<Page> {
|
|
const [newPage] = await Promise.all([
|
|
this.page.context().waitForEvent('page'),
|
|
this.page.click(`a:has-text("${linkText}")`),
|
|
]);
|
|
await newPage.waitForLoadState();
|
|
return newPage;
|
|
}
|
|
|
|
// Screenshot helper
|
|
async takeScreenshot(name: string): Promise<void> {
|
|
await this.page.screenshot({ path: `test-results/screenshots/${name}.png`, fullPage: true });
|
|
}
|
|
}
|