diff --git a/QA.md b/QA.md new file mode 100644 index 0000000..02bffe2 --- /dev/null +++ b/QA.md @@ -0,0 +1,17 @@ +app_type: spa +coverage_applies: false +coverage_source: null +coverage_threshold: 0 +coverage_tool: none +install_steps: +- npm install +- npm install --save-dev @testing-library/jest-dom @testing-library/react @testing-library/user-event + jsdom vitest @vitest/coverage-v8 +lint_tool: none +notes: Verify that the App component renders an

heading containing the text 'Hello + World'. +stack: TypeScript/React+Vite +test_files: +- src/App.test.jsx +test_runner: npx vitest run +workspace: /tmp/forge-repos/hello-world-react-app-02ad6163 diff --git a/RUNNING.md b/RUNNING.md index 77896cf..e2d5df9 100644 --- a/RUNNING.md +++ b/RUNNING.md @@ -1,33 +1,78 @@ -# Running the Todo API +# Hello World React App + +## TEAM_BRIEF +stack: TypeScript/React+Vite +test_runner: npx vitest run +lint_tool: none +coverage_tool: none +coverage_threshold: 0 +coverage_applies: false ## Prerequisites -- Python 3.10 or later +- Node.js 18+ and npm +- Docker (optional, for containerised execution) -## Install dependencies +## Local Setup ```bash -pip install fastapi uvicorn pydantic +# Install dependencies +npm install + +# Start the development server +npm run dev + +# Run the test suite +npm test + +# Build for production +npm run build + +# Preview the production build +npm run preview ``` -For running the test suite you will also need: +## Docker-based Setup ```bash -pip install httpx pytest +# Build the Docker image +docker build -t hello-world-react . + +# Run the tests inside a container +docker run --rm hello-world-react npm test + +# Run the dev server (accessible on http://localhost:5173) +docker run --rm -p 5173:5173 hello-world-react npm run dev -- --host 0.0.0.0 ``` -## Start the server +## Project Structure -```bash -uvicorn main:app --reload --host 0.0.0.0 --port 8000 ``` +. +├── index.html # Vite HTML entry point +├── package.json # Dependencies and scripts +├── vite.config.js # Vite + Vitest configuration +├── RUNNING.md # This file +└── src/ + ├── main.jsx # React entry point + ├── App.jsx # Main App component (renders Hello World) + ├── App.test.jsx # Vitest test suite for App component + └── setupTests.js # Test setup (jest-dom matchers) +``` + +## Testing -The API will be available at . +The test suite uses **Vitest** with **React Testing Library** and verifies that the +`App` component renders an `

` heading containing the text "Hello World". -Interactive docs are served at . +Run the tests: + +```bash +npm test +``` -## Run the tests +Run tests in watch mode: ```bash -pytest tests/ +npm run test:watch ``` diff --git a/index.html b/index.html new file mode 100644 index 0000000..8727541 --- /dev/null +++ b/index.html @@ -0,0 +1,12 @@ + + + + + + Hello World + + +
+ + + diff --git a/package.json b/package.json new file mode 100644 index 0000000..09370c2 --- /dev/null +++ b/package.json @@ -0,0 +1,25 @@ +{ + "name": "hello-world-react", + "private": true, + "version": "1.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview", + "test": "vitest run", + "test:watch": "vitest" + }, + "dependencies": { + "react": "^18.3.1", + "react-dom": "^18.3.1" + }, + "devDependencies": { + "@testing-library/jest-dom": "^6.6.3", + "@testing-library/react": "^16.1.0", + "@vitejs/plugin-react": "^4.3.4", + "jsdom": "^25.0.1", + "vite": "^6.0.0", + "vitest": "^2.1.8" + } +} diff --git a/src/App.jsx b/src/App.jsx new file mode 100644 index 0000000..2be9c6c --- /dev/null +++ b/src/App.jsx @@ -0,0 +1,12 @@ +/** + * App component — renders the main application heading. + * + * @returns {JSX.Element} A div containing the "Hello World" heading. + */ +export default function App() { + return ( +
+

Hello World

+
+ ); +} diff --git a/src/App.test.jsx b/src/App.test.jsx new file mode 100644 index 0000000..35f861d --- /dev/null +++ b/src/App.test.jsx @@ -0,0 +1,29 @@ +import { describe, it, expect } from 'vitest'; +import { render, screen } from '@testing-library/react'; +import App from './App.jsx'; + +describe('App', () => { + it('renders the Hello World heading', () => { + render(); + const heading = screen.getByRole('heading', { name: /hello world/i }); + expect(heading).toBeInTheDocument(); + }); + + it('renders Hello World as text content', () => { + render(); + const element = screen.getByText('Hello World'); + expect(element).toBeInTheDocument(); + }); + + it('renders exactly one heading element', () => { + const { container } = render(); + const headings = container.querySelectorAll('h1'); + expect(headings).toHaveLength(1); + }); + + it('heading contains the exact text Hello World', () => { + render(); + const heading = screen.getByRole('heading', { level: 1 }); + expect(heading).toHaveTextContent('Hello World'); + }); +}); diff --git a/src/main.jsx b/src/main.jsx new file mode 100644 index 0000000..6f4d655 --- /dev/null +++ b/src/main.jsx @@ -0,0 +1,9 @@ +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import App from './App.jsx'; + +ReactDOM.createRoot(document.getElementById('root')).render( + + + +); diff --git a/src/setupTests.js b/src/setupTests.js new file mode 100644 index 0000000..7b0828b --- /dev/null +++ b/src/setupTests.js @@ -0,0 +1 @@ +import '@testing-library/jest-dom'; diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 0000000..53d9d0c --- /dev/null +++ b/vite.config.js @@ -0,0 +1,11 @@ +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; + +export default defineConfig({ + plugins: [react()], + test: { + environment: 'jsdom', + globals: true, + setupFiles: './src/setupTests.js', + }, +});