Epic: Frontend Framework Migration + Automated UI Testing

Open
#299 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
20/100
Issue type
Feature
Clarity
Needs clarification
Activity status
Quiet
Tech stack
fastapi, playwright, python, tailwindcss

Research direction

Start by reading the migration phases, the VISUAL_QA.md interactive-element catalog, and the listed sub-issues to identify a bounded task. For UI testing, inspect tests/ui_functional/test_ui_functional.py and tests/ui_functional/conftest.py, then run the existing suite. Done is defined by the selected migration step being complete and the Playwright tests passing.

Written by the indexing model from the issue text.

Description

frontend testing

Epic: Frontend Framework Migration + Automated UI Testing

This epic tracks:

  1. Selecting and migrating to a modern frontend framework
  2. Establishing a Playwright-based automated functional test suite

🏆 JOB 1: Framework Recommendation

Options Evaluated
Framework Approach Bundle size Build step Mobile-first FastAPI compat
HTMX + Tailwind Hypermedia, Jinja2 stays Tiny (CDN) No ✅ Tailwind ✅ Perfect
Alpine.js + Tailwind JS sprinkles + utility CSS Small (~15 KB) Optional ✅ Tailwind ✅ Perfect
React + Vite Full SPA, FastAPI = API Large (100+ KB) Yes ⚠️ Needs config ✅ Good (API only)
SvelteKit Modern SPA Medium (~30 KB) Yes ⚠️ Needs config ✅ Good (API only)
Vue 3 + Vite Progressive SPA Medium (~40 KB) Yes ⚠️ Needs config ✅ Good (API only)

✅ Recommendation: HTMX + Tailwind CSS

Winner: HTMX + Tailwind CSS

Why HTMX + Tailwind wins for this app

Strengths:

  • 🧱 Zero build step — No Node.js bundler, no package.json complexity. Add via CDN <script> tag in base.html. Exactly one changed file to get started.
  • 🎨 Tailwind = instant mobile-first — Every utility is mobile-first by default (sm:, md:, lg: prefixes). Replacing the current hand-rolled CSS eliminates all responsive-design debt from the current audit (@media queries = zero in the current stylesheet).
  • 📦 Jinja2 templates stay — FastAPI keeps its current server-rendered architecture. No API layer refactor needed. All existing route handlers work unchanged.
  • 🔄 HTMX replaces all fetch() calls — The current inline JS (doSync(), fetch PATCH /accounts/<id>/name, fetch POST /ledgers, etc.) can be replaced with declarative hx-post, hx-patch, hx-swap attributes. Less JS to maintain, easier to read.
  • 📱 Mobile-first by design — Tailwind's responsive prefixes (md:flex, sm:hidden) handle nav collapsing, table stacking, touch-target sizing natively.
  • 🔒 Local app, no JS framework risks — No React hydration bugs, no SSR/CSR mismatches, no bundle splitting. HTML stays as HTML.

Trade-offs / Weaknesses:

  • Complex real-time UI (charts, drag-and-drop) would require more effort than in React/Svelte
  • HTMX is less familiar than React for new contributors
  • Tailwind's utility-class HTML can look verbose; Prettier + a style guide mitigates this

Why others were ruled out:

Option Reason ruled out
Alpine.js + Tailwind Good, but adds a JS layer on top of HTMX with overlap. Better to pick one paradigm. If complexity grows, Alpine can be added later alongside HTMX.
React + Vite Major architecture change — FastAPI must become a pure JSON API, all templates rewritten, Node build pipeline added, large bundle. Overkill for a personal finance app with ~10 pages.
SvelteKit Similar overhead to React: full SPA rewrite, separate Node server for SSR or FastAPI API-only. Excellent DX but too big a shift for incremental migration.
Vue 3 + Vite Middle ground but still requires build pipeline and API refactor. Doesn't add value over HTMX for a hypermedia-centric app.
Migration Approach

Phase 1 (no-risk): Add Tailwind CDN + HTMX CDN to base.html. Begin replacing inline <style> blocks and scattered hex codes with Tailwind utilities. No functional changes.

Phase 2: Convert nav to responsive (hamburger on mobile). Convert cards, tables to Tailwind grid/flex. Eliminate all inline style= attributes.

Phase 3: Incrementally replace fetch() + innerHTML patterns with HTMX hx-* attributes + Jinja2 fragment endpoints. Start with simpler endpoints (settings save, ledger create).

Phase 4: Tailwind CSS CLI (optional) — swap CDN for a proper Tailwind build step once the migration is stable, to remove unused utilities.


📋 JOB 2: Interactive Element Catalog

Full catalog in VISUAL_QA.md — Interactive Element Catalog section.

Summary
Page Interactive elements Plaid-required
base.html (nav) 6 links No
dashboard.html 2 (Sync Now, Export Excel) 1 (Sync Now)
accounts.html 5 (connect, copy token, disconnect, rename, transactions toggle) 3
ledgers.html 13 (add, create, cancel, delete×2, add item, expand, period selector×5, rename×2) 0
settings.html 3 (currency select, timezone select, save) 0
profile.html 10 (notification, save, view ledgers, sync, export, connect, disconnect, reconnect, desc input, save desc) 4
login.html 5 (username, password, sign in, forgot, switch profile) 0
forgot/reset.html 5 (username, submit, token, new password, reset) 0
setup.html 8 (username, password, confirm, continue×2, radio×3, plaid btn, skip) 1 (Plaid Link)
link.html 2 (cancel, Plaid auto-open) 1 (Plaid Link)

🧪 JOB 3: Playwright Automated Test Suite

Test file: tests/ui_functional/test_ui_functional.py
Conftest: tests/ui_functional/conftest.py (overrides autouse DB-path fixture)

Results (2026-05-31)
62 passed, 2 warnings in 44.59s

All tests pass. No Plaid credentials needed.

Coverage:

  • All 5 protected pages × 3 viewports (390, 768, 1440) = 15 tests
  • Auth pages (login, forgot, reset) = 4 tests
  • Dashboard interactions = 6 tests
  • Accounts page interactions = 4 tests
  • Ledgers page interactions = 7 tests
  • Settings page interactions = 4 tests
  • Profile page interactions = 7 tests
  • Navigation routing + logout = 5 tests
  • Export Excel = 1 test
  • Responsive layout (header/footer/main) × 3 viewports = 9 tests

Sub-issues

See linked issues below.

Closes #285

Dominant language
Python
Stars
1
Forks
1
PR merge metrics
No merged PRs in 30d

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from Riddy21/Friday_Budgeting_Pro

All issues in Riddy21/Friday_Budgeting_Pro

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.