Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
95 commits
Select commit Hold shift + click to select a range
930f1e5
Refactor homepage to use new baseTest pattern
webstackdev Oct 23, 2025
efa9f37
Refactor all tests to use new baseTest pattern
webstackdev Oct 23, 2025
b4cb3c7
Update state initialization and error handling in bootstrap
webstackdev Oct 24, 2025
0fc7c47
Improve error handling in Head component stores feature
webstackdev Oct 24, 2025
4440178
Remove JSON.stringify in themes store to stop escaping quotes on name
webstackdev Oct 24, 2025
668ec97
Update Scripts state bootstrap to use window property for errors in e2e
webstackdev Oct 24, 2025
53698c5
Update dev error handlers to use window prop system for e2e notification
webstackdev Oct 24, 2025
13039c5
Refactor smoke e2e tests to use Page Object Model base class
webstackdev Oct 25, 2025
7ed6dab
Refactor pages in 02-pages to use new page object model
webstackdev Oct 25, 2025
93fdef2
Refactor pages in 04-components to use new page object model
webstackdev Oct 25, 2025
bc78b82
Add robots directive in head, JSON-LD Schema data
webstackdev Oct 25, 2025
e1d7fa0
Refactor 05-metadata tests to POM and remove obsolete tests from 04-comp
webstackdev Oct 25, 2025
3ab23f8
Move API endpoints from Vercel ./api folder to Astro SSR endpoints
webstackdev Oct 25, 2025
dcb11e5
Move social-cards Astro SSR API endpoint to folder and add tests
webstackdev Oct 25, 2025
357c335
Implement and troubleshoot e2e tests for API endpoints
webstackdev Oct 25, 2025
1e21de3
Implement e2e tests in 03-forms and 09-pwa with @wip still to do
webstackdev Oct 26, 2025
72902aa
Implement core-web-vitals e2e test with passing scores
webstackdev Oct 26, 2025
d93a413
Fix many failures in unit tests due to config changes, but still skipped
webstackdev Oct 26, 2025
52065a1
First pass at implementing accessibility e2e tests
webstackdev Oct 26, 2025
72b4445
Dependency patch versions upgrade
webstackdev Oct 26, 2025
c94e479
Deps upgrade - minor of Astro, major of Vercel adapter, major of Zod
webstackdev Oct 26, 2025
608d6df
Add axe-playwright, commit home page errs, notes on accessibility tests
webstackdev Oct 26, 2025
1103b53
ARIA Required Children on carousel
webstackdev Oct 26, 2025
7ade5d3
Normalize CSS theme variable names and implement single source of truth
webstackdev Oct 26, 2025
912d3c0
Convert rgba values in theme.css to hex values
webstackdev Oct 26, 2025
e5d659e
Respect theme colors in logo and wordmarks in header
webstackdev Oct 26, 2025
cc490e9
Change padding of header
webstackdev Oct 26, 2025
0187133
Spacing improvements to themepicker icon and boxes
webstackdev Oct 26, 2025
c8a6968
Fix color and animation of main-nav elements
webstackdev Oct 26, 2025
dbdca87
Fix script execution error on theme picker activation after navigation
webstackdev Oct 26, 2025
f2633d5
Fix animation error on nav menu items when element loses hover
webstackdev Oct 26, 2025
2d46452
Change page names for about and contact for breadcrumbs and title
webstackdev Oct 26, 2025
acf2301
Fix mobile nav, add event system to pause animations
webstackdev Oct 27, 2025
87e52c5
Add a demo article showcasing all MDX components
webstackdev Oct 27, 2025
ae76b4e
Style tweak to desktop nav
webstackdev Oct 27, 2025
935471c
Adjust breadcrumbs padding
webstackdev Oct 27, 2025
c121201
Fixes to mobile nav
webstackdev Oct 30, 2025
8d2a30e
Normalize company and contacta data into one file
webstackdev Oct 30, 2025
c99555e
Fix unit test errors
webstackdev Oct 30, 2025
4607238
Fixes to desktop footer
webstackdev Oct 30, 2025
0459469
Fixes to mobile footer
webstackdev Oct 30, 2025
82e0858
Fixes to desktop cookie consent modal
webstackdev Oct 31, 2025
b46bcc8
Fixes to mobile cookie consent
webstackdev Oct 31, 2025
3fd2e92
Update dependencies
webstackdev Oct 31, 2025
54d6404
Fix typescript errors from npm run check
webstackdev Oct 31, 2025
8d696db
Fix typescript errors, update GitHub Action and Husky pre-commit hook…
webstackdev Oct 31, 2025
31482bd
Refactor style theme variables to use Tailwind @theme inline
webstackdev Oct 31, 2025
b494267
Docs updates
webstackdev Oct 31, 2025
4a6cda5
Break Base and Markdown layout elements out into Layout component dir…
webstackdev Oct 31, 2025
e823d23
Move CSS styles from :root to Tailwind @theme
webstackdev Oct 31, 2025
f1740e2
Add stories component for internal use on styling reviews
webstackdev Oct 31, 2025
2b45c7c
Revert "Add stories component for internal use on styling reviews"
webstackdev Nov 1, 2025
3fc5530
Revert "Move CSS styles from :root to Tailwind @theme"
webstackdev Nov 1, 2025
30ca667
Fix gremlin breaking CSS compilation
webstackdev Nov 1, 2025
b1f29b5
Update mobile nav e2e tests with changes made to nav
webstackdev Nov 1, 2025
7e85d13
Update footer e2e tests with clearCookieConsent helper and implement …
webstackdev Nov 1, 2025
a29f819
Fix to mobile nav menu test to work on all browsers
webstackdev Nov 1, 2025
3865a15
Fix to manifest test, skip on Firefox since it triggers a download di…
webstackdev Nov 1, 2025
6e375dc
Update deps
webstackdev Nov 1, 2025
2af259e
Fix error in critical paths e2e that assumed desktop on mobile
webstackdev Nov 1, 2025
cd32920
Fix error in homepage page e2e CTA section test to separate desktop a…
webstackdev Nov 1, 2025
e8341d4
Fix error in dynamic-pages e2e tests related to Firefox handling of m…
webstackdev Nov 1, 2025
08a3777
Fix test logic for several GDPR e2e test scenarios
webstackdev Nov 1, 2025
5f79feb
Remove browser validation on newsletter consent form for consistent u…
webstackdev Nov 1, 2025
9ec5e40
Fix assorted implementation errors with keyboard navigation on site
webstackdev Nov 1, 2025
4407676
Refactor nanostores state to persist across page transitions using As…
webstackdev Nov 1, 2025
649cd35
Fixing collateral damage from recent e2e fixes
webstackdev Nov 1, 2025
073fa47
Refactor script loading system to pattern suggested by Astro for view…
webstackdev Nov 2, 2025
5724dad
Fix flaky selector causing intermittent errors on webkit
webstackdev Nov 2, 2025
ab60821
Broken tests: theme picker stays open across navigation
webstackdev Nov 2, 2025
8adcac8
Broken tests: theme picker stays persists theme color across navigation
webstackdev Nov 2, 2025
43d97d8
Fix e2e tests related to theme picker refactor
webstackdev Nov 2, 2025
299214a
Fix to cookieConsent unit test after store refactor
webstackdev Nov 2, 2025
42f7de6
Fix skipped unit test cases in cookie consent
webstackdev Nov 2, 2025
bf519b3
Remove unneeded skip test files
webstackdev Nov 2, 2025
a96a992
Delete skipked tests in js-cookie.spec.ts
webstackdev Nov 2, 2025
f96aeec
Update functions signature for vi mock
webstackdev Nov 2, 2025
66fb11a
Fix noisy console output in test environment for Mastodon handler
webstackdev Nov 2, 2025
d69c35a
Improve mock event listener in Forms/Download client spec
webstackdev Nov 2, 2025
5a264b6
Remove debug logging from Carousel component
webstackdev Nov 2, 2025
41f433f
Mock logger in Forms/Download component
webstackdev Nov 2, 2025
7af872f
Migrate to ClientRouter from deprecated ViewTransitions component
webstackdev Nov 2, 2025
64dda0c
Mock console for Favicon build
webstackdev Nov 2, 2025
8e49677
Remove debug logging from contact API implementation
webstackdev Nov 2, 2025
de28605
Add mock console to newsletter component tests
webstackdev Nov 2, 2025
7cf880d
Add mock console to downloads api test
webstackdev Nov 2, 2025
7966749
Remove debug messages from Testimonials carousel
webstackdev Nov 2, 2025
30be768
Fix mock in Social Embed
webstackdev Nov 2, 2025
5a3b7c7
Remove debug logging from the scripts loader
webstackdev Nov 2, 2025
744d0b9
Remove debug logging from scripts loader
webstackdev Nov 2, 2025
bdec8d1
Remove debug logging from cookies consent test
webstackdev Nov 2, 2025
dc63e88
Implement @wip cookie consent e2e tests
webstackdev Nov 2, 2025
8458847
Fix test case in testimonials component to account for remocking logging
webstackdev Nov 2, 2025
f1698ca
Implement skipped testimonials component e2e tests
webstackdev Nov 2, 2025
b58a8ea
@wip theme picker work
webstackdev Nov 3, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/instructions/general.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ applyTo: "**"
- JavaScript loading warnings from happy-dom are silenced in vitest.setup.ts for clean test output.
- A working example test using the Container API is available at /home/kevin/Repos/Webstack Builders/Corporate Website/astro.webstackbuilders.com/src/components/Test/container.spec.ts
- **NEVER hard-code content slugs in e2e tests** (e.g., `/articles/typescript-best-practices`, `/services/web-development`). Content can be deleted or renamed. Always dynamically fetch the first available item from listing pages (articles, services, case-studies, etc.) and navigate to it. This prevents test breakage when content changes.
- **Playwright E2E Tests**: Set `DEBUG=1` environment variable to prevent the dev server from being launched by the Playwright test runner. This is useful when you want to run tests against an already running dev server.
- **Playwright E2E Tests**: ALWAYS run with `DEBUG=1` environment variable (e.g., `DEBUG=1 npx playwright test`). This prevents the Playwright test runner from launching its own dev server. The user maintains a running dev server for development.
- **NEVER run the full e2e test suite** unless explicitly requested by the user. The full suite is very resource intensive and takes over 10 minutes to run. Only run specific e2e test files when verification is needed (e.g., `DEBUG=1 npx playwright test test/e2e/specific-file.spec.ts`).
- **NEVER start a dev server yourself**. The user runs their own dev server for development. When you need a dev server running, notify the user instead of starting one.

