T
Tenanto
Documentation / E2E Test Plan

E2E Test Plan

Updated Jan 25, 2026

Comprehensive E2E Test Plan for Tenanto

This document outlines ALL Playwright E2E tests required for complete frontend coverage of the Tenanto SaaS application.


Test Organization

e2e/
├── auth/
│   ├── login.spec.ts           # Login flows
│   ├── logout.spec.ts          # Logout flows
│   ├── register.spec.ts        # Registration flow
│   ├── forgot-password.spec.ts # Password reset request
│   ├── reset-password.spec.ts  # Password reset completion
│   └── verify-email.spec.ts    # Email verification
├── admin/
│   ├── dashboard.spec.ts       # Admin dashboard
│   ├── tenants.spec.ts         # Tenant management (existing)
│   ├── users.spec.ts           # User management
│   └── licenses.spec.ts        # License management
├── tenant/
│   ├── dashboard.spec.ts       # Tenant dashboard & widgets
│   ├── projects.spec.ts        # Project CRUD (existing)
│   ├── tasks.spec.ts           # Task CRUD
│   ├── teams.spec.ts           # Team management
│   ├── users.spec.ts           # Tenant user management
│   ├── billing.spec.ts         # Billing pages (existing)
│   └── profile.spec.ts         # Profile management
├── isolation/
│   ├── tenant-isolation.spec.ts    # Data isolation (existing)
│   ├── cross-tenant-api.spec.ts    # API isolation tests
│   └── permission-isolation.spec.ts # Role-based access
├── api/
│   ├── auth-api.spec.ts        # Authentication API
│   ├── projects-api.spec.ts    # Projects REST API
│   └── tasks-api.spec.ts       # Tasks REST API
├── onboarding/
│   └── wizard.spec.ts          # Onboarding wizard flow
├── errors/
│   └── error-pages.spec.ts     # 403, 404, 500 pages
└── navigation/
    └── navigation.spec.ts      # Sidebar, routing tests

1. Authentication Tests (e2e/auth/)

1.1 Login Tests (login.spec.ts) - EXISTING (4 tests)

1.2 Logout Tests (logout.spec.ts) - NEW

test.describe('Logout Flow', () => {
    // Tenant Panel
    test('tenant user can logout from tenant panel')
    test('after logout, protected routes redirect to login')
    test('after logout, session is destroyed')

    // Admin Panel
    test('admin can logout from admin panel')
    test('admin logout redirects to admin login')
});

1.3 Registration Tests (register.spec.ts) - NEW

test.describe('Registration Flow', () => {
    test('shows registration page with form')
    test('can register with valid data')
    test('shows validation errors for invalid email')
    test('shows validation errors for weak password')
    test('shows validation errors for mismatched passwords')
    test('shows error for duplicate email')
    test('redirects to email verification after registration')
    test('sends verification email after registration')
});

1.4 Forgot Password Tests (forgot-password.spec.ts) - NEW

test.describe('Forgot Password', () => {
    test('shows forgot password page')
    test('can request password reset with valid email')
    test('shows success message after request')
    test('shows validation error for invalid email format')
    test('shows message for non-existent email (no leak)')
    test('sends password reset email')
});

1.5 Reset Password Tests (reset-password.spec.ts) - NEW

test.describe('Reset Password', () => {
    test('shows reset password form with valid token')
    test('can reset password with valid token')
    test('shows error for invalid token')
    test('shows error for expired token')
    test('shows validation error for weak password')
    test('shows validation error for mismatched passwords')
    test('can login with new password after reset')
});

1.6 Email Verification Tests (verify-email.spec.ts) - NEW

test.describe('Email Verification', () => {
    test('unverified user sees verification notice')
    test('unverified user cannot access protected routes')
    test('can resend verification email')
    test('valid verification link verifies email')
    test('invalid verification link shows error')
    test('verified user can access protected routes')
});

2. Admin Panel Tests (e2e/admin/)

2.1 Admin Dashboard Tests (dashboard.spec.ts) - NEW

test.describe('Admin Dashboard', () => {
    test('shows dashboard after login')
    test('displays tenant count widget')
    test('displays user count widget')
    test('displays recent activity widget')
    test('navigation sidebar is visible')
    test('admin profile dropdown works')
});

