Spaces:
Build error
Build error
# Getting Started with the OpenHands Frontend | |
## Overview | |
This is the frontend of the OpenHands project. It is a React application that provides a web interface for the OpenHands project. | |
## Tech Stack | |
- Remix SPA Mode (React + Vite + React Router) | |
- TypeScript | |
- Redux | |
- TanStack Query | |
- Tailwind CSS | |
- i18next | |
- React Testing Library | |
- Vitest | |
- Mock Service Worker | |
## Getting Started | |
### Prerequisites | |
- Node.js 20.x or later | |
- `npm`, `bun`, or any other package manager that supports the `package.json` file | |
### Installation | |
```sh | |
# Clone the repository | |
git clone https://github.com/All-Hands-AI/OpenHands.git | |
# Change the directory to the frontend | |
cd OpenHands/frontend | |
# Install the dependencies | |
npm install | |
``` | |
### Running the Application in Development Mode | |
We use `msw` to mock the backend API. To start the application with the mocked backend, run the following command: | |
```sh | |
npm run dev | |
``` | |
This will start the application in development mode. Open [http://localhost:3001](http://localhost:3001) to view it in the browser. | |
**NOTE: The backend is _partially_ mocked using `msw`. Therefore, some features may not work as they would with the actual backend.** | |
See the [Development.md](../Development.md) for extra tips on how to run in development mode. | |
### Running the Application with the Actual Backend (Production Mode) | |
To run the application with the actual backend: | |
```sh | |
# Build the application from the root directory | |
make build | |
# Start the application | |
make run | |
``` | |
Or to run backend and frontend separately. | |
```sh | |
# Start the backend from the root directory | |
make start-backend | |
# Serve the frontend | |
make start-frontend or | |
cd frontend && npm start -- --port 3001 | |
``` | |
Start frontend with Mock Service Worker (MSW), see testing for more info. | |
```sh | |
npm run dev:mock or npm run dev:mock:saas | |
``` | |
### Environment Variables | |
The frontend application uses the following environment variables: | |
| Variable | Description | Default Value | | |
| --------------------------- | ---------------------------------------------------------------------- | ---------------- | | |
| `VITE_BACKEND_BASE_URL` | The backend hostname without protocol (used for WebSocket connections) | `localhost:3000` | | |
| `VITE_BACKEND_HOST` | The backend host with port for API connections | `127.0.0.1:3000` | | |
| `VITE_MOCK_API` | Enable/disable API mocking with MSW | `false` | | |
| `VITE_MOCK_SAAS` | Simulate SaaS mode in development | `false` | | |
| `VITE_USE_TLS` | Use HTTPS/WSS for backend connections | `false` | | |
| `VITE_FRONTEND_PORT` | Port to run the frontend application | `3001` | | |
| `VITE_INSECURE_SKIP_VERIFY` | Skip TLS certificate verification | `false` | | |
| `VITE_GITHUB_TOKEN` | GitHub token for repository access (used in some tests) | - | | |
You can create a `.env` file in the frontend directory with these variables based on the `.env.sample` file. | |
### Project Structure | |
```sh | |
frontend | |
├── __tests__ # Tests | |
├── public | |
├── src | |
│ ├── api # API calls | |
│ ├── assets | |
│ ├── components | |
│ ├── context # Local state management | |
│ ├── hooks # Custom hooks | |
│ ├── i18n # Internationalization | |
│ ├── mocks # MSW mocks for development | |
│ ├── routes # React Router file-based routes | |
│ ├── services | |
│ ├── state # Redux state management | |
│ ├── types | |
│ ├── utils # Utility/helper functions | |
│ └── root.tsx # Entry point | |
└── .env.sample # Sample environment variables | |
``` | |
#### Components | |
Components are organized into folders based on their **domain**, **feature**, or **shared functionality**. | |
```sh | |
components | |
├── features # Domain-specific components | |
├── layout | |
├── modals | |
└── ui # Shared UI components | |
``` | |
### Features | |
- Real-time updates with WebSockets | |
- Internationalization | |
- Router data loading with Remix | |
- User authentication with GitHub OAuth (if saas mode is enabled) | |
## Testing | |
### Testing Framework and Tools | |
We use the following testing tools: | |
- **Test Runner**: Vitest | |
- **Rendering**: React Testing Library | |
- **User Interactions**: @testing-library/user-event | |
- **API Mocking**: [Mock Service Worker (MSW)](https://mswjs.io/) | |
- **Code Coverage**: Vitest with V8 coverage | |
### Running Tests | |
To run all tests: | |
```sh | |
npm run test | |
``` | |
To run tests with coverage: | |
```sh | |
npm run test:coverage | |
``` | |
### Testing Best Practices | |
1. **Component Testing** | |
- Test components in isolation | |
- Use our custom [`renderWithProviders()`](https://github.com/All-Hands-AI/OpenHands/blob/ce26f1c6d3feec3eedf36f823dee732b5a61e517/frontend/test-utils.tsx#L56-L85) that wraps the components we want to test in our providers. It is especially useful for components that use Redux | |
- Use `render()` from React Testing Library to render components | |
- Prefer querying elements by role, label, or test ID over CSS selectors | |
- Test both rendering and interaction scenarios | |
2. **User Event Simulation** | |
- Use `userEvent` for simulating realistic user interactions | |
- Test keyboard events, clicks, typing, and other user actions | |
- Handle edge cases like disabled states, empty inputs, etc. | |
3. **Mocking** | |
- We test components that make network requests by mocking those requests with Mock Service Worker (MSW) | |
- Use `vi.fn()` to create mock functions for callbacks and event handlers | |
- Mock external dependencies and API calls (more info)[https://mswjs.io/docs/getting-started] | |
- Verify mock function calls using `.toHaveBeenCalledWith()`, `.toHaveBeenCalledTimes()` | |
4. **Accessibility Testing** | |
- Use `toBeInTheDocument()` to check element presence | |
- Test keyboard navigation and screen reader compatibility | |
- Verify correct ARIA attributes and roles | |
5. **State and Prop Testing** | |
- Test component behavior with different prop combinations | |
- Verify state changes and conditional rendering | |
- Test error states and loading scenarios | |
6. **Internationalization (i18n) Testing** | |
- Test translation keys and placeholders | |
- Verify text rendering across different languages | |
Example Test Structure: | |
```typescript | |
import { render, screen } from "@testing-library/react"; | |
import userEvent from "@testing-library/user-event"; | |
import { describe, it, expect, vi } from "vitest"; | |
describe("ComponentName", () => { | |
it("should render correctly", () => { | |
render(<Component />); | |
expect(screen.getByRole("button")).toBeInTheDocument(); | |
}); | |
it("should handle user interactions", async () => { | |
const mockCallback = vi.fn(); | |
const user = userEvent.setup(); | |
render(<Component onClick={mockCallback} />); | |
const button = screen.getByRole("button"); | |
await user.click(button); | |
expect(mockCallback).toHaveBeenCalledOnce(); | |
}); | |
}); | |
``` | |
### Example Tests in the Codebase | |
For real-world examples of testing, check out these test files: | |
1. **Chat Input Component Test**: | |
[`__tests__/components/chat/chat-input.test.tsx`](https://github.com/All-Hands-AI/OpenHands/blob/main/frontend/__tests__/components/chat/chat-input.test.tsx) | |
- Demonstrates comprehensive testing of a complex input component | |
- Covers various scenarios like submission, disabled states, and user interactions | |
2. **File Explorer Component Test**: | |
[`__tests__/components/file-explorer/file-explorer.test.tsx`](https://github.com/All-Hands-AI/OpenHands/blob/main/frontend/__tests__/components/file-explorer/file-explorer.test.tsx) | |
- Shows testing of a more complex component with multiple interactions | |
- Illustrates testing of nested components and state management | |
### Test Coverage | |
- Aim for high test coverage, especially for critical components | |
- Focus on testing different scenarios and edge cases | |
- Use code coverage reports to identify untested code paths | |
### Continuous Integration | |
Tests are automatically run during: | |
- Pre-commit hooks | |
- Pull request checks | |
- CI/CD pipeline | |
## Contributing | |
Please read the [CONTRIBUTING.md](../CONTRIBUTING.md) file for details on our code of conduct, and the process for submitting pull requests to us. | |
## Troubleshooting | |
TODO | |