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
1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
**/tsconfig.webpack.json
**/node_modules
downstream_projects
integration
logo
src
scripts
Expand Down
7 changes: 6 additions & 1 deletion downstream_projects.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
{
"sample-app-react": "https://github.com/ui-router/sample-app-react.git"
"sample-app-react": "https://github.com/ui-router/sample-app-react.git",
"react-versions": {
"react17": "./integration/react17",
"react18": "./integration/react18",
"react19": "./integration/react19"
}
}
70 changes: 70 additions & 0 deletions integration/react17/__tests__/sanity.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/**
* Sanity test for @uirouter/react with React 17
* This test verifies basic functionality works with React 17
*/
import { describe, it, expect } from 'vitest';
import * as React from 'react';
import { render, screen, waitFor } from '@testing-library/react';
import { UIRouter, UIView, UISref, pushStateLocationPlugin } from '@uirouter/react';
import { memoryLocationPlugin } from '@uirouter/core';

const Home = () => <div data-testid="home">Home Page</div>;
const About = () => <div data-testid="about">About Page</div>;

const states = [
{ name: 'home', url: '/home', component: Home },
{ name: 'about', url: '/about', component: About },
];

describe('@uirouter/react with React 17', () => {
it('renders UIRouter and UIView', async () => {
render(
<UIRouter plugins={[memoryLocationPlugin]} states={states}>
<UIView />
</UIRouter>
);

// Should render without crashing
expect(document.body).toBeDefined();
});

it('navigates to a state and renders the component', async () => {
const { container } = render(
<UIRouter plugins={[memoryLocationPlugin]} states={states}>
<div>
<nav>
<UISref to="home">
<a data-testid="home-link">Home</a>
</UISref>
<UISref to="about">
<a data-testid="about-link">About</a>
</UISref>
</nav>
<UIView />
</div>
</UIRouter>
);

// Click home link
screen.getByTestId('home-link').click();

await waitFor(() => {
expect(screen.getByTestId('home')).toBeDefined();
});
});

it('UISref generates correct href', async () => {
render(
<UIRouter plugins={[memoryLocationPlugin]} states={states}>
<UISref to="about">
<a data-testid="link">About</a>
</UISref>
</UIRouter>
);

await waitFor(() => {
const link = screen.getByTestId('link');
expect(link.getAttribute('href')).toContain('/about');
});
});
});
23 changes: 23 additions & 0 deletions integration/react17/e2e/sanity.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { test, expect } from '@playwright/test';

test.describe('UI-Router React 17 Sample App', () => {
test('loads and navigates between states', async ({ page }) => {
await page.goto('/');

// Should have navigation links
await expect(page.getByTestId('home-link')).toBeVisible();
await expect(page.getByTestId('about-link')).toBeVisible();

// Navigate to home
await page.getByTestId('home-link').click();
await expect(page.getByTestId('home-title')).toHaveText('Home Page');

// Navigate to about
await page.getByTestId('about-link').click();
await expect(page.getByTestId('about-title')).toHaveText('About Page');

// Navigate back to home
await page.getByTestId('home-link').click();
await expect(page.getByTestId('home-title')).toHaveText('Home Page');
});
});
12 changes: 12 additions & 0 deletions integration/react17/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>UI-Router React 17 Sample App</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
27 changes: 27 additions & 0 deletions integration/react17/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "integration-test-react17",
"version": "1.0.0",
"private": true,
"description": "Integration tests for @uirouter/react with React 17",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"test": "vitest run && npm run build && npx playwright install chromium && npx playwright test"
},
"dependencies": {
"react": "^17.0.2",
"react-dom": "^17.0.2"
},
"devDependencies": {
"@playwright/test": "^1.49.1",
"@testing-library/react": "^12.1.5",
"@types/react": "^17.0.80",
"@types/react-dom": "^17.0.25",
"@vitejs/plugin-react": "^4.3.4",
"jsdom": "^27.4.0",
"typescript": "^5.9.3",
"vite": "^6.0.7",
"vitest": "^4.0.16"
}
}
14 changes: 14 additions & 0 deletions integration/react17/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { defineConfig } from '@playwright/test';

export default defineConfig({
testDir: './e2e',
timeout: 30000,
use: {
baseURL: 'http://localhost:4173',
},
webServer: {
command: 'npm run preview',
port: 4173,
reuseExistingServer: !process.env.CI,
},
});
41 changes: 41 additions & 0 deletions integration/react17/src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from 'react';
import { UIRouter, UIView, UISref, hashLocationPlugin } from '@uirouter/react';

const Home = () => (
<div>
<h1 data-testid="home-title">Home Page</h1>
<p>Welcome to the UI-Router React 17 sample app!</p>
</div>
);