2.2 Tenant Management Tests (tenants.spec.ts) - EXISTING (4 tests)

Additional tests to add:

test.describe('Admin - Tenant Management Extended', () => {
    test('can search/filter tenants by name')
    test('can search/filter tenants by domain')
    test('can delete tenant')
    test('can view tenant subscription info')
    test('can view tenant users')
    test('pagination works on tenant list')
    test('can create tenant without owner')
    test('slug is auto-generated from name')
    test('shows validation for duplicate slug')
    test('can edit tenant domain')
    test('can toggle tenant active status')
});

2.3 Admin User Management Tests (users.spec.ts) - NEW

test.describe('Admin - User Management', () => {
    test('can view all users list')
    test('can filter users by tenant')
    test('can filter users by role')
    test('can search users by name/email')
    test('can view user details')
    test('can create new user')
    test('can edit user')
    test('can delete user')
    test('cannot delete self')
    test('pagination works')
});

2.4 License Management Tests (licenses.spec.ts) - NEW

test.describe('Admin - License Management', () => {
    test('can view licenses list')
    test('can create new license')
    test('can view license details')
    test('can view license key (masked)')
    test('can copy license key')
    test('can revoke license')
    test('can filter by status (active/revoked)')
    test('license statistics widget displays')
    test('can edit license metadata')
    test('shows validation for required fields')
});

3. Tenant Panel Tests (e2e/tenant/)

3.1 Tenant Dashboard Tests (dashboard.spec.ts) - NEW

test.describe('Tenant Dashboard', () => {
    test('shows dashboard after login')
    test('displays projects overview widget')
    test('displays recent tasks widget')
    test('widget stats are accurate')
    test('navigation sidebar shows all menu items')
    test('clicking widget navigates to related page')
    test('shows correct tenant branding')
});

3.2 Project Management Tests (projects.spec.ts) - EXISTING (3 tests)

Additional tests to add:

test.describe('Projects Management Extended', () => {
    test('can edit project')
    test('can delete project')
    test('can archive project')
    test('can unarchive project')
    test('archived projects appear in archived tab')
    test('can filter projects by status')
    test('can search projects by name')
    test('shows project completion percentage')
    test('can view project tasks')
    test('pagination works')
    test('shows validation for empty name')
    test('shows validation for duplicate name')
    test('project badge shows task count')
});

3.3 Task Management Tests (tasks.spec.ts) - NEW

test.describe('Task Management', () => {
    // List & Navigation
    test('can view tasks list')
    test('can filter tasks by status (todo/in_progress/completed)')
    test('can filter tasks by priority')
    test('can filter tasks by project')
    test('can filter my tasks only')
    test('can search tasks by title')
    test('pagination works')

    // CRUD Operations
    test('can create task from tasks list')
    test('can create task from project detail')
    test('can view task details')
    test('can edit task')
    test('can delete task')

    // Status & Assignment
    test('can change task status')
    test('can mark task as completed')
    test('can assign task to user')
    test('can set task priority')
    test('can set task due date')

    // Validation
    test('shows validation for empty title')
    test('shows validation for required project')

    // Relations
    test('task shows project name')
    test('task shows assignee name')
});

3.4 Team Management Tests (teams.spec.ts) - NEW

test.describe('Team Management', () => {
    // List & Navigation
    test('can view teams list')
    test('can search teams by name')
    test('pagination works')

    // CRUD Operations
    test('can create team')
    test('can view team details')
    test('can edit team')
    test('can delete team')

    // Member Management
    test('can add member to team')
    test('can remove member from team')
    test('can change member role in team')
    test('shows team member count')

    // Validation
    test('shows validation for empty name')
    test('shows validation for duplicate name')
});

3.5 Tenant User Management Tests (users.spec.ts) - NEW

test.describe('Tenant User Management', () => {
    // List & Navigation
    test('can view tenant users list')
    test('can search users by name/email')
    test('pagination works')

    // CRUD Operations
    test('owner can create new user/invite')
    test('can view user details')
    test('owner can edit user')
    test('owner can delete user')

    // Role Management
    test('owner can change user role')
    test('admin cannot change owner role')
    test('member cannot access user management')

    // Constraints
    test('cannot delete self')
    test('cannot delete tenant owner')
    test('shows validation for duplicate email')

    // Permission-based visibility
    test('owner sees all management options')
    test('admin sees limited options')
    test('member cannot see users menu')
});

