Home

Testing Strategy for The Sys. Blog

Testing Strategy for "The Sys." Blog

Context: Terminal-only development environment (SSH to EC2, no GUI). Need to verify frontend changes work correctly without breaking existing functionality.

Problem: How do we test web frontend changes when we can't view a browser during development?


Requirements

  1. Terminal-only execution - Must run via SSH, no GUI required
  2. Fast feedback - Quick smoke tests for rapid iteration
  3. Regression detection - Catch when changes break existing functionality
  4. Visual confidence - Some way to verify UI didn't break (even if delayed)
  5. Minimal dependencies - Keep it simple, avoid over-engineering

Considered Options

Option 1: Curl-Based Smoke Tests

What it is: Shell script using curl to make HTTP requests and validate responses with grep.

Pros:

Cons:

Example:

curl -s http://localhost:3000 | grep -q "The Sys" || echo "FAIL"

Verdict: ✅ Use as first line of defense


Option 2: Headless Browser Tests (Puppeteer/Playwright)

What it is: Node.js libraries that control a real browser (Chrome/Firefox) without GUI. Runs in terminal.

Pros:

Cons:

Example:

const page = await browser.newPage();
await page.goto('http://localhost:3000');
const title = await page.title();
assert(title === 'The Sys.');
await page.screenshot({ path: 'homepage.png' });

Verdict: ✅ Use as comprehensive validation before committing changes


Option 3: Visual Regression Testing (Percy/BackstopJS)

What it is: Tools that take screenshots, compare pixel-by-pixel differences between versions.

Pros:

Cons:

Example:

backstop test  # Compares current vs baseline

Verdict: ❌ Too heavy for this use case. Manual screenshot review is sufficient.


Option 4: Integration Tests with Jest + Puppeteer

What it is: Full test suite using Jest framework + Puppeteer for browser automation.

Pros:

Cons:

Example:

test('homepage loads', async () => {
  await page.goto('http://localhost:3000');
  expect(await page.title()).toBe('The Sys.');
});

Verdict: 🤔 Good for future if complexity grows. Start simpler for now.


Layered testing strategy:

Layer 1: Smoke Tests (Always Run)

Tool: Bash script with curl When: After every change, before anything else Runtime: ~5 seconds Purpose: Catch obvious breakage immediately

Tests:

Why:


Layer 2: Browser Tests (Before Committing)

Tool: Puppeteer (headless Chrome) When: Before committing changes or when making UI changes Runtime: ~15-30 seconds Purpose: Comprehensive validation including JavaScript and CSS

Tests:

Why:


Layer 3: Manual Review (As Needed)

Tool: Work Mac browser When: After deploying, or for significant UI changes Purpose: Human visual validation

Process:

  1. SSH to EC2, make changes, run tests
  2. If tests pass, access from work Mac browser
  3. Visually verify everything looks right
  4. If broken, revert and iterate

Why:


Implementation Plan

File Structure

/home/ubuntu/yap/
├── server.js
├── smoke-test.sh          # Layer 1: Fast curl tests
├── browser-test.js        # Layer 2: Puppeteer tests
├── package.json           # npm scripts for easy running
├── screenshots/           # Generated screenshots for review
└── design-doc.md          # This file

Scripts to Add

package.json:

{
  "scripts": {
    "test": "npm run test:smoke && npm run test:browser",
    "test:smoke": "./smoke-test.sh",
    "test:browser": "node browser-test.js"
  }
}

Usage:

# Quick check during development
npm run test:smoke

# Full validation before commit
npm test

# Just browser tests
npm run test:browser

Workflow

During Development:

# 1. Make changes
vim server.js

# 2. Restart server
sudo systemctl restart blog

# 3. Quick validation (5 sec)
npm run test:smoke

# 4. Keep iterating if smoke tests fail
# Repeat 1-3 until smoke tests pass

Before Committing:

# 1. Run full test suite
npm test

# 2. Review any screenshots generated
ls screenshots/

# 3. If tests pass, commit
git add .
git commit -m "Update styling"

After Deploying:

# 1. From work Mac, visit http://[EC2-IP]:3000
# 2. Visual review
# 3. If broken, SSH back in and revert

Why This Works for "The Sys."

  1. Terminal-only compatible - Everything runs via SSH
  2. Fast iteration - Smoke tests give instant feedback
  3. Confidence before commit - Browser tests catch real issues
  4. No unnecessary complexity - No S3, no CI/CD, no over-engineering
  5. Fits the philosophy - Simple, automatic, removes guesswork

Trade-offs We're Accepting

Not doing:

Why: These add complexity without proportional value for a personal blog with 7 markdown files.

Keep it simple. Make it automatic. Remove options.


Future Considerations

If the blog grows significantly:

For now: Two layers (smoke + browser) are sufficient.


Success Metrics

We'll know this is working if:

  1. Smoke tests run in < 5 seconds and catch obvious errors
  2. Browser tests run in < 30 seconds and provide confidence
  3. We catch regressions before they hit work Mac browser
  4. Testing doesn't slow down development iteration
  5. We actually run the tests (not too complex/annoying)

Last updated: October 2025

READ i