Skip to content
Open
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
70 changes: 52 additions & 18 deletions .github/workflows/frontend.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

name: Frontend CI/CD

on:
Expand All @@ -11,26 +12,25 @@ on:
- "frontend/**"
- ".github/workflows/frontend.yml"
branches: [ 'main' ]
workflow_dispatch:
permissions: read-all

jobs:
lint:
runs-on: ubuntu-latest
defaults:
run:
working-directory: 'frontend'
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd

- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f
uses: actions/setup-node@v4
with:
node-version: "24"
node-version: "20"
cache: "npm"
cache-dependency-path: '**/package-lock.json'

cache-dependency-path: 'frontend/package-lock.json'
- name: Install dependencies
run: npm ci --legacy-peer-deps

- name: Run ESLint
run: npm run lint

Expand All @@ -40,23 +40,57 @@ jobs:
run:
working-directory: 'frontend'
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd

- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f
uses: actions/setup-node@v4
with:
node-version: "24"
node-version: "20"
cache: "npm"
cache-dependency-path: '**/package-lock.json'

# Install dependencies
cache-dependency-path: 'frontend/package-lock.json'
- name: Install dependencies
run: npm ci --legacy-peer-deps

# Run build
- name: Run build
run: npm run build

# Run tests (if available)
- name: Run tests
run: npm test || echo "No tests yet"

playwright:
name: Playwright Component Tests
runs-on: ubuntu-latest
needs: build
timeout-minutes: 20
defaults:
run:
working-directory: 'frontend'
steps:
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
cache-dependency-path: 'frontend/package-lock.json'

- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: '1.23'

- name: Create Backend Env File
run: mkdir -p ../go-backend && touch ../go-backend/.env

- name: Install dependencies
run: npm ci --legacy-peer-deps

- name: Install Playwright Browsers
run: npx playwright install --with-deps

- name: Run Playwright Component Tests
run: npx playwright test
- name: Upload Playwright report
uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
path: frontend/playwright-report/
retention-days: 30
9 changes: 8 additions & 1 deletion frontend/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,11 @@ yarn-error.log*
*.tsbuildinfo
next-env.d.ts

.DS_Store
.DS_Store

# Playwright
/test-results/
/playwright-report/
/blob-report/
/playwright/.cache/
/playwright/.auth/
7 changes: 6 additions & 1 deletion frontend/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export default function Home() {
} = useGittufExplorer()

