Files
automaker/apps/ui/tests/projects/open-existing-project.spec.ts
Test User 036a7d9d26 refactor: update e2e tests to use 'load' state for page navigation
- Changed instances of `waitForLoadState('networkidle')` to `waitForLoadState('load')` across multiple test files and utility functions to improve test reliability in applications with persistent connections.
- Added documentation to the e2e testing guide explaining the rationale behind using 'load' state instead of 'networkidle' to prevent timeouts and flaky tests.
2025-12-22 17:16:55 -05:00

126 lines
4.5 KiB
TypeScript

/**
* Open Project End-to-End Test
*
* Tests opening an existing project directory from the welcome view.
* This verifies that:
* 1. An existing directory can be opened as a project
* 2. The .automaker directory is initialized if it doesn't exist
* 3. The project is loaded and shown in the board view
*/
import { test, expect } from '@playwright/test';
import * as fs from 'fs';
import * as path from 'path';
import { createTempDirPath, cleanupTempDir, setupWelcomeView } from '../utils';
// Create unique temp dir for this test run
const TEST_TEMP_DIR = createTempDirPath('open-project-test');
test.describe('Open Project', () => {
test.beforeAll(async () => {
// Create test temp directory
if (!fs.existsSync(TEST_TEMP_DIR)) {
fs.mkdirSync(TEST_TEMP_DIR, { recursive: true });
}
});
test.afterAll(async () => {
// Cleanup temp directory
cleanupTempDir(TEST_TEMP_DIR);
});
test('should open an existing project directory from recent projects', async ({ page }) => {
const projectName = `existing-project-${Date.now()}`;
const projectPath = path.join(TEST_TEMP_DIR, projectName);
const projectId = `project-${Date.now()}`;
// Create the project directory with some files to simulate an existing codebase
fs.mkdirSync(projectPath, { recursive: true });
// Create a package.json to simulate a real project
fs.writeFileSync(
path.join(projectPath, 'package.json'),
JSON.stringify(
{
name: projectName,
version: '1.0.0',
description: 'A test project for e2e testing',
},
null,
2
)
);
// Create a README.md
fs.writeFileSync(path.join(projectPath, 'README.md'), `# ${projectName}\n\nA test project.`);
// Create a src directory with an index.ts file
fs.mkdirSync(path.join(projectPath, 'src'), { recursive: true });
fs.writeFileSync(
path.join(projectPath, 'src', 'index.ts'),
'export const hello = () => console.log("Hello World");'
);
// Set up welcome view with the project in recent projects (but NOT as current project)
await setupWelcomeView(page, {
recentProjects: [
{
id: projectId,
name: projectName,
path: projectPath,
lastOpened: new Date(Date.now() - 86400000).toISOString(), // 1 day ago
},
],
});
// Navigate to the app
await page.goto('/');
await page.waitForLoadState('load');
// Wait for welcome view to be visible
await expect(page.locator('[data-testid="welcome-view"]')).toBeVisible({ timeout: 10000 });
// Verify we see the "Recent Projects" section
await expect(page.getByText('Recent Projects')).toBeVisible({ timeout: 5000 });
// Click on the recent project to open it
const recentProjectCard = page.locator(`[data-testid="recent-project-${projectId}"]`);
await expect(recentProjectCard).toBeVisible();
await recentProjectCard.click();
// Wait for the board view to appear (project was opened)
await expect(page.locator('[data-testid="board-view"]')).toBeVisible({ timeout: 15000 });
// Verify the project name appears in the project selector (sidebar)
await expect(
page.locator('[data-testid="project-selector"]').getByText(projectName)
).toBeVisible({ timeout: 5000 });
// Verify .automaker directory was created (initialized for the first time)
// Use polling since file creation may be async
const automakerDir = path.join(projectPath, '.automaker');
await expect(async () => {
expect(fs.existsSync(automakerDir)).toBe(true);
}).toPass({ timeout: 10000 });
// Verify the required structure was created by initializeProject:
// - .automaker/categories.json
// - .automaker/features directory
// - .automaker/context directory
// Note: app_spec.txt is NOT created automatically for existing projects
const categoriesPath = path.join(automakerDir, 'categories.json');
await expect(async () => {
expect(fs.existsSync(categoriesPath)).toBe(true);
}).toPass({ timeout: 10000 });
// Verify subdirectories were created
expect(fs.existsSync(path.join(automakerDir, 'features'))).toBe(true);
expect(fs.existsSync(path.join(automakerDir, 'context'))).toBe(true);
// Verify the original project files still exist (weren't modified)
expect(fs.existsSync(path.join(projectPath, 'package.json'))).toBe(true);
expect(fs.existsSync(path.join(projectPath, 'README.md'))).toBe(true);
expect(fs.existsSync(path.join(projectPath, 'src', 'index.ts'))).toBe(true);
});
});