3.6 Billing Tests (billing.spec.ts) - EXISTING (4 tests)

Additional tests to add:

test.describe('Billing Extended', () => {
    // Subscription Flow
    test('can initiate checkout for plan')
    test('checkout redirects to Stripe')
    test('success page shows after payment')
    test('can access Stripe billing portal')

    // Subscription Management
    test('can view current subscription')
    test('can see subscription status (active/canceled/trial)')
    test('can see trial days remaining')
    test('can cancel subscription')
    test('can resume canceled subscription')
    test('can swap to different plan')

    // Invoices
    test('invoice list shows past invoices')
    test('can download invoice PDF')
    test('empty state shows when no invoices')

    // Plan Comparison
    test('shows feature comparison between plans')
    test('current plan is highlighted')
    test('upgrade/downgrade buttons show correctly')

    // Access Control
    test('only owner can access billing')
    test('admin cannot access billing')
    test('member cannot access billing')
});

3.7 Profile Management Tests (profile.spec.ts) - NEW

test.describe('Profile Management', () => {
    // Profile Info
    test('can view profile page')
    test('shows current user info')
    test('can update name')
    test('can update email')
    test('email change requires re-verification')

    // Password
    test('can change password')
    test('shows error for wrong current password')
    test('shows validation for weak new password')
    test('shows validation for mismatched passwords')

    // Account Deletion
    test('can delete account')
    test('delete requires password confirmation')
    test('delete shows confirmation dialog')
    test('after deletion redirects to login')

    // Validation
    test('shows validation for invalid email')
    test('shows validation for empty name')
});

4. Isolation Tests (e2e/isolation/)

4.1 Tenant Isolation Tests (tenant-isolation.spec.ts) - EXISTING (3 tests)

Additional tests to add:

test.describe('Tenant Isolation Extended', () => {
    // Data Isolation
    test('tenant A cannot see tenant B projects')
    test('tenant A cannot see tenant B tasks')
    test('tenant A cannot see tenant B users')
    test('tenant A cannot see tenant B teams')

    // Direct URL Access
    test('direct URL to other tenant project returns 404')
    test('direct URL to other tenant task returns 404')
    test('direct URL to other tenant user returns 404')

    // Session Isolation
    test('tenant A session not valid on tenant B domain')
    test('login on tenant A does not affect tenant B')
});

4.2 Cross-Tenant API Tests (cross-tenant-api.spec.ts) - NEW

test.describe('Cross-Tenant API Isolation', () => {
    test('API token from tenant A fails on tenant B domain')
    test('API cannot list other tenant projects')
    test('API cannot create project on other tenant')
    test('API cannot update other tenant project')
    test('API cannot delete other tenant project')
    test('API project ID from tenant A returns 404 on tenant B')
    test('API task ID from tenant A returns 404 on tenant B')
});

4.3 Permission Isolation Tests (permission-isolation.spec.ts) - NEW

test.describe('Permission Isolation', () => {
    // Role-based UI
    test('owner sees all admin features')
    test('admin sees limited admin features')
    test('member sees only basic features')

    // Owner-only actions
    test('only owner can access billing')
    test('only owner can delete other users')
    test('only owner can change user roles')

    // Admin actions
    test('admin can create projects')
    test('admin can manage tasks')
    test('admin can manage teams')

    // Member restrictions
    test('member cannot create projects')
    test('member cannot manage users')
    test('member can only see assigned tasks')

    // System admin isolation
    test('system admin cannot access tenant panel')
    test('tenant user cannot access admin panel')
});

5. API Tests (e2e/api/)

5.1 Authentication API Tests (auth-api.spec.ts) - PARTIALLY EXISTING