# Personality
- Do not apologize
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ name: CI - Build & Test

on:
push:
branches: [main]
pull_request:
branches: [main]

Expand All @@ -25,6 +24,9 @@ jobs:
- name: Install dependencies
run: npm ci

- name: Run TypeScript check
run: npm run check

- name: Run lint
run: npm run lint

Expand Down
31 changes: 31 additions & 0 deletions .github/workflows/type-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Fast code quality checks (TypeScript + Linting)
name: Code Quality Check

on:
push:
pull_request:
branches: [main]

jobs:
quality-check:
name: Code Quality Check
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "22.x"
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Run TypeScript check
run: npm run check

- name: Run linting
run: npm run lint
Comment on lines +11 to +31

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}
20 changes: 19 additions & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,7 +1,25 @@
#!/bin/sh

# Load nvm if available and use appropriate node version
if [ -f "$HOME/.nvm/nvm.sh" ]; then
. "$HOME/.nvm/nvm.sh"
# Try different nvm use strategies in order of preference
if nvm use 2>/dev/null; then
echo "Using current nvm node version"
elif nvm use node 2>/dev/null; then
echo "Using latest nvm node version"
elif nvm use --lts 2>/dev/null; then
echo "Using LTS node version"
else
echo "Using system node version"
fi
fi

