# Playwright Testing Plan — SupportHub

## Status: Ready to Plan (IDs/data-testid added 2026-02-26)

## Context

All HTML templates have been audited and tagged with stable selectors (IDs, `data-testid`, `data-*` attributes) specifically to support Playwright end-to-end testing. The next step is to enter **plan mode** and design the full Playwright test suite.

## What Was Done (2026-02-26)

### HTML Identifiers Added

Every page now has a top-level `id` on its container div for easy page detection, plus granular IDs/data-testid on interactive elements and key sections.

#### base.html (shared layout)
- `id="top-nav"` — top navigation bar
- `id="logo-link"` + `data-testid="logo-link"` — SupportHub logo link
- `id="user-menu"` — user avatar + sync + logout area
- `id="sync-button"` — sync messages button (pre-existing)
- `id="logout-link"` + `data-testid="logout"` — logout link
- `id="sidebar-nav"` — sidebar navigation container (pre-existing)
- `data-testid="nav-dashboard"` through `data-testid="nav-settings"` — all sidebar nav links
- `id="main-content"` — main content area
- `id="flash-container"` — flash messages container (pre-existing)

#### login.html
- `id="login-form"` — login form
- `id="login-error"` — error message banner
- `id="username"` / `id="password"` — input fields (pre-existing)
- `id="login-submit"` — submit button

#### dashboard.html
- `id="dashboard-page"` — page container
- `id="dashboard-date-form"` — date range filter form
- `id="date-from"` / `id="date-to"` — date inputs
- `id="date-apply-btn"` — apply button
- `id="ticket-stats"` — ticket stat cards grid
- `data-testid="stat-total"`, `stat-unread`, `stat-open`, `stat-avg-response` — individual stat cards
- `id="revenue-stats"` — revenue stat cards grid
- `data-testid="stat-total-revenue"`, `stat-recent-revenue`, `stat-total-orders`, `stat-avg-order`
- `id="status-breakdown"` / `id="priority-breakdown"` — bar chart sections
- `id="expiring-section"` — expired support alerts
- `id="recent-activity"` / `id="recent-activity-table"` — recent activity section/table
- `id="sync-orders-btn"` — sync orders button (pre-existing)
- Chart canvases: `ordersRevenueChart`, `productChart`, `geoChart`, `segmentChart` (pre-existing)

#### inbox.html
- `id="inbox-page"` — page container
- `id="inbox-filter-form"` — filter form
- `id="inbox-status-filter"` / `id="inbox-priority-filter"` / `id="inbox-tag-filter"` / `id="inbox-search-filter"` — filter inputs
- `id="inbox-product-filter"` — product filter (pre-existing)
- `id="inbox-filter-btn"` — filter submit button
- `id="inbox-clear-filters"` — clear filters link
- `id="sortSelect"` — sort dropdown (pre-existing)
- `id="inbox-table"` / `id="inbox-tbody"` — table/body (pre-existing)
- `data-testid="ticket-row"` + `data-ticket-id` — ticket rows
- `data-ticket-id` + `data-starred` — star buttons (pre-existing)
- `id="inbox-pagination"` — pagination container (pre-existing)

#### ticket.html
- `id="ticket-page"` + `data-ticket-id` — page container with ticket ID
- `id="ticket-header"` — sticky header area
- `id="ticket-subject"` — ticket subject heading
- `id="ticket-id"` — ticket ID label
- `id="ticket-external-link"` + `data-testid="external-link"` — Addons marketplace link
- `id="ticket-product-info"` — product info row
- `id="ticket-controls"` — controls row (status, priority, badges)
- `id="status-select"` / `id="priority-select"` — dropdowns (pre-existing)
- `data-testid="support-status"` — support status badge
- `data-testid="intent-badge"` — AI intent/sentiment badge
- `id="customer-lang-select"` — customer language selector (pre-existing)
- `id="thread-summary"` + `data-testid="thread-summary"` — collapsible TL;DR
- `id="message-thread"` — conversation thread (pre-existing)
- `data-message-id` — individual messages (pre-existing)
- `id="reply-bar"` — reply editor area
- `id="reply-editor"` — Quill editor (pre-existing)
- `id="quick-reply-container"` / `id="quick-reply-select"` — quick replies (pre-existing)
- `id="link-builder-container"` — product link builder (pre-existing)
- `id="send-reply-btn"` — send button (pre-existing)
- `id="reply-attachment"` — file input (pre-existing)
- `id="attachment-chip"` — attachment preview chip (pre-existing)
- `id="ticket-sidebar"` — right sidebar
- `id="missing-info"` + `data-testid="missing-info"` — missing info checklist
- `id="ai-assistant"` — AI assistant section
- `id="generate-ai-btn"` — generate suggestion button (pre-existing)
- `id="ai-suggestions"` — suggestions container (pre-existing)
- `data-testid="ai-suggestion"` + `data-suggestion-id` — individual suggestion cards
- `id="tags-section"` — tags section
- `id="tags-display"` / `id="tags-input"` — tags display/input (pre-existing)
- `id="properties-section"` — properties collapsible
- `data-testid="customer-value"` — customer value section

