This directory contains standalone HTML test files that load and test the built Sonar Quiz System artifacts from the dist folder.
Purpose: Demonstrates the quiz index page with login UI and navigation Features:
- Login panel (
qd-logincomponent) for student authentication - Status panel (
qd-statuscomponent) showing progress - Navigation links with R/A/G (Red/Amber/Green) status badges
- Links to quiz and analysis pages
- Publication title element (
.wh_publication_title .title) - REQUIRED for Release ID extraction
What it tests:
- Login component rendering and interaction
- Status panel injection into
#qd-statusdiv - Home badge initialization for navigation links
- Event system (
qd:login,qd:state-changed) - Session management and storage
Purpose: Demonstrates interactive quiz tables with MCQ and numeric questions Features:
- Mixed MCQ and numeric question tables
- MCQ-only table examples
- Numeric-only table examples
- Proper
qd-quizclass markup - Authoring guidelines
What it tests:
- Quiz table detection and parsing
- Table enhancement with interactive controls
- Answer validation (MCQ 1-indexed, numeric with tolerance)
- Answer storage in IndexedDB
qd:answer-savedevents- State calculation (unstarted → incomplete → complete)
Purpose: Demonstrates editable analysis tables for free-form student input Features:
- Various analysis table layouts
- Interactive vs read-only cells
- Mixed pre-filled and editable content
- Proper
qd-analysisclass andinteractiveclass markup - Authoring guidelines
What it tests:
- Analysis table detection and parsing
- Cell-level editability based on
interactiveclass - Cell key generation (R{row}C{col}#f:{hash})
- Auto-save functionality
- 500 character cell limit
- Storage persistence
Configuration Spans (Hidden Elements)
All demo HTML files include hidden configuration spans that are read by the system at runtime. These are typically injected by the DITA/Oxygen XSL transform:
<body>
<!-- Configuration (hidden, injected by Oxygen XSL transform) -->
<span id="qd-status-container" style="display:none;">.wh_top_menu_and_indexterms_link</span>
<span id="qd-title-selector" style="display:none;">.wh_publication_title .title</span>
<span id="qd-db-name" style="display:none;">BrowserTest</span>
<span id="qd-instructor-hash" style="display:none;">5e884898da28...</span>
<!-- ... page content ... -->
</body>Configuration IDs:
#qd-status-container: CSS selector where status panel should be injected (default:.wh_top_menu_and_indexterms_link)#qd-title-selector: CSS selector for publication title element containing Release ID (default:.wh_publication_title .title)#qd-db-name: IndexedDB database name (default:BrowserTest)#qd-instructor-hash: SHA-256 hash of instructor password (optional, for instructor login)
The publication title element MUST exist in the document and match the selector specified in #qd-title-selector:
<div class="wh_publication_title">
<span class="title">TRV Connectors Autumn 2025</span>
</div>Why it matters:
- The
ReleaseIdis extracted from this element's textContent - This element is automatically added by DITA/Oxygen WebHelp publishing
- Login will FAIL without this element: "Release not found"
- There is NO release input field in the login form - release comes from this DOM element only
Common mistake: Attempting to read release from a form input. The login form only has serviceId and name fields.
- Build the project to generate the dist bundle:
This creates
npm run build
dist/sonar-quiz.iife.jsanddist/sonar-quiz.esm.js
-
Open the HTML files directly in your browser using
file://protocol:# On Linux/Mac open demo/quiz-index.html # Or manually navigate to: # file:///path/to/BrowserTest/demo/quiz-index.html
-
Note: IndexedDB may have restrictions in
file://protocol depending on browser:- Chrome/Edge: Works with
--allow-file-access-from-filesflag - Firefox: Works by default
- Safari: Works with "Disable Local File Restrictions" in Develop menu
- Chrome/Edge: Works with
Serve the files over HTTP to test with full browser features:
# Using Python
python3 -m http.server 8000
# Using Node.js http-server
npx http-server -p 8000
# Using Vite preview (from project root)
npm run previewThen navigate to:
- http://localhost:8000/demo/quiz-index.html
- http://localhost:8000/demo/quiz-examples.html
- http://localhost:8000/demo/analysis-examples.html
- Open
quiz-index.html - Verify login component appears
- Enter service ID (e.g., "RN2344") and name
- Click "Login"
- Verify status panel updates to show progress
Expected Results:
- Login form renders correctly
- Validation works (alphanumeric service ID, 2-10 chars)
qd:loginevent fires- Session stored in sessionStorage
- Status panel shows "Your Progress"
- Console shows debug logs (when
DEBUG_MODE = true)
- From index, click "Sonar Basics" →
quiz-examples.html - Verify quiz tables are enhanced with interactive controls
- Answer some MCQ questions (select options)
- Answer some numeric questions (enter values)
- Check console for
qd:answer-savedevents - Verify answers persist on page reload
Expected Results:
- Tables enhanced with input controls
- MCQ: 1-indexed selection (1 = first option)
- Numeric: Tolerance validation
- Answers saved to IndexedDB
- State changes from unstarted → incomplete
- Page state badge updates on index
- From index, click "Contact Analysis" →
analysis-examples.html - Verify cells with
class="interactive"are editable - Enter text in editable cells
- Verify read-only cells cannot be edited
- Check auto-save (debounced ~200ms)
- Reload page and verify data persists
Expected Results:
- Only
interactivecells are editable - Text inputs render in editable cells
- Auto-save triggers after typing stops
- Cell keys generated correctly (R{row}C{col}#f:{hash})
- Data persists in storage
- 500 character limit enforced
- Login on index page
- Navigate to quiz/analysis pages
- Answer questions
- Wait for session timeout (30 min) OR manually clear sessionStorage
- Verify auto-logout behavior
Expected Results:
- Session persists across page navigation
lastActivitytimestamp updates- Session expires after 30 min inactivity
qd:logoutevent fires on expiry- User redirected to login
- Login and answer some questions
- Return to index page
- Verify badge colors update:
- Red: Unstarted (no answers)
- Amber: Incomplete (some answered OR any incorrect)
- Green: Complete (all answered AND all correct)
Expected Results:
- Badges render next to navigation links
- Colors match page completion state
- States calculate correctly
- Cache updates propagate to badges
Debug mode is controlled by the DEBUG_MODE constant in src/index.ts:
const DEBUG_MODE = true; // Set to false for productionAll HTML files use a simple script tag with no attributes:
<script defer src="../dist/sonar-quiz.iife.js"></script>When DEBUG_MODE = true, the system enables:
- Console logging of all events
- Initialization messages
- State transition logs
- Storage monitor component (toggle with
Ctrl+Shift+D) - Validation error banners (if any)
To disable debug mode, set DEBUG_MODE = false in src/index.ts and rebuild.
- Open DevTools → Application/Storage tab
- IndexedDB: Look for
qd/{release}/u{serviceId}keys- Should contain
StudentRecordwith answers and page data
- Should contain
- sessionStorage: Look for
qd/sessionandqd/statekeysqd/session: Current session dataqd/state: Session cache (totals, page states)
- Open DevTools → Console
- Monitor for custom events:
qd:init- System initializedqd:login- User logged inqd:logout- User logged outqd:answer-saved- Answer persistedqd:state-changed- Page state updated
Since the system is offline-first:
- No network requests should occur during normal operation
- All data stays local (IndexedDB/sessionStorage)
- No telemetry, CDN, or remote config calls
demo/
├── README.md # This file
├── quiz-index.html # NEW: Index page with login & navigation
├── quiz-examples.html # UPDATED: Loads dist bundle
├── analysis-examples.html # UPDATED: Loads dist bundle
└── (other files...)
dist/ # Generated by npm run build
├── sonar-quiz.iife.js # IIFE bundle (auto-init)
├── sonar-quiz.iife.js.map # Source map
├── sonar-quiz.esm.js # ESM bundle
├── sonar-quiz.esm.js.map # Source map
└── index.d.ts # TypeScript definitions
Check:
- Table has
class="qd-quiz"orclass="qd-analysis" - Script loaded (check console for errors)
- No JavaScript errors blocking initialization
Check:
- Index page has
<div id="qd-status"></div> - Or system will inject before
<main>or first child of<body> - Custom elements registered (check
customElements.get('qd-login'))
Check:
- Browser supports IndexedDB
- No storage quota exceeded
- Console for save errors
- Network tab shows no blocking requests
Check:
- sessionStorage enabled in browser
- Not in private/incognito mode (sessionStorage cleared on close)
- Session timeout not exceeded (30 min)
Check:
- Links have
class="qd-test-link" data-page-idattribute matches page IDs in storage- Cache being updated on answer save
- Console for
qd:state-changedevents
These HTML files can be used for:
- Manual Testing: Open in browser to verify functionality
- E2E Testing: Playwright/Puppeteer can automate interactions
- Visual Regression: Chromatic snapshots
- Bundle Size Verification: Check
dist/sonar-quiz.iife.jssize - Smoke Tests: Verify bundle loads without errors
- Offline-first: No network dependencies, works from
file://URLs - Progressive Enhancement: Works without JavaScript (shows static tables)
- Zero Configuration: Single
<script>tag, auto-initializes - Bundle Size: IIFE bundle must be ≤35KB min+gzip
- Browser Support: Chrome/Edge ≥96, Firefox ≥102
- Accessibility: WCAG 2.1 Level AA compliant
/home/user/BrowserTest/CLAUDE.md- Project overview and architecture/home/user/BrowserTest/specs/001-sonar-quiz-system/spec.md- Full feature spec/home/user/BrowserTest/docs/System_Requirements.md- Functional requirements/home/user/BrowserTest/docs/Technical_Design.md- Technical architecture