mirror of
https://github.com/spliit-app/spliit.git
synced 2026-02-08 16:46:12 +01:00
- 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>
42 lines
1.1 KiB
TypeScript
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 })
|
|
}
|
|
}
|