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
17 changes: 17 additions & 0 deletions QA.md
Original file line number Diff line number Diff line change
@@ -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 <h1> 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
71 changes: 58 additions & 13 deletions RUNNING.md
Original file line number Diff line number Diff line change
@@ -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 <http://localhost:8000>.
The test suite uses **Vitest** with **React Testing Library** and verifies that the
`App` component renders an `<h1>` heading containing the text "Hello World".

Interactive docs are served at <http://localhost:8000/docs>.
Run the tests:

```bash
npm test
```

## Run the tests
Run tests in watch mode:

```bash
pytest tests/
npm run test:watch
```
12 changes: 12 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Hello World</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
25 changes: 25 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -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"
}
}
12 changes: 12 additions & 0 deletions src/App.jsx
Original file line number Diff line number Diff line change
@@ -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 (
<div>
<h1>Hello World</h1>
</div>
);
}
29 changes: 29 additions & 0 deletions src/App.test.jsx
Original file line number Diff line number Diff line change
@@ -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(<App />);
const heading = screen.getByRole('heading', { name: /hello world/i });
expect(heading).toBeInTheDocument();
});

it('renders Hello World as text content', () => {
render(<App />);
const element = screen.getByText('Hello World');
expect(element).toBeInTheDocument();
});

it('renders exactly one heading element', () => {
const { container } = render(<App />);
const headings = container.querySelectorAll('h1');
expect(headings).toHaveLength(1);
});

it('heading contains the exact text Hello World', () => {
render(<App />);
const heading = screen.getByRole('heading', { level: 1 });
expect(heading).toHaveTextContent('Hello World');
});
});
9 changes: 9 additions & 0 deletions src/main.jsx
Original file line number Diff line number Diff line change
@@ -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(
<React.StrictMode>
<App />
</React.StrictMode>
);
1 change: 1 addition & 0 deletions src/setupTests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import '@testing-library/jest-dom';
11 changes: 11 additions & 0 deletions vite.config.js
Original file line number Diff line number Diff line change
@@ -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',
},
});