# Run TypeScript check (fast feedback on type errors)
npm run check

# Run unit tests (fast feedback)
nvm use default && npm run test:unit
npm run test:unit

# Verify branch naming convention
.husky/scripts/check-branch-name.sh
Expand Down
4 changes: 4 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"Flink",
"FNAME",
"fosstodon",
"glidejs",
"GSAP",
"hocho",
"Hudi",
Expand Down Expand Up @@ -67,9 +68,12 @@
"Qualys",
"repost",
"reposts",
"RGAA",
"Ryuk",
"samp",
"SCORM",
"shiki",
"shikijs",
"shipit",
"SIEM",
"signup",
Expand Down
53 changes: 1 addition & 52 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,58 +143,7 @@ To add a new theme (e.g., a holiday theme), follow these steps:

#### 1. Add CSS Variables in `src/styles/themes.css`

Add a new CSS rule with your theme's custom properties:

```css
/* Holiday Theme Example */
[data-theme="holiday"] {
/* Background Colors */
--color-bg: #0f172a;
--color-bg-offset: #1e293b;

/* Text Colors */
--color-text: #f1f5f9;
--color-text-offset: #cbd5e1;

/* Primary Brand Colors */
--color-primary: #dc2626;
--color-primary-offset: #991b1b;
--color-primary-bg: #7f1d1d;
--color-primary-bg-hover: #991b1b;
--color-primary-hover: #b91c1c;

/* Secondary Colors */
--color-secondary: #16a34a;
--color-secondary-offset: #15803d;
--color-secondary-bg: #052e16;

/* Status Colors */
--color-success: #16a34a;
--color-success-offset: #22c55e;
--color-success-bg: #052e16;

--color-info: #0891b2;
--color-info-bg: #164e63;

--color-warning: #a16207;
--color-warning-offset: #ca8a04;
--color-warning-bg: #451a03;

--color-danger: #dc2626;
--color-danger-bg: #7f1d1d;

/* Special Colors */
--color-twitter: #1da1f2;
--color-modal-background: #0f172a;

/* Accent Colors */
--color-accent: #fbbf24;
--color-accent-bg: #451a03;

/* Syntax Highlighting */
--shiki-theme: 'github-dark';
}
```
Add a new CSS rule with the theme's custom colors following the pattern of existing themes in this file.