const About = () => (
<div>
<h1 data-testid="about-title">About Page</h1>
<p>This is a simple sample application.</p>
</div>
);

const states = [
{ name: 'home', url: '/home', component: Home },
{ name: 'about', url: '/about', component: About },
];

const App = () => (
<UIRouter plugins={[hashLocationPlugin]} states={states}>
<div>
<nav>
<UISref to="home">
<a data-testid="home-link">Home</a>
</UISref>
{' | '}
<UISref to="about">
<a data-testid="about-link">About</a>
</UISref>
</nav>
<hr />
<UIView />
</div>
</UIRouter>
);

export default App;
10 changes: 10 additions & 0 deletions integration/react17/src/main.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
18 changes: 18 additions & 0 deletions integration/react17/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"strict": true,
"esModuleInterop": true
},
"include": ["src", "e2e", "__tests__"]
}
6 changes: 6 additions & 0 deletions integration/react17/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
plugins: [react()],
});
9 changes: 9 additions & 0 deletions integration/react17/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { defineConfig } from 'vitest/config';

export default defineConfig({
test: {
environment: 'jsdom',
include: ['**/*.test.ts', '**/*.test.tsx'],
exclude: ['e2e/**', 'node_modules/**'],
},
});
70 changes: 70 additions & 0 deletions integration/react18/__tests__/sanity.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/**
* Sanity test for @uirouter/react with React 18
* This test verifies basic functionality works with React 18
*/
import { describe, it, expect } from 'vitest';
import * as React from 'react';
import { render, screen, waitFor } from '@testing-library/react';
import { UIRouter, UIView, UISref, pushStateLocationPlugin } from '@uirouter/react';
import { memoryLocationPlugin } from '@uirouter/core';

const Home = () => <div data-testid="home">Home Page</div>;
const About = () => <div data-testid="about">About Page</div>;

const states = [
{ name: 'home', url: '/home', component: Home },
{ name: 'about', url: '/about', component: About },
];

describe('@uirouter/react with React 18', () => {
it('renders UIRouter and UIView', async () => {
render(
<UIRouter plugins={[memoryLocationPlugin]} states={states}>
<UIView />
</UIRouter>
);

// Should render without crashing
expect(document.body).toBeDefined();
});

it('navigates to a state and renders the component', async () => {
const { container } = render(
<UIRouter plugins={[memoryLocationPlugin]} states={states}>
<div>
<nav>
<UISref to="home">
<a data-testid="home-link">Home</a>
</UISref>
<UISref to="about">
<a data-testid="about-link">About</a>
</UISref>
</nav>
<UIView />
</div>
</UIRouter>
);

// Click home link
screen.getByTestId('home-link').click();

await waitFor(() => {
expect(screen.getByTestId('home')).toBeDefined();
});
});

it('UISref generates correct href', async () => {
render(
<UIRouter plugins={[memoryLocationPlugin]} states={states}>
<UISref to="about">
<a data-testid="link">About</a>
</UISref>
</UIRouter>
);

await waitFor(() => {
const link = screen.getByTestId('link');
expect(link.getAttribute('href')).toContain('/about');
});
});
});
23 changes: 23 additions & 0 deletions integration/react18/e2e/sanity.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { test, expect } from '@playwright/test';

test.describe('UI-Router React 18 Sample App', () => {
test('loads and navigates between states', async ({ page }) => {
await page.goto('/');

// Should have navigation links
await expect(page.getByTestId('home-link')).toBeVisible();
await expect(page.getByTestId('about-link')).toBeVisible();

// Navigate to home
await page.getByTestId('home-link').click();
await expect(page.getByTestId('home-title')).toHaveText('Home Page');

// Navigate to about
await page.getByTestId('about-link').click();
await expect(page.getByTestId('about-title')).toHaveText('About Page');

// Navigate back to home
await page.getByTestId('home-link').click();
await expect(page.getByTestId('home-title')).toHaveText('Home Page');
});
});
12 changes: 12 additions & 0 deletions integration/react18/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>UI-Router React 18 Sample App</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
27 changes: 27 additions & 0 deletions integration/react18/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "integration-test-react18",
"version": "1.0.0",
"private": true,
"description": "Integration tests for @uirouter/react with React 18",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"test": "vitest run && npm run build && npx playwright install chromium && npx playwright test"
},
"dependencies": {
"react": "^18.3.1",
"react-dom": "^18.3.1"
},
"devDependencies": {
"@playwright/test": "^1.49.1",
"@testing-library/react": "^14.3.1",
"@types/react": "^18.3.18",
"@types/react-dom": "^18.3.5",
"@vitejs/plugin-react": "^4.3.4",
"jsdom": "^27.4.0",
"typescript": "^5.9.3",
"vite": "^6.0.7",
"vitest": "^4.0.16"
}
}
Loading