test.describe('Auth API', () => {
    // Login
    test('POST /auth/login returns token with valid credentials')
    test('POST /auth/login returns 401 with invalid credentials')
    test('POST /auth/login returns 422 with missing fields')
    test('POST /auth/login returns user data with token')

    // Current User
    test('GET /auth/me returns current user')
    test('GET /auth/me returns 401 without token')
    test('GET /auth/me returns 401 with invalid token')

    // Logout
    test('POST /auth/logout invalidates token')
    test('token cannot be reused after logout')

    // Rate Limiting
    test('login is rate limited')
    test('authenticated requests are rate limited')
});

5.2 Projects API Tests (projects-api.spec.ts) - NEW

test.describe('Projects API', () => {
    // List
    test('GET /projects returns project list')
    test('GET /projects supports pagination')
    test('GET /projects supports search filter')
    test('GET /projects supports archived filter')

    // Create
    test('POST /projects creates project')
    test('POST /projects returns 422 for invalid data')
    test('POST /projects sets tenant_id automatically')

    // Read
    test('GET /projects/{id} returns project')
    test('GET /projects/{id} returns 404 for invalid id')
    test('GET /projects/{id} returns 404 for other tenant project')

    // Update
    test('PUT /projects/{id} updates project')
    test('PUT /projects/{id} returns 422 for invalid data')
    test('PUT /projects/{id} returns 404 for other tenant')

    // Delete
    test('DELETE /projects/{id} deletes project')
    test('DELETE /projects/{id} returns 404 for other tenant')

    // Archive
    test('POST /projects/{id}/archive archives project')
    test('POST /projects/{id}/unarchive unarchives project')
});

5.3 Tasks API Tests (tasks-api.spec.ts) - NEW

test.describe('Tasks API', () => {
    // List (scoped to project)
    test('GET /projects/{id}/tasks returns task list')
    test('GET /projects/{id}/tasks supports status filter')
    test('GET /projects/{id}/tasks supports priority filter')
    test('GET /projects/{id}/tasks supports pagination')

    // Create
    test('POST /projects/{id}/tasks creates task')
    test('POST /projects/{id}/tasks returns 422 for invalid data')
    test('POST /projects/{id}/tasks sets tenant_id automatically')

    // Read
    test('GET /tasks/{id} returns task')
    test('GET /tasks/{id} returns 404 for invalid id')
    test('GET /tasks/{id} returns 404 for other tenant task')

    // Update
    test('PUT /tasks/{id} updates task')
    test('PUT /tasks/{id} returns 422 for invalid data')
    test('PUT /tasks/{id} returns 404 for other tenant')

    // Delete
    test('DELETE /tasks/{id} deletes task')
    test('DELETE /tasks/{id} returns 404 for other tenant')

    // Complete
    test('POST /tasks/{id}/complete marks task as completed')
    test('POST /tasks/{id}/complete returns completed_at timestamp')
});

6. Onboarding Tests (e2e/onboarding/)

6.1 Onboarding Wizard Tests (wizard.spec.ts) - NEW

test.describe('Onboarding Wizard', () => {
    // Wizard Flow
    test('new tenant owner sees onboarding wizard')
    test('wizard shows step 1 - welcome')
    test('can proceed to step 2 - company setup')
    test('can proceed to step 3 - invite team')
    test('can proceed to step 4 - complete')
    test('can skip steps')
    test('completing wizard redirects to dashboard')

    // Step Validation
    test('company name is required in step 2')
    test('email format is validated in step 3')

    // Progress Persistence
    test('progress is saved between sessions')
    test('can resume wizard from last step')

    // Skip & Complete
    test('skip button available on optional steps')
    test('completed wizard does not show again')
    test('can manually access wizard from settings')
});

7. Error Pages Tests (e2e/errors/)

7.1 Error Pages Tests (error-pages.spec.ts) - NEW

test.describe('Error Pages', () => {
    // 404 Not Found
    test('shows 404 page for non-existent route')
    test('404 page has back to home link')
    test('404 page shows correct branding')

    // 403 Forbidden
    test('shows 403 page when access denied')
    test('403 page has appropriate message')

    // 500 Server Error (simulated)
    test('500 page shows user-friendly message')
    test('500 page hides stack trace in production')

    // Error Recovery
    test('can navigate home from error pages')
    test('error pages work on tenant subdomain')
    test('error pages work on admin subdomain')
});

8. Navigation Tests (e2e/navigation/)

8.1 Navigation Tests (navigation.spec.ts) - NEW

test.describe('Navigation', () => {
    // Tenant Panel Sidebar
    test('sidebar shows all menu items for owner')
    test('sidebar hides restricted items for member')
    test('sidebar highlights current page')
    test('sidebar collapse/expand works')
    test('sidebar navigation icons are visible')

    // Admin Panel Sidebar
    test('admin sidebar shows all resources')
    test('admin sidebar groups are correct')
    test('admin navigation to all resources works')

    // Breadcrumbs
    test('breadcrumbs show on detail pages')
    test('breadcrumb navigation works')

    // Mobile Navigation
    test('mobile menu toggle works')
    test('mobile sidebar opens/closes')

    // Redirects
    test('root URL redirects based on domain')
    test('dashboard redirects to correct panel')
    test('unauthenticated user redirects to login')

    // Cross-Panel Navigation
    test('cannot navigate from tenant to admin')
    test('cannot navigate from admin to tenant')
});

Test Data Requirements

Seeded Users (for tests)

Email Password Tenant Role
[email protected] password - System Admin
[email protected] password demo Owner
[email protected] password demo Admin
[email protected] password demo Member
[email protected] password acme Owner

Seeded Data


Test Count Summary

Category Existing New Total
Auth 4 28 32
Admin Panel 4 26 30
Tenant Panel 7 58 65
Isolation 3 20 23
API 1 35 36
Onboarding 0 12 12
Error Pages 0 9 9
Navigation 0 15 15
TOTAL 19 203 222

Implementation Priority

Phase 1 - Critical (Must Have)

  1. auth/logout.spec.ts
  2. auth/register.spec.ts
  3. tenant/tasks.spec.ts
  4. isolation/cross-tenant-api.spec.ts
  5. Extended tenant/projects.spec.ts
  6. Extended admin/tenants.spec.ts

Phase 2 - Important

  1. tenant/teams.spec.ts
  2. tenant/users.spec.ts
  3. tenant/profile.spec.ts
  4. admin/users.spec.ts
  5. admin/licenses.spec.ts
  6. Extended tenant/billing.spec.ts

Phase 3 - Nice to Have

  1. auth/forgot-password.spec.ts
  2. auth/reset-password.spec.ts
  3. auth/verify-email.spec.ts
  4. onboarding/wizard.spec.ts
  5. errors/error-pages.spec.ts
  6. navigation/navigation.spec.ts

Phase 4 - Complete Coverage

  1. admin/dashboard.spec.ts
  2. tenant/dashboard.spec.ts
  3. api/auth-api.spec.ts
  4. api/projects-api.spec.ts
  5. api/tasks-api.spec.ts
  6. isolation/permission-isolation.spec.ts

Test Helpers & Fixtures

Recommended Test Helpers

// e2e/helpers/auth.ts
export async function loginAsTenantOwner(page: Page) { ... }
export async function loginAsTenantAdmin(page: Page) { ... }
export async function loginAsTenantMember(page: Page) { ... }
export async function loginAsSystemAdmin(page: Page) { ... }
export async function logout(page: Page) { ... }

// e2e/helpers/api.ts
export async function getApiToken(request: APIRequestContext, email: string) { ... }
export async function createProject(request: APIRequestContext, token: string, data: object) { ... }
export async function createTask(request: APIRequestContext, token: string, projectId: string, data: object) { ... }

// e2e/fixtures/index.ts
export const testUsers = { ... }
export const testTenants = { ... }

Notes

  1. Mobile Tests: Mobile viewport tests are expected to have some failures due to Filament's desktop-first design. Focus on desktop browsers.

  2. Stripe Tests: Billing checkout tests require Stripe test mode and test cards. Use 4242 4242 4242 4242 for success scenarios.

  3. Email Tests: Email-related tests (verification, password reset) should use Mailhog for local testing.

  4. Flaky Tests: Admin login tests may be flaky due to Livewire initialization. Use appropriate waits.

  5. Parallelism: Keep workers limited (3 max) to avoid server contention with Livewire forms.


Last updated: 2025-12-05