Files
spliit/tests/pom/group-page.ts
Sebastien Castiel 4d58ff9946 Complete E2E test implementation with comprehensive reliability fixes
- Implement Priority 1 E2E test coverage for critical user journeys:
  * Group lifecycle management (creation, navigation, editing)
  * Basic expense management (create, view, edit, delete)
  * Balance calculation and verification
  * Multiple expense scenarios and split calculations

- Add comprehensive reliability infrastructure:
  * ReliabilityUtils class with retry mechanisms and enhanced navigation
  * Page Object Model (POM) architecture for maintainable tests
  * Test data management utilities with unique identifiers
  * Enhanced Playwright configuration with increased timeouts and retries

- Fix all flaky test issues:
  * Add required test IDs to UI components for reliable element targeting
  * Implement multiple fallback strategies for element selection
  * Enhanced tab navigation with URL verification and retry logic
  * Proper wait strategies for network idle states and dynamic content

- Test results: 39/39 tests passing (100% success rate) across all browsers

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-04 22:04:18 -04:00

42 lines
1.1 KiB
TypeScript

import { Locator, Page } from '@playwright/test'
export class GroupPage {
page: Page
title: Locator
constructor(page: Page) {
this.page = page
this.title = page.getByTestId('group-name')
}
async createExpense() {
// Wait for the page to be in a stable state before clicking
await this.page.waitForLoadState('networkidle')
// Retry clicking the create expense link if it fails
for (let attempt = 0; attempt < 3; attempt++) {
try {
await this.page.getByRole('link', { name: 'Create expense' }).click({ timeout: 5000 })
break
} catch (error) {
if (attempt === 2) throw error
await this.page.waitForTimeout(1000)
await this.page.waitForLoadState('networkidle')
}
}
}
async waitForGroupPageLoad() {
// Wait for group name to be visible
await this.title.waitFor({ state: 'visible' })
// Wait for network to be idle
await this.page.waitForLoadState('networkidle')
}
getExpenseCard(expenseTitle: string) {
return this.page
.locator('[data-expense-card]')
.filter({ hasText: expenseTitle })
}
}