#### 2. Register Theme in `src/lib/themes.ts`

Expand Down
127 changes: 127 additions & 0 deletions THEME_SYSTEM_WIP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# Theme System - Work in Progress

## Current Status

### What's Working
- ✅ Theme picker tests: 9/10 @ready (63 tests passing across 7 browsers)
- ✅ Manual theme selection and persistence works correctly
- ✅ Theme switching via theme picker UI works
- ✅ View Transitions correctly maintain theme across page navigations
- ✅ CSS architecture refactored: `@theme inline` uses `var()` references instead of hard-coded values

### What's Broken
- ❌ **System preference (prefers-color-scheme) not respected on first visit in real browser**
- Test passes but real usage fails
- Opening site in new incognito window with dark mode preference shows light theme
- Google.com correctly shows dark, but our site doesn't

- ❌ **Theme picker buttons should show their own theme's colors**
- Dark theme button should use `--dark-color-*` variables
- Default theme button should use `--light-color-*` variables
- Currently all buttons use light theme colors (partially fixed but needs completion)

## Root Cause Analysis

### System Preference Issue

The problem is a **race condition** between:
1. HEAD inline script (synchronous) - correctly sets `data-theme="dark"` based on `prefers-color-scheme`
2. `persistentAtom` restore (asynchronous) - overwrites theme back to 'default'

**Sequence of events:**
```
1. HEAD script runs → checks localStorage (empty) → checks prefersDark=true → sets data-theme="dark" ✓
2. persistentAtom initializes with default value 'default'
3. Our init code runs with setTimeout(100ms)
4. persistentAtom's restore() completes (async) → fires .listen() → overwrites to 'default' ✗
```

**Current fix attempt:**
- Using `isInitialized` flag to prevent `.listen()` from applying themes until init completes
- Using `setTimeout(100ms)` to delay init until after `persistentAtom.restore()` completes
- **Problem:** The timing is unreliable - 100ms might not be enough on slower devices

**Test vs Reality:**
- Playwright test passes because it's using `emulateMedia({ colorScheme: 'dark' })`
- Real browser behavior is different - the race condition manifests differently
- Test needs to be improved to catch this real-world bug

## Files Modified

### Theme Initialization
- `src/components/Scripts/state/store/themes.ts` (lines 127-180)
- Changed from `.subscribe()` to `.listen()` to avoid immediate firing
- Added `isInitialized` flag to gate theme applications
- Added `setTimeout(100)` to wait for `persistentAtom.restore()`
- **HAS DEBUG LOGGING** - needs to be removed before commit

### Theme Picker UI
- `src/components/ThemePicker/Themes.astro` (lines 97-120)
- **NOT YET FIXED** - still needs to map theme.id to color prefix
- Should use `--${colorPrefix}-color-*` variables per button

### HEAD Script
- `src/components/Head/index.astro` (lines 56-63)
- Correctly checks `prefers-color-scheme` and sets `data-theme`
- Logic: stored theme (if not 'default') > system preference > 'default'

### CSS Architecture
- `src/styles/themes.css`
- ✅ Lines 65-105: `@theme inline` refactored to use `var()` references
- ✅ All theme-specific colors defined at `:root` level
- Has `--light-color-*`, `--dark-color-*`, and base `--color-*` variables

## Next Steps

### High Priority
1. **Fix system preference detection**
- Option A: Find more reliable way to detect when `persistentAtom.restore()` completes
- Option B: Use `MutationObserver` to watch for theme changes from restore
- Option C: Initialize theme BEFORE importing `persistentAtom`
- Option D: Use regular `atom` for store, manually sync to localStorage after restore completes
- Option E: Don't rely on setTimeout - use `requestIdleCallback` or similar

2. **Fix theme picker button colors**
- Complete the Themes.astro fix to show each theme's own colors
- Map `theme.id` to color variable prefix: 'default' → 'light', 'dark' → 'dark'
- Update color swatches to use theme-specific variables

3. **Remove debug logging**
- `src/components/Scripts/state/store/themes.ts` has console.log statements
- Clean these up before final commit

### Test Improvements
4. **Make test match real browser behavior**
- Current test uses `emulateMedia()` which might not trigger same race condition
- Consider testing with actual localStorage clearing and page reload
- Add test that validates theme immediately on page load (before JS runs)

## Technical Constraints

- **MUST use `persistentAtom`** - required for View Transitions to maintain theme across navigations
- **CANNOT use regular `atom`** - will lose persistence across page navigations
- HEAD script must run synchronously to prevent FOUC (Flash of Unstyled Content)
- Theme must be applied before page renders (critical for UX)

## Code Locations

- Theme store: `src/components/Scripts/state/store/themes.ts`
- Theme picker UI: `src/components/ThemePicker/Themes.astro`
- Theme picker element: `src/components/ThemePicker/theme-picker-element.ts`
- HEAD script: `src/components/Head/index.astro` (lines 56-63)
- CSS themes: `src/styles/themes.css`
- E2E tests: `test/e2e/specs/04-components/theme-picker.spec.ts` (line 134 is failing test)

## Questions to Answer

