Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
138 changes: 121 additions & 17 deletions apps/landing-page/__tests__/__helpers__/mock-translations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,37 @@
*/
export const mockTranslations: Record<string, Record<string, string>> = {
hero: {
title: 'Multi-AI Rules for Consistent Coding',
subtitle: 'One ruleset for Cursor, Claude Code, Codex, Antigravity, Q, and Kiro.',
title: 'Prove Your AI Coding Is Actually Improving',
subtitle: 'One command. 9 AI tools. Measurable impact on every session.',
cta: 'Get Started',
github: 'Star on GitHub',
terminalTitle: '~/your-project',
terminalCmd: 'npx codingbuddy init',
terminalInstalling: 'Installing codingbuddy-rules...',
terminalRulesSynced: 'Rules synced to 6 AI tools',
terminalAgents: '35 specialist agents activated',
terminalRulesSynced: 'Rules synced to 9 AI tools',
terminalAgents: '37 specialist agents activated',
terminalWorkflow: 'PLAN → ACT → EVAL workflow ready',
terminalSkills: '50 built-in skills loaded',
terminalCursorrules: '.cursorrules',
terminalClaudeMd: 'CLAUDE.md',
terminalCodex: '.codex/',
terminalAntigravity: '.antigravity/',
terminalQ: '.q/',
terminalKiro: '.kiro/',
terminalWindsurf: '.windsurfrules',
terminalAider: '.aider.conf.yml',
terminalOpenCode: '.opencode/',
terminalReady: 'Ready! One source, all tools.',
},
socialProof: {
agents: '37 Agents',
tools: '9 AI Tools',
skills: '50 Skills',
checklists: '9 Checklists',
languages: '8 Languages',
},
agents: {
title: '35 Specialist Agents',
title: '37 Specialist Agents',
subtitle: 'Focused expertise for every aspect of development',
filter: 'Filter by category',
allCategories: 'All',
Expand All @@ -36,6 +47,14 @@ export const mockTranslations: Record<string, Record<string, string>> = {
'categories.Security': 'Security',
'categories.UX': 'UX',
count: '{count} agents',
stacks: 'Agent Stacks',
stacksSubtitle: 'Pre-built teams for common workflows',
fullStack: 'Full-Stack',
apiDev: 'API Development',
dataPipeline: 'Data Pipeline',
frontendPolish: 'Frontend Polish',
mlInfra: 'ML Infrastructure',
securityAudit: 'Security Audit',
},
quickStart: {
title: 'Quick Start',
Expand All @@ -48,6 +67,9 @@ export const mockTranslations: Record<string, Record<string, string>> = {
step3Desc: 'Use PLAN, ACT, EVAL modes with specialist agents',
copy: 'Copy',
copied: 'Copied!',
tab_claude: 'Claude Code',
tab_cursor: 'Cursor',
tab_codex: 'Codex',
},
header: {
'nav.features': 'Features',
Expand Down Expand Up @@ -77,24 +99,29 @@ export const mockTranslations: Record<string, Record<string, string>> = {
decline: 'Decline',
},
metadata: {
title: 'Codingbuddy - Multi-AI Rules for Consistent Coding',
description: 'One ruleset for Cursor, Claude Code, Codex, Antigravity, Q, and Kiro.',
title: 'Codingbuddy - Prove Your AI Coding Is Actually Improving',
description:
'One command for 9 AI tools. 37 specialist agents. Measurable impact on every session.',
},
beforeAfter: {
title: 'The Problem & Solution',
beforeLabel: 'Before',
afterLabel: 'After',
beforeFiles: '6 config files. Always out of sync.',
beforeFiles: '9 config files. Always out of sync.',
afterFiles: 'Single source. Auto-synced to all tools.',
cursorrules: '.cursorrules',
claudeMd: 'CLAUDE.md',
codexRules: '.codex/instructions.md',
antigravityRules: '.antigravity/rules.md',
qRules: '.q/rules.md',
kiroRules: '.kiro/rules.md',
windsurfRules: '.windsurfrules',
aiderRules: '.aider.conf.yml',
opencodeRules: '.opencode/rules.md',
singleSource: 'codingbuddy-rules/.ai-rules/',
autoSynced: 'Auto-synced',
alwaysCurrent: 'Always current',
impactTracked: 'Impact tracked',
},
supportedTools: {
title: 'Works with your favorite AI tools',
Expand All @@ -105,6 +132,9 @@ export const mockTranslations: Record<string, Record<string, string>> = {
antigravity: 'Antigravity',
amazonQ: 'Amazon Q',
kiro: 'Kiro',
windsurf: 'Windsurf',
aider: 'Aider',
opencode: 'OpenCode',
},
tuiDashboard: {
title: 'Real-Time Agent Dashboard',
Expand All @@ -126,26 +156,100 @@ export const mockTranslations: Record<string, Record<string, string>> = {
features: {
title: 'What You Get',
universalRulesTitle: 'Universal Rules',
universalRulesDesc: 'One source of truth automatically applied to all 6 AI coding tools.',
agentsTitle: '35 AI Agents',
universalRulesDesc: 'One source of truth automatically applied to all 9 AI coding tools.',
agentsTitle: '37 Specialist Agents',
agentsDesc:
'Specialist agents for architecture, security, testing, performance, and accessibility.',
'Domain experts for architecture, security, testing, performance, and accessibility.',
workflowTitle: 'Structured Workflow',
workflowDesc: 'PLAN → ACT → EVAL cycle ensures consistent quality across all development.',
qualityTitle: 'Quality Built-in',
qualityDesc: 'TDD, SOLID principles, and 90%+ test coverage enforced as standard practice.',
mcpTitle: 'MCP Protocol',
mcpDesc: 'Standard Model Context Protocol for seamless AI tool integration.',
impactTitle: 'Session Impact Reports',
impactDesc:
'Measurable proof that AI coding is improving — issues prevented, agents dispatched, rules enforced.',
selfEvolvingTitle: 'Self-Evolving Rules',
selfEvolvingDesc:
'Rules that learn from repeated failure patterns and suggest improvements automatically.',
skillsTitle: '50 Built-in Skills',
skillsDesc: 'Reusable workflows for TDD, shipping, code review, debugging, and more.',
zeroConfigTitle: 'Zero Config',
zeroConfigDesc: 'One command to install. Works out of the box with all supported tools.',
},
workflowDemo: {
title: 'Your AI Coding Workflow, Supercharged',
subtitle: 'Four modes that take AI-assisted development from chaos to production-ready.',
planTitle: 'PLAN',
planDesc:
'Question-first planning with intelligent clarification. Specialists recommend architecture before a single line of code.',
planDetail1: 'Clarification gate catches ambiguity',
planDetail2: 'Specialists recommend architecture',
planDetail3: 'Permission forecast before execution',
actTitle: 'ACT',
actDesc:
'Execute with TDD discipline. Real-time rule enforcement prevents drift. Quality gates block bad patterns.',
actDetail1: 'TDD Red → Green → Refactor cycle',
actDetail2: 'Live rule enforcement',
actDetail3: 'Dynamic checklists per domain',
evalTitle: 'EVAL',
evalDesc:
'Specialist council independently reviews. Cross-review findings. Consensus-driven approval.',
evalDetail1: 'Parallel specialist review',
evalDetail2: 'Cross-review and debate',
evalDetail3: 'Consensus: approve / concern / reject',
autoTitle: 'AUTO',
autoDesc:
'Fully autonomous cycle. Iterates PLAN → ACT → EVAL until zero critical issues. Ship with confidence.',
autoDetail1: 'Autonomous iteration',
autoDetail2: 'Quality gate: Critical=0, High=0',
autoDetail3: 'Production-ready guarantee',
},
hudShowcase: {
title: 'Intelligence at a Glance',
subtitle:
'A living statusbar that breathes with your session — cost tracking, cache savings, and mode awareness built in.',
buddyTitle: 'Breathing Buddy',
buddyDesc:
'Animated avatar reacts to session phase — idle, thinking, active, blocked, victory.',
costTitle: 'Cost Velocity',
costDesc:
'Real-time spend-rate tracking with trend indicators so you never get a billing surprise.',
cacheTitle: 'Cache Savings',
cacheDesc: 'See exactly how much prompt caching saves you per session.',
modeTitle: 'Mode Rainbow',
modeDesc:
'Per-mode color gradients — blue for PLAN, green for ACT, purple for EVAL, rainbow for AUTO.',
contextTitle: 'Context Bar',
contextDesc: 'Visual progress bar shows context window usage with warning thresholds.',
screenshotAlt:
'Codingbuddy HUD Statusbar showing buddy face, cost velocity, cache savings, and mode indicator',
},
skillsLibrary: {
title: '50 Built-in Skills',
subtitle: 'Reusable workflows that codify best practices into repeatable actions',
development: 'Development',
teamGit: 'Team & Git',
review: 'Review & Code',
intelligence: 'Intelligence',
specialized: 'Specialized',
developmentSkills:
'TDD, Refactoring, Debugging, Performance Optimization, Brainstorming, Legacy Modernization, Database Migration, API Design, Frontend Design, MCP Builder',
teamGitSkills: 'Ship, Git Master, Worktrees, Parallel Agents, Subagent Dev, Cross-Repo Issues',
reviewSkills:
'PR Review, PR All-in-One, Code Review, Code Explanation, Error Analysis, Build Fix, Verification',
intelligenceSkills:
'Retrospective, Security Audit, Tech Debt, Rule Authoring, Skill Creator, Prompt Engineering',
specializedSkills:
'Incident Response, Onboard, Deployment Checklist, Cost Budget, Widget Architecture, Agent Design',
},
ctaFooter: {
title: 'Ready to unify your AI coding?',
title: 'Ready to prove your AI coding works?',
command: 'npx codingbuddy init',
github: 'GitHub',
github: 'Star on GitHub',
docs: 'Documentation',
copyright: `© {year} Codingbuddy. All rights reserved.`,
madeWith: 'Made for developers who ship with AI',
copy: 'Copy',
copied: 'Copied!',
copyright: `© {year} Codingbuddy. MIT License.`,
madeWith: '37 agents. 9 tools. 50 skills. One command.',
},
};

Expand Down
4 changes: 4 additions & 0 deletions apps/landing-page/__tests__/i18n/request.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,15 @@ describe('i18n request config logic', () => {
expect(messages).toBeDefined();
expect(Object.keys(messages)).toEqual([
'hero',
'socialProof',
'beforeAfter',
'features',
'workflowDemo',
'supportedTools',
'hudShowcase',
'tuiDashboard',
'agents',
'skillsLibrary',
'quickStart',
'ctaFooter',
'header',
Expand Down
8 changes: 4 additions & 4 deletions apps/landing-page/__tests__/widgets/AgentsShowcase.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ describe('AgentsShowcase', () => {

it('should display section heading', () => {
render(<AgentsShowcase locale="en" />);
expect(screen.getByRole('heading', { level: 2 })).toHaveTextContent('35 Specialist Agents');
expect(screen.getByRole('heading', { level: 2 })).toHaveTextContent('37 Specialist Agents');
});

it('should have id attribute for anchor navigation', () => {
Expand All @@ -42,16 +42,16 @@ describe('AgentsShowcase', () => {

it('should render agent cards up to max 8', () => {
render(<AgentsShowcase locale="en" />);
// Total agents is 29, but only 8 should be visible
expect(screen.getByText('Frontend Developer')).toBeInTheDocument();
// Total agents is 37, but only 8 should be visible
expect(screen.getByText('Plan Mode Agent')).toBeInTheDocument();
// Count visible agent cards (each has role="img" for the emoji)
const agentIcons = screen.getAllByRole('img', { hidden: true });
expect(agentIcons.length).toBeLessThanOrEqual(8);
});

it('should display agent count for all agents', () => {
render(<AgentsShowcase locale="en" />);
expect(screen.getByText('29 agents')).toBeInTheDocument();
expect(screen.getByText('37 agents')).toBeInTheDocument();
});

it('should not render a search input', () => {
Expand Down
4 changes: 2 additions & 2 deletions apps/landing-page/__tests__/widgets/CTAFooter.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ describe('CTAFooter', () => {
it('should render CTA heading', async () => {
render(await CTAFooter({ locale: 'en' }));
expect(
screen.getByRole('heading', { level: 2, name: /Ready to unify your AI coding/i }),
screen.getByRole('heading', { level: 2, name: /Ready to prove your AI coding works/i }),
).toBeInTheDocument();
});

Expand Down Expand Up @@ -45,7 +45,7 @@ describe('CTAFooter', () => {

it('should render made for developers text', async () => {
render(await CTAFooter({ locale: 'en' }));
expect(screen.getByText(/Made for developers who ship with AI/)).toBeInTheDocument();
expect(screen.getByText(/37 agents\. 9 tools\. 50 skills\. One command\./)).toBeInTheDocument();
});

it('should have CTA section with data-testid', async () => {
Expand Down
12 changes: 7 additions & 5 deletions apps/landing-page/__tests__/widgets/Features.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,23 +31,25 @@ describe('Features', () => {
expect(section).toHaveAttribute('id', 'features');
});

it('should render 6 feature cards', async () => {
it('should render 8 feature cards', async () => {
render(await Features({ locale: 'en' }));
expect(screen.getByText('Universal Rules')).toBeInTheDocument();
expect(screen.getByText('35 AI Agents')).toBeInTheDocument();
expect(screen.getByText('37 Specialist Agents')).toBeInTheDocument();
expect(screen.getByText('Structured Workflow')).toBeInTheDocument();
expect(screen.getByText('Quality Built-in')).toBeInTheDocument();
expect(screen.getByText('MCP Protocol')).toBeInTheDocument();
expect(screen.getByText('Session Impact Reports')).toBeInTheDocument();
expect(screen.getByText('Self-Evolving Rules')).toBeInTheDocument();
expect(screen.getByText('50 Built-in Skills')).toBeInTheDocument();
expect(screen.getByText('Zero Config')).toBeInTheDocument();
});

it('should render feature descriptions', async () => {
render(await Features({ locale: 'en' }));
expect(screen.getByText(/One source of truth automatically applied/)).toBeInTheDocument();
expect(screen.getByText(/Specialist agents for architecture/)).toBeInTheDocument();
expect(screen.getByText(/Domain experts for architecture/)).toBeInTheDocument();
expect(screen.getByText(/PLAN → ACT → EVAL cycle/)).toBeInTheDocument();
expect(screen.getByText(/TDD, SOLID principles/)).toBeInTheDocument();
expect(screen.getByText(/Standard Model Context Protocol/)).toBeInTheDocument();
expect(screen.getByText(/Measurable proof that AI coding/)).toBeInTheDocument();
expect(screen.getByText(/One command to install/)).toBeInTheDocument();
});
});
4 changes: 2 additions & 2 deletions apps/landing-page/__tests__/widgets/Hero.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ describe('Hero', () => {
it('should display h1 heading', async () => {
render(await Hero({ locale: 'en' }));
expect(screen.getByRole('heading', { level: 1 })).toHaveTextContent(
'Multi-AI Rules for Consistent Coding',
'Prove Your AI Coding Is Actually Improving',
);
});

Expand All @@ -30,7 +30,7 @@ describe('Hero', () => {
it('should display subtitle', async () => {
render(await Hero({ locale: 'en' }));
expect(
screen.getByText('One ruleset for Cursor, Claude Code, Codex, Antigravity, Q, and Kiro.'),
screen.getByText('One command. 9 AI tools. Measurable impact on every session.'),
).toBeInTheDocument();
});

Expand Down
45 changes: 45 additions & 0 deletions apps/landing-page/__tests__/widgets/HudShowcase.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { describe, it, expect } from 'vitest';
import { render, screen } from '@testing-library/react';
import '@/__tests__/__helpers__/next-intl-server-mock';
import { HudShowcase } from '@/widgets/HudShowcase';

describe('HudShowcase', () => {
it('should render with locale prop', async () => {
render(await HudShowcase({ locale: 'en' }));
expect(screen.getByTestId('hud-showcase')).toBeInTheDocument();
});

it('should set lang attribute matching locale', async () => {
render(await HudShowcase({ locale: 'ko' }));
expect(screen.getByTestId('hud-showcase')).toHaveAttribute('lang', 'ko');
});

it('should display section heading', async () => {
render(await HudShowcase({ locale: 'en' }));
expect(screen.getByRole('heading', { level: 2 })).toHaveTextContent('Intelligence at a Glance');
});

it('should have aria-labelledby linking to heading', async () => {
render(await HudShowcase({ locale: 'en' }));
expect(screen.getByTestId('hud-showcase')).toHaveAttribute(
'aria-labelledby',
'hud-showcase-heading',
);
});

it('should render simulated HUD statusbar with all segments', async () => {
render(await HudShowcase({ locale: 'en' }));
expect(screen.getByText('buddy')).toBeInTheDocument();
expect(screen.getByText('PLAN')).toBeInTheDocument();
expect(screen.getByText('$0.47 saved')).toBeInTheDocument();
});

it('should render all 5 feature cards', async () => {
render(await HudShowcase({ locale: 'en' }));
expect(screen.getByText('Breathing Buddy')).toBeInTheDocument();
expect(screen.getByText('Cost Velocity')).toBeInTheDocument();
expect(screen.getByText('Cache Savings')).toBeInTheDocument();
expect(screen.getByText('Mode Rainbow')).toBeInTheDocument();
expect(screen.getByText('Context Bar')).toBeInTheDocument();
});
});
Loading
Loading