init project

This commit is contained in:
root
2026-06-25 19:06:59 -04:00
parent c5dfee6efb
commit 5d017f533a
349 changed files with 31330 additions and 0 deletions
@@ -0,0 +1,17 @@
ID,Area,Check,Method,Criterion,Status
A11Y-001,Page,One h1 and logical heading order,Automated + manual,WCAG 1.3.1,Required
A11Y-002,Keyboard,All interactive controls reachable and operable,Manual,WCAG 2.1.1,Required
A11Y-003,Focus,Visible focus and logical order,Manual,"WCAG 2.4.7, 2.4.11",Required
A11Y-004,Skip link,Moves focus/viewport to main content,Manual,WCAG 2.4.1,Required
A11Y-005,Drawer/dialog,"Containment, inert background, Escape, return focus",Manual + browser,"WCAG 2.4.3, 3.2.1",Required
A11Y-006,Forms,"Visible labels, programmatic names, instructions",Automated + SR,"WCAG 1.3.1, 3.3.2",Required
A11Y-007,Errors,"Summary, inline association, first invalid focus",SR + manual,"WCAG 3.3.1, 3.3.3",Required
A11Y-008,Status,Success/failure announced without focus theft,SR,WCAG 4.1.3,Required
A11Y-009,Contrast,"Text, UI, focus in both themes",Automated + manual,"WCAG 1.4.3, 1.4.11",Required
A11Y-010,Reflow,320px and 400% zoom,Manual,WCAG 1.4.10,Required
A11Y-011,Text spacing,User overrides do not clip,Bookmarklet/manual,WCAG 1.4.12,Required
A11Y-012,Motion,Reduced-motion honored,Manual,WCAG 2.3.3,Required
A11Y-013,Language,Page and language changes identified,DOM + SR,"WCAG 3.1.1, 3.1.2",Required
A11Y-014,Bidi,Mixed-direction values remain intelligible,Visual + SR,WCAG 1.3.2,Required
A11Y-015,Targets,Target spacing and size tested,Automated + manual,WCAG 2.5.8,Required
A11Y-016,Autofill,Correct autocomplete tokens,DOM + browser,WCAG 1.3.5,Required
1 ID Area Check Method Criterion Status
2 A11Y-001 Page One h1 and logical heading order Automated + manual WCAG 1.3.1 Required
3 A11Y-002 Keyboard All interactive controls reachable and operable Manual WCAG 2.1.1 Required
4 A11Y-003 Focus Visible focus and logical order Manual WCAG 2.4.7, 2.4.11 Required
5 A11Y-004 Skip link Moves focus/viewport to main content Manual WCAG 2.4.1 Required
6 A11Y-005 Drawer/dialog Containment, inert background, Escape, return focus Manual + browser WCAG 2.4.3, 3.2.1 Required
7 A11Y-006 Forms Visible labels, programmatic names, instructions Automated + SR WCAG 1.3.1, 3.3.2 Required
8 A11Y-007 Errors Summary, inline association, first invalid focus SR + manual WCAG 3.3.1, 3.3.3 Required
9 A11Y-008 Status Success/failure announced without focus theft SR WCAG 4.1.3 Required
10 A11Y-009 Contrast Text, UI, focus in both themes Automated + manual WCAG 1.4.3, 1.4.11 Required
11 A11Y-010 Reflow 320px and 400% zoom Manual WCAG 1.4.10 Required
12 A11Y-011 Text spacing User overrides do not clip Bookmarklet/manual WCAG 1.4.12 Required
13 A11Y-012 Motion Reduced-motion honored Manual WCAG 2.3.3 Required
14 A11Y-013 Language Page and language changes identified DOM + SR WCAG 3.1.1, 3.1.2 Required
15 A11Y-014 Bidi Mixed-direction values remain intelligible Visual + SR WCAG 1.3.2 Required
16 A11Y-015 Targets Target spacing and size tested Automated + manual WCAG 2.5.8 Required
17 A11Y-016 Autofill Correct autocomplete tokens DOM + browser WCAG 1.3.5 Required
@@ -0,0 +1,10 @@
Browser_or_AT,Version_policy,Platform,Coverage
Chrome desktop,Latest stable and previous major,"Windows 11, macOS","All functional, visual, performance smoke"
Edge desktop,Latest stable and previous major,Windows 11,All functional and visual smoke
Firefox desktop,Latest stable and previous major,"Windows 11, macOS","Functional, keyboard, layout, forced-colors where supported"
Safari desktop,Latest stable and previous major,macOS,"Functional, dialog, storage, typography, visual"
Safari iOS,Latest stable and previous major,Representative iPhone compact and large,"Navigation, dialogs, virtual keyboard, form, viewport"
Chrome Android,Latest stable and previous major,Representative Android phone,"Navigation, dialogs, virtual keyboard, form, viewport"
Assistive technology,NVDA + Firefox/Chrome current,Windows,Critical paths
Assistive technology,VoiceOver + Safari current,macOS/iOS,Critical paths
Assistive technology,TalkBack + Chrome current,Android,Critical paths
1 Browser_or_AT Version_policy Platform Coverage
2 Chrome desktop Latest stable and previous major Windows 11, macOS All functional, visual, performance smoke
3 Edge desktop Latest stable and previous major Windows 11 All functional and visual smoke
4 Firefox desktop Latest stable and previous major Windows 11, macOS Functional, keyboard, layout, forced-colors where supported
5 Safari desktop Latest stable and previous major macOS Functional, dialog, storage, typography, visual
6 Safari iOS Latest stable and previous major Representative iPhone compact and large Navigation, dialogs, virtual keyboard, form, viewport
7 Chrome Android Latest stable and previous major Representative Android phone Navigation, dialogs, virtual keyboard, form, viewport
8 Assistive technology NVDA + Firefox/Chrome current Windows Critical paths
9 Assistive technology VoiceOver + Safari current macOS/iOS Critical paths
10 Assistive technology TalkBack + Chrome current Android Critical paths
@@ -0,0 +1,28 @@
{
"version": "1.0",
"measurement": "75th percentile real-user data where available; otherwise repeatable lab median on defined mobile profile",
"core": {
"LCP_ms_max": 2500,
"INP_ms_max": 200,
"CLS_max": 0.1,
"TTFB_ms_max": 800
},
"transfer_gzip": {
"initial_javascript_kb_max": 180,
"initial_css_kb_max": 60,
"initial_html_kb_max": 100,
"hero_media_kb_max": 250,
"font_total_kb_max": 220
},
"requests": {
"initial_third_party_max": 2,
"initial_font_files_max": 2
},
"rules": [
"No marketing tag may block first paint.",
"Load analytics after consent and idle where possible.",
"Reserve media dimensions to prevent layout shift.",
"No autoplay video on initial load.",
"Test EN, FR, and AR because font and copy costs differ."
]
}
@@ -0,0 +1,7 @@
# Browser Acceptance Specification
Automated browser tests must cover the scenarios in `visual-regression-scenarios_v1.0.json` plus behavioral assertions from `QA_MATRIX_v1.0.csv`.
Use semantic locators first: role, accessible name, label, heading, and visible text. Add `data-testid` only where locale-independent state cannot be selected reliably. Never use generated class names as test contracts.
At minimum, assert server HTML attributes, locale switching with preserved hash, root-only detection, theme no-flash state before app hydration, cookie precedence, system live update, drawer focus loop and inert state, dialog focus return, invalid form focus, recoverable failure value retention, idempotent submit, tour progress, reduced motion, and prohibited PII absence from analytics calls.
+27
View File
@@ -0,0 +1,27 @@
ID,Area,Scenario,Variants,Method,Expected,Gate
QA-001,Routing,Each locale route renders server-correct lang/dir/canonical/hreflang,en/fr/ar,Automated HTML assertion,No hydration correction required,Release
QA-002,Localization,Key parity and scalar/array type parity,en/fr/ar,CI validator,"Zero missing, empty, or extra production keys",Release
QA-003,Localization,Translation overflow,320/390/768/1024/1440; all locales,Visual + manual,"No clipping, ellipsis, fixed-height collision, or horizontal page scroll",Release
QA-004,RTL,Full homepage direction,ar light/dark,Visual + DOM,"Logical order, correct start alignment, selective mirroring",Release
QA-005,Mixed direction,"Plate, email, URL, phone, date, currency",ar,Screen reader + visual,Atomic value order remains correct,Release
QA-006,Theme,Preference persistence and cookie/storage disagreement,light/dark/system,Browser automation,Cookie wins; no flash; system stays system,Release
QA-007,Theme,OS theme changes while System selected,system,Browser automation,Resolved theme updates without changing preference,Release
QA-008,Navigation,Desktop header collision and keyboard use,1120/1280/1440; all locales,Visual + keyboard,No overlap; visible focus; logical order,Release
QA-009,Navigation,Drawer open/close containment,390/1024; ltr/rtl,Keyboard + SR,"Focus trapped, background inert, Escape and focus return work",Release
QA-010,Hero,Primary demo and tour actions,all locales/themes,Browser,Correct dialogs open; analytics source accurate,Release
QA-011,Demo form,Empty/invalid submission,all locales,Browser + SR,Summary announced; first invalid focused; inline errors associated,Release
QA-012,Demo form,Recoverable server failure,all locales,Integration,Values preserved; retry possible; persistent error,Release
QA-013,Demo form,Duplicate click/network retry,all locales,Integration,Single lead due to disabled submit and idempotency,Release
QA-014,Demo form,Success,all locales,Integration,Accurate localized confirmation; no PII in analytics,Release
QA-015,Tour,Four-step keyboard flow,all locales,Browser + SR,Progress announced; back/next/finish correct; focus moves,Release
QA-016,FAQ,Toggle by keyboard and screen reader,all locales,Manual + browser,Summary semantics and state announced,Release
QA-017,Accessibility,200% zoom and 400% reflow,320-equivalent; all locales,Manual,No two-dimensional scrolling except data regions,Release
QA-018,Accessibility,Forced colors,Windows,Manual,"Controls, focus, boundaries, status remain perceivable",Release
QA-019,Accessibility,Reduced motion,all,Browser + manual,No smooth scrolling or essential animation,Release
QA-020,Accessibility,Touch target size,compact,Automated + manual,44x44 preferred; WCAG minimum not violated,Release
QA-021,Evidence,Claims and assets,production content,Content audit,Every claim has approval or is suppressed,Release
QA-022,SEO,Metadata and language alternates,indexable routes,Automated,Unique localized metadata; reciprocal alternates; self-canonical,Release
QA-023,Performance,Budgets,mobile + desktop; each locale,Lighthouse/WebPageTest/RUM,All budgets met or approved exception,Release
QA-024,Security,CSP and bootstrap,production,Header inspection,Nonce/hash accepted; no unsafe inline expansion,Release
QA-025,Privacy,Consent and analytics gating,regions in scope,Integration/manual,No non-essential analytics before required consent,Release
QA-026,Visual regression,Named screen states,scenario manifest,Automated screenshots,No unapproved diffs above threshold,Release
1 ID Area Scenario Variants Method Expected Gate
2 QA-001 Routing Each locale route renders server-correct lang/dir/canonical/hreflang en/fr/ar Automated HTML assertion No hydration correction required Release
3 QA-002 Localization Key parity and scalar/array type parity en/fr/ar CI validator Zero missing, empty, or extra production keys Release
4 QA-003 Localization Translation overflow 320/390/768/1024/1440; all locales Visual + manual No clipping, ellipsis, fixed-height collision, or horizontal page scroll Release
5 QA-004 RTL Full homepage direction ar light/dark Visual + DOM Logical order, correct start alignment, selective mirroring Release
6 QA-005 Mixed direction Plate, email, URL, phone, date, currency ar Screen reader + visual Atomic value order remains correct Release
7 QA-006 Theme Preference persistence and cookie/storage disagreement light/dark/system Browser automation Cookie wins; no flash; system stays system Release
8 QA-007 Theme OS theme changes while System selected system Browser automation Resolved theme updates without changing preference Release
9 QA-008 Navigation Desktop header collision and keyboard use 1120/1280/1440; all locales Visual + keyboard No overlap; visible focus; logical order Release
10 QA-009 Navigation Drawer open/close containment 390/1024; ltr/rtl Keyboard + SR Focus trapped, background inert, Escape and focus return work Release
11 QA-010 Hero Primary demo and tour actions all locales/themes Browser Correct dialogs open; analytics source accurate Release
12 QA-011 Demo form Empty/invalid submission all locales Browser + SR Summary announced; first invalid focused; inline errors associated Release
13 QA-012 Demo form Recoverable server failure all locales Integration Values preserved; retry possible; persistent error Release
14 QA-013 Demo form Duplicate click/network retry all locales Integration Single lead due to disabled submit and idempotency Release
15 QA-014 Demo form Success all locales Integration Accurate localized confirmation; no PII in analytics Release
16 QA-015 Tour Four-step keyboard flow all locales Browser + SR Progress announced; back/next/finish correct; focus moves Release
17 QA-016 FAQ Toggle by keyboard and screen reader all locales Manual + browser Summary semantics and state announced Release
18 QA-017 Accessibility 200% zoom and 400% reflow 320-equivalent; all locales Manual No two-dimensional scrolling except data regions Release
19 QA-018 Accessibility Forced colors Windows Manual Controls, focus, boundaries, status remain perceivable Release
20 QA-019 Accessibility Reduced motion all Browser + manual No smooth scrolling or essential animation Release
21 QA-020 Accessibility Touch target size compact Automated + manual 44x44 preferred; WCAG minimum not violated Release
22 QA-021 Evidence Claims and assets production content Content audit Every claim has approval or is suppressed Release
23 QA-022 SEO Metadata and language alternates indexable routes Automated Unique localized metadata; reciprocal alternates; self-canonical Release
24 QA-023 Performance Budgets mobile + desktop; each locale Lighthouse/WebPageTest/RUM All budgets met or approved exception Release
25 QA-024 Security CSP and bootstrap production Header inspection Nonce/hash accepted; no unsafe inline expansion Release
26 QA-025 Privacy Consent and analytics gating regions in scope Integration/manual No non-essential analytics before required consent Release
27 QA-026 Visual regression Named screen states scenario manifest Automated screenshots No unapproved diffs above threshold Release
+14
View File
@@ -0,0 +1,14 @@
Test_ID,Element,Justification
site-header,Header root,Only for visual anchor
mobile-drawer,Drawer root,State assertion
locale-selector,Locale control,State assertion
theme-selector,Theme control,State assertion
hero-demo,Hero demo CTA,Source attribution
hero-tour,Hero tour CTA,Source attribution
demo-dialog,Demo dialog,Overlay state
demo-form,Demo form,Submission state
demo-alert,Form summary,Error assertion
tour-dialog,Tour dialog,Overlay state
tour-step,Current tour step,Progress assertion
pricing-demo,Pricing CTA,Source attribution
final-demo,Final CTA,Source attribution
1 Test_ID Element Justification
2 site-header Header root Only for visual anchor
3 mobile-drawer Drawer root State assertion
4 locale-selector Locale control State assertion
5 theme-selector Theme control State assertion
6 hero-demo Hero demo CTA Source attribution
7 hero-tour Hero tour CTA Source attribution
8 demo-dialog Demo dialog Overlay state
9 demo-form Demo form Submission state
10 demo-alert Form summary Error assertion
11 tour-dialog Tour dialog Overlay state
12 tour-step Current tour step Progress assertion
13 pricing-demo Pricing CTA Source attribution
14 final-demo Final CTA Source attribution
@@ -0,0 +1,24 @@
import fs from 'node:fs';
import path from 'node:path';
import crypto from 'node:crypto';
const root = path.resolve(path.dirname(new URL(import.meta.url).pathname), '..');
const required = [
'09_DEVELOPER_HANDOFF_v1.0.md','DECISION_LOG_v9.0.md','DEFINITION_OF_DONE_v1.0.md','OPEN_ISSUE_REGISTER_v1.0.csv',
'tokens/design-tokens_v1.0.json','tokens/semantic-tokens_v1.0.css','components/COMPONENT_CONTRACTS_v1.0.md',
'localization/ROUTE_MANIFEST_v1.0.json','localization/locales/en/homepage.json','localization/locales/fr/homepage.json','localization/locales/ar/homepage.json',
'interaction/theme-bootstrap_v1.0.js','qa/QA_MATRIX_v1.0.csv','qa/ACCESSIBILITY_CHECKLIST_v1.0.csv','qa/PERFORMANCE_BUDGETS_v1.0.json'
];
const errors=[]; let checks=0;
for (const file of required){ checks++; if(!fs.existsSync(path.join(root,file))) errors.push(`Missing ${file}`); }
const readJson=(f)=>JSON.parse(fs.readFileSync(path.join(root,f),'utf8'));
for (const file of ['tokens/design-tokens_v1.0.json','localization/ROUTE_MANIFEST_v1.0.json','qa/PERFORMANCE_BUDGETS_v1.0.json','qa/visual-regression-scenarios_v1.0.json']) { try{readJson(file);checks++;}catch(e){errors.push(`${file}: ${e.message}`);} }
function shape(value){ if(Array.isArray(value)) return value.map(shape); if(value && typeof value==='object') return Object.fromEntries(Object.keys(value).sort().map(k=>[k,shape(value[k])])); return typeof value; }
const locales=['en','fr','ar'].map(l=>readJson(`localization/locales/${l}/homepage.json`));
const base=JSON.stringify(shape(locales[0]));
for (let i=1;i<locales.length;i++){ checks++; if(JSON.stringify(shape(locales[i]))!==base) errors.push(`Locale shape mismatch: ${['en','fr','ar'][i]}`); }
const routes=readJson('localization/ROUTE_MANIFEST_v1.0.json');
for (const route of routes.routes){ for (const locale of routes.locales){ checks++; if(!(locale in route.slugs)) errors.push(`Route ${route.id} missing ${locale}`); } }
const issueCsv=fs.readFileSync(path.join(root,'OPEN_ISSUE_REGISTER_v1.0.csv'),'utf8'); checks++; if(/,(Critical|High),[^\n]*,,/.test(issueCsv)) errors.push('Critical/High issue missing ownership data');
const css=fs.readFileSync(path.join(root,'tokens/semantic-tokens_v1.0.css'),'utf8'); checks++; if(!css.includes('--color-action-conversion')) errors.push('Conversion semantic token missing');
if(errors.length){ console.error(JSON.stringify({status:'FAILED',checks,errors},null,2)); process.exit(1); }
console.log(JSON.stringify({status:'PASSED',checks,files:fs.readdirSync(root).length},null,2));
@@ -0,0 +1,86 @@
{
"version": "1.0",
"pixelDiffThreshold": 0.01,
"scenarios": [
{
"id": "VR-001",
"route": "/en",
"viewport": [
1440,
1000
],
"theme": "light",
"state": "homepage-top"
},
{
"id": "VR-002",
"route": "/fr",
"viewport": [
1024,
900
],
"theme": "dark",
"state": "homepage-top"
},
{
"id": "VR-003",
"route": "/ar",
"viewport": [
390,
844
],
"theme": "light",
"state": "homepage-top"
},
{
"id": "VR-004",
"route": "/ar",
"viewport": [
390,
844
],
"theme": "dark",
"state": "drawer-open"
},
{
"id": "VR-005",
"route": "/en",
"viewport": [
390,
844
],
"theme": "light",
"state": "demo-invalid"
},
{
"id": "VR-006",
"route": "/fr",
"viewport": [
768,
1024
],
"theme": "dark",
"state": "tour-step-3"
},
{
"id": "VR-007",
"route": "/ar",
"viewport": [
320,
800
],
"theme": "dark",
"state": "reflow-gate"
},
{
"id": "VR-008",
"route": "/en",
"viewport": [
1440,
1000
],
"theme": "dark",
"state": "pricing-and-final-cta"
}
]
}