return (
<main className="min-h-screen bg-gradient-to-br from-slate-50 via-blue-50 to-indigo-50">
<main className="min-h-screen bg-gradient-to-br from-slate-50 via-blue-50 to-indigo-50" data-testid="homepage-container">
<div className="max-w-7xl mx-auto p-4 md:p-8">
<Header
currentRepository={currentRepository}
Expand Down Expand Up @@ -98,6 +98,7 @@ export default function Home() {
<TabsList className="mb-6 bg-white/80 backdrop-blur-sm p-1 rounded-lg shadow-sm">
<TabsTrigger
value="commits"
data-testid="tab-commits"
className="flex items-center data-[state=active]:bg-blue-500 data-[state=active]:text-white"
>
<GitCommit className="h-4 w-4 mr-2" />
Expand All @@ -106,6 +107,7 @@ export default function Home() {
<TabsTrigger
value="visualization"
disabled={!selectedCommit}
data-testid="tab-visualization"
className="flex items-center data-[state=active]:bg-green-500 data-[state=active]:text-white"
>
<FileJson className="h-4 w-4 mr-2" />
Expand All @@ -114,6 +116,7 @@ export default function Home() {
<TabsTrigger
value="tree"
disabled={!selectedCommit}
data-testid="tab-tree"
className="flex items-center data-[state=active]:bg-purple-500 data-[state=active]:text-white"
>
<FileJson className="h-4 w-4 mr-2" />
Expand All @@ -122,6 +125,7 @@ export default function Home() {
<TabsTrigger
value="compare"
disabled={!compareCommits.base || !compareCommits.compare}
data-testid="tab-compare"
className="flex items-center data-[state=active]:bg-orange-500 data-[state=active]:text-white"
>
<GitCompare className="h-4 w-4 mr-2" />
Expand All @@ -130,6 +134,7 @@ export default function Home() {
<TabsTrigger
value="analysis"
disabled={selectedCommits.length < 2}
data-testid="tab-analysis"
className="flex items-center data-[state=active]:bg-indigo-500 data-[state=active]:text-white"
>
<BarChart3 className="h-4 w-4 mr-2" />
Expand Down
17 changes: 12 additions & 5 deletions frontend/app/simulator/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,14 @@ export default function SimulatorPage() {

return (
<div
data-testid="homepage-container"
className={`min-h-screen transition-colors duration-300 ${
darkMode ? "bg-gray-900 text-white" : "bg-gradient-to-br from-blue-50 via-indigo-50 to-purple-50"
}`}
>
{/* Story Modal */}
<StoryModal
data-testid="story-modal"
isOpen={showStory}
onClose={() => setShowStory(false)}
fixture={fixture}
Expand All @@ -49,18 +51,23 @@ export default function SimulatorPage() {
<AnimatePresence>
{showSimulator && (
<motion.div
data-testid="simulator-content"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -20 }}
className="space-y-6"
>
{/* Status Card */}
<StatusCard result={displayResult.result} reasons={displayResult.reasons} />
<StatusCard
data-testid="status-card"
result={displayResult.result}
reasons={displayResult.reasons}
/>

{/* Main Content Area */}
<div className={`grid gap-6 ${expandedGraph ? "grid-cols-1" : "grid-cols-1 lg:grid-cols-4"}`}>
<SimulatorControls state={state} />
<SimulatorGraph state={state} />
<SimulatorControls state={state} data-testid="simulator-controls"/>
<SimulatorGraph state={state} data-testid="simulator-graph" />
</div>

{/* Detailed Results */}
Expand All @@ -70,11 +77,11 @@ export default function SimulatorPage() {
</AnimatePresence>

{/* Footer Glossary */}
<SimulatorGlossary state={state} />
<SimulatorGlossary data-testid="simulator-glossary" state={state} />
</div>

{/* Custom Config Dialog */}
<SimulatorConfigModal state={state} />
</div>
)
}
}
3 changes: 2 additions & 1 deletion frontend/components/features/commit/commit-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export default function CommitList({
}

return (
<div className="space-y-4">
<div className="space-y-4" data-testid="commit-list">
<div className="flex flex-col md:flex-row gap-3 items-start md:items-center">
<div className="relative flex-grow">
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-slate-400 h-4 w-4" />
Expand Down Expand Up @@ -226,6 +226,7 @@ export default function CommitList({
? "bg-blue-50 border-blue-200"
: "bg-white border-slate-200 hover:border-slate-300"
}`}
data-testid="commit-item"
>
<div className="flex items-start justify-between">
{selectionMode === "range" && (
Expand Down
12 changes: 8 additions & 4 deletions frontend/components/features/json/json-diff-visualization.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ const NODE_WIDTH = 220
const NODE_HEIGHT = 80

// Animated node wrapper
const AnimatedNode = ({ children }: { children: React.ReactNode }) => {
const AnimatedNode = ({ children, testId }: { children: React.ReactNode; testId?: string }) => {
return (
<motion.div initial={{ opacity: 0, scale: 0.8 }} animate={{ opacity: 1, scale: 1 }} transition={{ duration: 0.3 }}>
<motion.div initial={{ opacity: 0, scale: 0.8 }} animate={{ opacity: 1, scale: 1 }} transition={{ duration: 0.3 }} data-testid={testId}>
{children}
</motion.div>
)
Expand Down Expand Up @@ -169,7 +169,7 @@ function DiffRootNode({ data, isConnectable }: { data: DiffNodeData; isConnectab

function DiffAddedNode({ data, isConnectable }: { data: DiffNodeData; isConnectable: boolean }) {
return (
<AnimatedNode>
<AnimatedNode testId="diff-added">
<DiffNodeTooltip data={data} type="diffAdded">
<CollapsibleCard
title={data.label || "Added"}
Expand Down Expand Up @@ -713,7 +713,9 @@ export default function JsonDiffVisualization({
}, [baseData, compareData, expandedNodes, toggleNodeExpansion, showUnchanged, setNodes, setEdges])

return (
<ReactFlow
<div data-testid="json-diff-viewer">
<div data-testid="json-diff-container">
<ReactFlow
nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}
Expand Down Expand Up @@ -758,5 +760,7 @@ export default function JsonDiffVisualization({
</div>
)}
</ReactFlow>
</div>
</div>
)
}
2 changes: 1 addition & 1 deletion frontend/components/features/json/json-tree-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ export default function JsonTreeView({ jsonData, viewMode = "normal" }: JsonTree
}

return (
<div className="font-mono text-sm max-h-[600px] overflow-auto">
<div className="font-mono text-sm max-h-[600px] overflow-auto" data-testid="json-tree-view">
<div className="p-4">
<TreeNode data={jsonData} viewMode={viewMode} />
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ interface ValidationDetails {
}

return (
<Card className="bg-white/90 backdrop-blur-sm border-slate-200 shadow-lg">
<Card className="bg-white/90 backdrop-blur-sm border-slate-200 shadow-lg" data-testid="repository-selector">
<CardHeader className="pb-4">
<div className="flex items-center justify-between">
<div className="flex items-center space-x-3">
Expand All @@ -152,7 +152,7 @@ interface ValidationDetails {
</div>
</div>
{currentRepository && (
<div className="text-right">
<div className="text-right" data-testid="selected-repository">
<Badge variant="outline" className="bg-green-50 text-green-700 border-green-200">
<CheckCircle className="h-3 w-3 mr-1" />
Connected
Expand All @@ -165,11 +165,11 @@ interface ValidationDetails {
<CardContent className="space-y-6">
<Tabs value={activeTab} onValueChange={(value) => setActiveTab(value as "remote" | "local")}>
<TabsList className="grid w-full grid-cols-2">
<TabsTrigger value="remote" className="flex items-center">
<TabsTrigger value="remote" className="flex items-center" data-testid="repository-option">
<Globe className="h-4 w-4 mr-2" />
Remote Repository
</TabsTrigger>
<TabsTrigger value="local" className="flex items-center">
<TabsTrigger value="local" className="flex items-center" data-testid="repository-option">
<HardDrive className="h-4 w-4 mr-2" />
Local Repository
</TabsTrigger>
Expand Down Expand Up @@ -229,6 +229,7 @@ interface ValidationDetails {
onClick={handleTryDemo}
disabled={isLoading}
className="text-blue-600 border-blue-200 hover:bg-blue-50 bg-transparent"
data-testid="try-demo-button"
>
Try Demo
</Button>
Expand Down
7 changes: 4 additions & 3 deletions frontend/components/features/simulator/simulator-controls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ import type { SimulatorState } from "@/hooks/use-gittuf-simulator"

interface SimulatorControlsProps {
state: SimulatorState
"data-testid"?: string
}

export function SimulatorControls({ state }: SimulatorControlsProps) {
const {
export function SimulatorControls({ state, "data-testid": testId }: SimulatorControlsProps) {
const {
expandedGraph,
showControls,
setShowControls,
Expand All @@ -33,7 +34,7 @@ export function SimulatorControls({ state }: SimulatorControlsProps) {
if (expandedGraph) return null

return (
<motion.div initial={{ opacity: 0, x: -20 }} animate={{ opacity: 1, x: 0 }} className="lg:col-span-1 space-y-4">
<motion.div initial={{ opacity: 0, x: -20 }} animate={{ opacity: 1, x: 0 }} className="lg:col-span-1 space-y-4" data-testid={testId}>
<Card className={darkMode ? "bg-gray-800 border-gray-700" : "bg-white"}>
<CardHeader className="pb-3">
<div className="flex items-center justify-between">
Expand Down
Loading