#### settings.html
- `id="settings-page"` — page container
- `id="settings-sync"` — historical sync section
- `id="settings-auto-close"` — auto-close section
- `id="settings-language"` — language preferences section
- `id="settings-signature"` — reply signature section
- `id="settings-doc-sources"` — documentation sources section
- All internal controls have IDs (pre-existing): `start-btn`, `pause-btn`, `resume-btn`, `auto-close-toggle`, `auto-close-days`, `signature-textarea`, `preferred-language-select`, etc.

#### products.html
- `id="products-page"` — page container
- `id="products-table"` / `id="products-tbody"` — table (pre-existing)
- `id="product-search"` / `id="status-filter"` — filters (pre-existing)
- `.product-row` + data attributes — rows (pre-existing)
- `id="candidates-panel"` — guide candidates panel (pre-existing)

#### guides.html
- `id="guides-page"` — page container
- `id="guides-table"` — guides table

#### orders.html
- `id="orders-page"` — page container
- `id="orders-filter-form"` — filter form
- `id="orders-sort-tabs"` — sort tab buttons
- `id="orders-table"` — orders table
- `id="orders-pagination"` — pagination
- `id="sync-all-btn"` — sync all history button (pre-existing)

#### predefined_messages.html
- `id="quick-replies-page"` — page container
- `id="messages-table"` — messages table
- `id="create-message-btn"` — new message button
- `id="create-modal"` / `id="edit-modal"` — modals (pre-existing)

---

## Planned Playwright Test Suite

### Test Categories (to be designed in plan mode)

1. **Authentication Flow**
   - Login with valid credentials
   - Login with invalid credentials → error message
   - Logout and redirect
   - Session persistence

2. **Navigation & Layout**
   - Sidebar link navigation (all pages reachable)
   - Active state highlighting
   - Badge count visibility in sidebar
   - Responsive behavior (if applicable)

3. **Dashboard**
   - Stat cards render with correct values
   - Revenue cards visible when data exists
   - Charts render (canvas elements exist)
   - Date filter form works
   - Expired support alerts shown
   - Recent activity table populated

4. **Inbox**
   - Ticket list renders with rows
   - Filter by status/priority/search/product/tag
   - Clear filters
   - Sort options work
   - Star toggle
   - Pagination
   - Unread indicators
   - Ticket row click navigates to ticket

5. **Ticket Detail**
   - Header info (subject, ID, product, badges)
   - Message thread renders bubbles
   - Status/priority dropdowns work
   - Intent badge and support status visible
   - Thread summary collapsible
   - Reply editor (Quill) accepts input
   - Send reply flow
   - Attachment handling
   - Quick reply dropdown
   - AI suggestion generation and display
   - "Use as Reply" / "Copy" / "Generate Draft" buttons
   - Tags CRUD
   - Properties sidebar data
   - Translation button
   - Mark as read button

6. **Settings**
   - All sections render
   - Auto-close toggle and save
   - Language settings save
   - Signature save
   - Doc sources add/scrape/delete
   - Historical sync start/pause/resume

7. **Products**
   - Product list renders
   - Search filter
   - Status filter (All/Active/Declined)
   - Column sorting
   - Guide candidates panel open/close
   - External link opens

8. **Guides**
   - Guides list renders
   - Copy markdown button

9. **Orders**
   - Orders list renders
   - Filter form works
   - Sort tabs
   - Pagination
   - Sync all button

10. **Quick Replies**
    - Messages table renders
    - Create new message (modal)
    - Edit message (modal)
    - Delete message

### Technical Approach

- **Framework**: Playwright with Python (pytest-playwright)
- **Fixtures**: Login fixture that creates a session, shared across tests
- **Page Objects**: One per page (LoginPage, DashboardPage, InboxPage, TicketPage, SettingsPage, etc.)
- **Selectors**: Prefer `data-testid` > `id` > CSS class chains
- **Database**: Use the actual SQLite dev database with test data; consider a fixture that seeds known data
- **Server**: Test against local Flask dev server (http://127.0.0.1:5000)

### Prerequisites

- Install: `pip install playwright pytest-playwright`
- Run `playwright install chromium`
- Flask dev server must be running
- Database should have at least a few tickets, products, orders for meaningful tests

---

## How to Start

1. Load this note on any workstation
2. Enter plan mode in Claude Code
3. Design the test suite architecture, page objects, and test files
4. Implement incrementally (auth first, then page-by-page)
