Skip to content
Open
Show file tree
Hide file tree
Changes from 4 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
3 changes: 3 additions & 0 deletions .github/workflows/playwright.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ jobs:
- name: Install dependencies
run: bun install

- name: Install React app dependencies
run: cd react-app && bun install

- name: Install Playwright Browsers
run: bunx playwright install --with-deps chromium

Expand Down
35 changes: 35 additions & 0 deletions .github/workflows/react.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: React App

on:
push:
branches: [main, master]
pull_request:
branches: [main, master]

jobs:
build-lint-test:
runs-on: ubuntu-latest

defaults:
run:
working-directory: react-app

steps:
- uses: actions/checkout@v4
with:
submodules: true

- name: Setup Bun
uses: oven-sh/setup-bun@v2

- name: Install dependencies
run: bun install

- name: Lint
run: bun run lint

- name: Unit tests
run: bun run test

- name: Build
run: bun run build
3 changes: 3 additions & 0 deletions .github/workflows/security-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ jobs:
- name: Install dependencies
run: bun install

- name: Install React app dependencies
run: cd react-app && bun install

- name: Install Playwright Browsers
run: bunx playwright install --with-deps chromium

Expand Down
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,21 @@ Run `bun run setup` again after a `git pull` that updates the `realworld` submod

Run `bun run build` to build the project. The build artifacts will be stored in the `dist/` directory.

## React migration (`react-app/`)

This repository also contains a 1:1 port of the Conduit app to **React 18 + TypeScript + Vite**, located in [`react-app/`](./react-app). It preserves the exact same routes, the custom Conduit theme, and the external RealWorld API contract. The Angular source remains in place during the migration.

```bash
cd react-app
bun install
bun run dev # Dev server at http://localhost:4200
bun run build # Type-check + production build to react-app/dist
bun run lint # ESLint (zero warnings)
bun run test # Unit tests (Vitest)
```

End-to-end Playwright tests (in the repo-root `e2e/` suite) run against the React app — the root `playwright.config.ts` boots `react-app` on port 4200.

## Functionality overview

The example application is a social blogging site (i.e. a Medium.com clone) called "Conduit". It uses a custom API for all requests, including authentication. You can view a live demo over at [demo.realworld.show](https://demo.realworld.show)
Expand Down
7 changes: 4 additions & 3 deletions playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { defineConfig } from '@playwright/test';
import { baseConfig } from './e2e/playwright.base';

/**
* Angular-specific Playwright configuration.
* Extends the shared RealWorld base config with the Angular dev server.
* Playwright configuration for the migrated React + Vite app.
* Extends the shared RealWorld base config with the React dev server.
*/
export default defineConfig({
...baseConfig,
Expand All @@ -14,7 +14,8 @@ export default defineConfig({
},

webServer: {
command: 'npm run start',
command: 'bun run dev',
cwd: 'react-app',
Comment on lines +17 to +18

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚩 Playwright E2E tests now target the React app instead of Angular

The playwright.config.ts change switches the web server from npm run start (Angular CLI dev server) to bun run dev with cwd: 'react-app' (Vite dev server). This means all E2E tests in the e2e/ directory now run exclusively against the React app. Any behavioral differences between the Angular and React implementations could cause E2E test regressions. The Angular app's dev server is no longer exercised by CI at all. This is presumably intentional as part of the migration, but worth confirming that the Angular app isn't meant to continue being tested independently.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed intentional. The goal of this PR is to validate the React port against the existing e2e suite, so the Playwright webServer now boots the React app. The Angular build/unit tests still run via the existing test job (root bun run test) and the Angular source is untouched. If you'd prefer to keep an Angular e2e job running in parallel during the transition, that's easy to add — let me know and I'll wire up a second webServer/project. Final disposition of the Angular source (keep vs. remove) is the open question on the PR.

Comment on lines +17 to +18

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚩 Playwright config now runs React app instead of Angular — Angular E2E coverage removed

The root playwright.config.ts was changed from command: 'npm run start' (Angular) to command: 'bun run dev', cwd: 'react-app' (React). This means all existing E2E tests in e2e/ now run exclusively against the React app. The Angular app's E2E coverage is silently dropped. This is presumably intentional for the migration, but it means the Angular app (still present in src/) no longer has automated E2E validation. If both apps need to be maintained in parallel, a separate Playwright config for Angular would be needed.

Open in Devin Review (Staging)

Was this helpful? React with 👍 or 👎 to provide feedback.

Debug

Playground

url: 'http://localhost:4200',
reuseExistingServer: !process.env.CI,
timeout: 120_000,
Expand Down
28 changes: 28 additions & 0 deletions react-app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local
*.tsbuildinfo

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

# Vitest / coverage
coverage
810 changes: 810 additions & 0 deletions react-app/bun.lock

Large diffs are not rendered by default.

25 changes: 25 additions & 0 deletions react-app/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import js from '@eslint/js';
import globals from 'globals';
import reactHooks from 'eslint-plugin-react-hooks';
import reactRefresh from 'eslint-plugin-react-refresh';
import tseslint from 'typescript-eslint';

export default tseslint.config(
{ ignores: ['dist'] },
{
extends: [js.configs.recommended, ...tseslint.configs.recommended],
files: ['**/*.{ts,tsx}'],
languageOptions: {
ecmaVersion: 2022,
globals: globals.browser,
},
plugins: {
'react-hooks': reactHooks,
'react-refresh': reactRefresh,
},
rules: {
...reactHooks.configs.recommended.rules,
'react-refresh/only-export-components': ['warn', { allowConstantExport: true }],
},
},
);
20 changes: 20 additions & 0 deletions react-app/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Conduit</title>
<base href="/" />

<meta name="viewport" content="width=device-width, initial-scale=1" />
<link href="//code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css" rel="stylesheet" type="text/css" />
<link
href="//fonts.googleapis.com/css?family=Titillium+Web:700|Lora:400,400italic,700,700italic|Source+Sans+Pro:400,300,600,700,300italic,400italic,600italic,700italic"
rel="stylesheet"
type="text/css"
/>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
43 changes: 43 additions & 0 deletions react-app/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"name": "react-conduit",
"version": "0.0.0",
"license": "MIT",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"start": "vite",
"build": "tsc -b && vite build",
"preview": "vite preview",
"lint": "eslint . --max-warnings 0",
"test": "vitest run",
"test:watch": "vitest"
},
"engines": {
"node": ">=20.11.1"
},
"dependencies": {
"dompurify": "^3.2.4",
"marked": "^17.0.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^6.30.0"
},
"devDependencies": {
"@eslint/js": "^9.18.0",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.1.0",
"@types/react": "^18.3.18",
"@types/react-dom": "^18.3.5",
"@vitejs/plugin-react": "^4.3.4",
"eslint": "^9.18.0",
"eslint-plugin-react-hooks": "^5.1.0",
"eslint-plugin-react-refresh": "^0.4.18",
"globals": "^15.14.0",
"jsdom": "^25.0.1",
"typescript": "~5.9.3",
"typescript-eslint": "^8.21.0",
"vite": "^6.0.7",
"vitest": "^2.1.8"
}
}
1 change: 1 addition & 0 deletions react-app/public/_redirects
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/* /index.html 200
3 changes: 3 additions & 0 deletions react-app/public/assets/conduit-logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions react-app/public/assets/default-avatar.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added react-app/public/assets/end.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading