refactor: consolidate AGENTS.md and CLAUDE.md files, update tech stac… (#444)

* refactor: consolidate AGENTS.md and CLAUDE.md files, update tech stack and architecture details

- Merged content from CLAUDE.md into AGENTS.md for better organization.
- Updated tech stack section to reflect the current technologies used, including Next.js, Supabase, and Tailwind CSS.
- Enhanced monorepo structure documentation with detailed directory purposes.
- Streamlined multi-tenant architecture explanation and essential commands.
- Added key patterns for naming conventions and server actions.
- Removed outdated agent files related to Playwright and PostgreSQL, ensuring a cleaner codebase.
- Bumped version to 2.23.7 to reflect changes.
This commit is contained in:
Giancarlo Buomprisco
2026-01-18 10:44:40 +01:00
committed by GitHub
parent bebd56238b
commit cfa137795b
61 changed files with 3636 additions and 9522 deletions

View File

@@ -1,32 +1,23 @@
# End-to-End Testing
## End-to-End Testing with Playwright
## Skills
For E2E test implementation:
- `/playwright-e2e` - Test patterns and Page Objects
## Running Tests
Running the tests for testing single file:
```bash
pnpm --filter web-e2e exec playwright test <partial-name-or-folder-name> --workers=1
```
# Single file (preferred)
pnpm --filter web-e2e exec playwright test <name> --workers=1
Example:
```bash
pnpm --filter web-e2e exec playwright test <partial-name-or-folder-name> --workers=1
```
This is useful for quickly testing a single file or a specific feature and should be your default choice.
Running all tests (rarely needed, only use if asked by the user):
```bash
# All tests
pnpm test
```
### Page Object Pattern (Required)
Always use Page Objects for test organization and reusability:
## Page Object Pattern (Required)
```typescript
// Example: auth.po.ts
export class AuthPageObject {
constructor(private readonly page: Page) {}
@@ -35,91 +26,35 @@ export class AuthPageObject {
await this.page.fill('input[name="password"]', params.password);
await this.page.click('button[type="submit"]');
}
async signOut() {
await this.page.click('[data-test="account-dropdown-trigger"]');
await this.page.click('[data-test="account-dropdown-sign-out"]');
}
}
```
### Reliability Patterns
## Selectors
**Use `toPass()` for flaky operations** - Always wrap unreliable operations:
Always use `data-test` attributes:
```typescript
// ✅ CORRECT - Reliable email/OTP operations
await expect(async () => {
const otpCode = await this.getOtpCodeFromEmail(email);
expect(otpCode).not.toBeNull();
await this.enterOtpCode(otpCode);
}).toPass();
await this.page.click('[data-test="submit-button"]');
await this.page.getByTestId('submit-button').click();
```
// ✅ CORRECT - Network requests with validation
## Reliability with `toPass()`
```typescript
await expect(async () => {
const response = await this.page.waitForResponse(resp =>
resp.url().includes('auth/v1/user')
const response = await this.page.waitForResponse(
resp => resp.url().includes('auth/v1/user')
);
expect(response.status()).toBe(200);
}).toPass();
// ✅ CORRECT - Complex operations with custom intervals
await expect(async () => {
await auth.submitMFAVerification(AuthPageObject.MFA_KEY);
}).toPass({
intervals: [500, 2500, 5000, 7500, 10_000, 15_000, 20_000]
});
```
### Test Data Management
## Test Organization
**Email Testing**: Use `createRandomEmail()` for unique test emails:
```typescript
createRandomEmail() {
const value = Math.random() * 10000000000000;
return `${value.toFixed(0)}@makerkit.dev`;
}
```
**User Bootstrapping**: Use `bootstrapUser()` for consistent test user creation:
```typescript
await auth.bootstrapUser({
email: 'test@example.com',
password: 'testingpassword',
name: 'Test User'
});
tests/
├── authentication/
├── billing/
├── *.po.ts # Page Objects
└── utils/
```
This method creates a user with an API call.
To sign in:
```tsx
await auth.loginAsUser({
email: 'test@example.com',
password: 'testingpassword',
});
```
### Test Selectors
**Always use `data-test` attributes** for reliable element selection:
```typescript
// ✅ CORRECT - Use data-test attributes
await this.page.click('[data-test="submit-button"]');
await this.page.fill('[data-test="email-input"]', email);
// ✅ OR
await this.page.getByTestId('submit-button').click();
// ❌ AVOID - Fragile selectors
await this.page.click('.btn-primary');
await this.page.click('button:nth-child(2)');
```
### Test Organization
- **Feature-based folders**: `/tests/authentication/`, `/tests/billing/`
- **Page Objects**: `*.po.ts` files for reusable page interactions
- **Setup files**: `auth.setup.ts` for global test setup
- **Utility classes**: `/tests/utils/` for shared functionality