1. When exactly does `persistentAtom.restore()` complete?
2. Is there an event or promise we can wait for?
3. Should we implement our own localStorage persistence instead of using `persistentAtom`?
4. Can we leverage the `@media (prefers-color-scheme: dark)` CSS to avoid needing JS for system preference?

## Useful Context

- The `@media (prefers-color-scheme: dark)` CSS rule at lines 337-373 in themes.css correctly applies dark theme
- This CSS works WITHOUT JavaScript
- The issue is the JS is overriding this CSS by setting `data-theme="default"`
- Maybe we should NOT set `data-theme` at all when using system preference?
78 changes: 70 additions & 8 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,75 @@
# TODO

From the error output, the article page has:

<h1 id="article-title"> - the actual article title (correct)
<h1 id="create-custom-font-sets-use-font-forge"> - from markdown content (wrong!)
<h1>No islands detected.</h1> - from some debug/dev tool
<h1>Audit</h1> - from some debug/dev tool
<h1>No accessibility or performance issues detected.</h1> - from debug/dev tool
<h1>Settings</h1> - from debug/dev tool
Files with Skipped Tests:

social-shares.spec.ts - 12 @wip
gdpr-consent.spec.ts - 10 @wip

Blocked Categories (44 tests):

Visual regression testing (18) - Needs Percy/Chromatic
PWA functionality (12) - Service workers not implemented
Lighthouse audits (6) - Integration pending
Newsletter double opt-in (6) - Email testing infrastructure
Axe accessibility (2) - axe-core integration

\[color:var\(--color-(.*?)\)\]

## Axe tags

cat.aria: Rules related to Accessible Rich Internet Applications (ARIA) attributes and roles.
cat.color: Rules related to color contrast and meaning conveyed by color.
cat.controls: Rules for interactive controls, such as form elements and links.
cat.forms: Rules specifically for forms, form fields, and their labels.
cat.keyboard: Rules related to keyboard operability.
cat.links: Rules for links, including their names and destinations.
cat.name-role-value: Rules that check if an element has a name, role, and value that can be correctly interpreted by assistive technologies.
cat.semantics: Rules related to the semantic structure of a document, such as headings and landmarks.
cat.sensory-and-visual-cues: Rules that deal with information conveyed by sensory or visual characteristics.
cat.structure: Rules related to the document's overall structure, like the proper nesting of elements.
cat.tables: Rules for data tables, including headers and associations.
cat.text-alternatives: Rules for ensuring that text alternatives are provided for non-text content, such as images.

## Social Media Preview Cards

Looking at the social-card endpoint implementation, it's designed to work with third-party screenshot services, not the social networks themselves.

Here's how it works:

The Two Formats
HTML format (format=html or default): Returns a full HTML page with inline CSS styled as a 1200x630px card - the standard Open Graph image dimensions.

OG format (format=og): Returns JSON with Open Graph meta tags, where the og:image URL points back to the HTML version of the card.

How Social Networks Actually Work
Social networks like Twitter, Facebook, LinkedIn, etc. don't screenshot HTML pages. They expect:

- Direct image URLs (PNG, JPEG, etc.)
- Standard dimensions (1200x630px for most platforms)

The Intended Workflow

This endpoint is designed to integrate with screenshot services like:

- Puppeteer or Playwright - Run your own screenshot service
- Vercel OG Image Generation - Vercel's built-in service
- Cloudinary - Can fetch and screenshot URLs
- ScreenshotOne or ApiFlash - Dedicated screenshot APIs
- Satori - Convert HTML/CSS to SVG/PNG

Current Limitation

As implemented, this endpoint would need an additional step to be useful for social sharing:

Your endpoint → Screenshot service → Image file → Social networks

Better Approaches

For a production Astro site, you'd typically:

- Use @vercel/og or Satori to generate actual images server-side
- Pre-generate images at build time for static content
- Use a screenshot service that can be called from your endpoint to return actual images

## @TODO: Use Confetti on CTA forms

Expand Down
Loading
Loading