mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-01-30 06:12:03 +00:00
test: update project view tests for dashboard integration
- Modified tests to navigate directly to the dashboard instead of the welcome view, ensuring a smoother project selection process. - Updated project name verification to check against the sidebar button instead of multiple elements. - Added logic to expand the sidebar if collapsed, improving visibility for project names during tests. - Adjusted test assertions to reflect changes in the UI structure, including the introduction of the dashboard view.
This commit is contained in:
@@ -123,8 +123,17 @@ test.describe('Feature Manual Review Flow', () => {
|
||||
await waitForNetworkIdle(page);
|
||||
await expect(page.locator('[data-testid="board-view"]')).toBeVisible({ timeout: 10000 });
|
||||
|
||||
// Verify we're on the correct project
|
||||
await expect(page.getByText(projectName).first()).toBeVisible({ timeout: 10000 });
|
||||
// Expand sidebar if collapsed to see project name
|
||||
const expandSidebarButton = page.locator('button:has-text("Expand sidebar")');
|
||||
if (await expandSidebarButton.isVisible()) {
|
||||
await expandSidebarButton.click();
|
||||
await page.waitForTimeout(300);
|
||||
}
|
||||
|
||||
// Verify we're on the correct project (project name appears in sidebar button)
|
||||
await expect(page.getByRole('button', { name: new RegExp(projectName) })).toBeVisible({
|
||||
timeout: 10000,
|
||||
});
|
||||
|
||||
// Create the feature via HTTP API (writes to disk)
|
||||
const feature = {
|
||||
|
||||
@@ -122,9 +122,7 @@ test.describe('Board Background Persistence', () => {
|
||||
],
|
||||
});
|
||||
|
||||
await authenticateForTests(page);
|
||||
|
||||
// Intercept settings API to use our test projects and clear currentProjectId
|
||||
// Intercept settings API BEFORE authenticateForTests (which navigates to the page)
|
||||
// This ensures the app shows the welcome view with our test projects
|
||||
await page.route('**/api/settings/global', async (route) => {
|
||||
const response = await route.fetch();
|
||||
@@ -151,6 +149,8 @@ test.describe('Board Background Persistence', () => {
|
||||
await route.fulfill({ response, json });
|
||||
});
|
||||
|
||||
await authenticateForTests(page);
|
||||
|
||||
// Track API calls to /api/settings/project to verify settings are being loaded
|
||||
const settingsApiCalls: Array<{ url: string; method: string; body: string }> = [];
|
||||
page.on('request', (request) => {
|
||||
@@ -163,24 +163,31 @@ test.describe('Board Background Persistence', () => {
|
||||
}
|
||||
});
|
||||
|
||||
// Navigate to the app
|
||||
await page.goto('/');
|
||||
// Navigate directly to dashboard to avoid auto-open which would bypass the project selection
|
||||
await page.goto('/dashboard');
|
||||
await page.waitForLoadState('load');
|
||||
await handleLoginScreenIfPresent(page);
|
||||
|
||||
// Wait for welcome view
|
||||
await expect(page.locator('[data-testid="welcome-view"]')).toBeVisible({ timeout: 10000 });
|
||||
// Wait for dashboard view
|
||||
await expect(page.locator('[data-testid="dashboard-view"]')).toBeVisible({ timeout: 10000 });
|
||||
|
||||
// Open project A (has background settings)
|
||||
const projectACard = page.locator(`[data-testid="recent-project-${projectAId}"]`);
|
||||
const projectACard = page.locator(`[data-testid="project-card-${projectAId}"]`);
|
||||
await expect(projectACard).toBeVisible();
|
||||
await projectACard.click();
|
||||
|
||||
// Wait for board view
|
||||
await expect(page.locator('[data-testid="board-view"]')).toBeVisible({ timeout: 15000 });
|
||||
|
||||
// Verify project A is current (check header paragraph which is always visible)
|
||||
await expect(page.locator('[data-testid="board-view"]').getByText(projectAName)).toBeVisible({
|
||||
// Ensure sidebar is expanded before checking project name
|
||||
const expandSidebarButton = page.locator('button:has-text("Expand sidebar")');
|
||||
if (await expandSidebarButton.isVisible()) {
|
||||
await expandSidebarButton.click();
|
||||
await page.waitForTimeout(300);
|
||||
}
|
||||
|
||||
// Verify project A is current (project name appears in sidebar button)
|
||||
await expect(page.getByRole('button', { name: new RegExp(projectAName) })).toBeVisible({
|
||||
timeout: 5000,
|
||||
});
|
||||
|
||||
@@ -196,13 +203,6 @@ test.describe('Board Background Persistence', () => {
|
||||
// Wait for initial project load to stabilize
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// Ensure sidebar is expanded before interacting with project selector
|
||||
const expandSidebarButton = page.locator('button:has-text("Expand sidebar")');
|
||||
if (await expandSidebarButton.isVisible()) {
|
||||
await expandSidebarButton.click();
|
||||
await page.waitForTimeout(300);
|
||||
}
|
||||
|
||||
// Switch to project B (no background)
|
||||
const projectSelector = page.locator('[data-testid="project-selector"]');
|
||||
await expect(projectSelector).toBeVisible({ timeout: 5000 });
|
||||
|
||||
@@ -33,27 +33,29 @@ test.describe('Project Creation', () => {
|
||||
const projectName = `test-project-${Date.now()}`;
|
||||
|
||||
await setupWelcomeView(page, { workspaceDir: TEST_TEMP_DIR });
|
||||
await authenticateForTests(page);
|
||||
|
||||
// Intercept settings API to ensure it doesn't return a currentProjectId
|
||||
// This prevents settings hydration from restoring a project
|
||||
// Intercept settings API BEFORE authenticateForTests (which navigates to the page)
|
||||
// This prevents settings hydration from restoring a project and disables auto-open
|
||||
await page.route('**/api/settings/global', async (route) => {
|
||||
const response = await route.fetch();
|
||||
const json = await response.json();
|
||||
// Remove currentProjectId to prevent restoring a project
|
||||
// Remove currentProjectId and clear projects to prevent auto-open
|
||||
if (json.settings) {
|
||||
json.settings.currentProjectId = null;
|
||||
json.settings.projects = [];
|
||||
}
|
||||
await route.fulfill({ response, json });
|
||||
});
|
||||
|
||||
// Navigate to root
|
||||
await page.goto('/');
|
||||
await authenticateForTests(page);
|
||||
|
||||
// Navigate directly to dashboard to avoid auto-open logic
|
||||
await page.goto('/dashboard');
|
||||
await page.waitForLoadState('load');
|
||||
await handleLoginScreenIfPresent(page);
|
||||
|
||||
// Wait for welcome view to be visible
|
||||
await expect(page.locator('[data-testid="welcome-view"]')).toBeVisible({ timeout: 15000 });
|
||||
// Wait for dashboard view
|
||||
await expect(page.locator('[data-testid="dashboard-view"]')).toBeVisible({ timeout: 15000 });
|
||||
|
||||
await page.locator('[data-testid="create-new-project"]').click();
|
||||
await page.locator('[data-testid="quick-setup-option"]').click();
|
||||
@@ -67,10 +69,18 @@ test.describe('Project Creation', () => {
|
||||
|
||||
await expect(page.locator('[data-testid="board-view"]')).toBeVisible({ timeout: 15000 });
|
||||
|
||||
// Expand sidebar if collapsed to see project name
|
||||
const expandSidebarButton = page.locator('button:has-text("Expand sidebar")');
|
||||
if (await expandSidebarButton.isVisible()) {
|
||||
await expandSidebarButton.click();
|
||||
await page.waitForTimeout(300);
|
||||
}
|
||||
|
||||
// Wait for project to be set as current and visible on the page
|
||||
// The project name appears in multiple places: project-selector, board header paragraph, etc.
|
||||
// Check any element containing the project name
|
||||
await expect(page.getByText(projectName).first()).toBeVisible({ timeout: 15000 });
|
||||
// The project name appears in the sidebar project selector button
|
||||
await expect(page.getByRole('button', { name: new RegExp(projectName) })).toBeVisible({
|
||||
timeout: 15000,
|
||||
});
|
||||
|
||||
// Project was created successfully if we're on board view with project name visible
|
||||
// Note: The actual project directory is created in the server's default workspace,
|
||||
|
||||
@@ -113,12 +113,13 @@ test.describe('Open Project', () => {
|
||||
|
||||
// Now navigate to the app
|
||||
await authenticateForTests(page);
|
||||
await page.goto('/');
|
||||
// Navigate directly to dashboard to avoid auto-open which would bypass the project selection
|
||||
await page.goto('/dashboard');
|
||||
await page.waitForLoadState('load');
|
||||
await handleLoginScreenIfPresent(page);
|
||||
|
||||
// Wait for welcome view to be visible
|
||||
await expect(page.locator('[data-testid="welcome-view"]')).toBeVisible({ timeout: 15000 });
|
||||
// Wait for dashboard view
|
||||
await expect(page.locator('[data-testid="dashboard-view"]')).toBeVisible({ timeout: 15000 });
|
||||
|
||||
// Verify we see the "Recent Projects" section
|
||||
await expect(page.getByText('Recent Projects')).toBeVisible({ timeout: 5000 });
|
||||
@@ -135,7 +136,7 @@ test.describe('Open Project', () => {
|
||||
if (!isOurProjectVisible) {
|
||||
// Our project isn't visible - use the first available recent project card instead
|
||||
// This tests the "open recent project" flow even if our specific project didn't get injected
|
||||
const firstProjectCard = page.locator('[data-testid^="recent-project-"]').first();
|
||||
const firstProjectCard = page.locator('[data-testid^="project-card-"]').first();
|
||||
await expect(firstProjectCard).toBeVisible({ timeout: 5000 });
|
||||
// Get the project name from the card to verify later
|
||||
targetProjectName = (await firstProjectCard.locator('p').first().textContent()) || '';
|
||||
@@ -147,10 +148,19 @@ test.describe('Open Project', () => {
|
||||
// Wait for the board view to appear (project was opened)
|
||||
await expect(page.locator('[data-testid="board-view"]')).toBeVisible({ timeout: 15000 });
|
||||
|
||||
// Expand sidebar if collapsed to see project name
|
||||
const expandSidebarButton = page.locator('button:has-text("Expand sidebar")');
|
||||
if (await expandSidebarButton.isVisible()) {
|
||||
await expandSidebarButton.click();
|
||||
await page.waitForTimeout(300);
|
||||
}
|
||||
|
||||
// Wait for a project to be set as current and visible on the page
|
||||
// The project name appears in multiple places: project-selector, board header paragraph, etc.
|
||||
// The project name appears in the sidebar project selector button
|
||||
if (targetProjectName) {
|
||||
await expect(page.getByText(targetProjectName).first()).toBeVisible({ timeout: 15000 });
|
||||
await expect(page.getByRole('button', { name: new RegExp(targetProjectName) })).toBeVisible({
|
||||
timeout: 15000,
|
||||
});
|
||||
}
|
||||
|
||||
// Only verify filesystem if we opened our specific test project
|
||||
|
||||
@@ -93,7 +93,9 @@ test.describe('Settings startup sync race', () => {
|
||||
|
||||
// App should eventually render a main view after settings hydration.
|
||||
await page
|
||||
.locator('[data-testid="welcome-view"], [data-testid="board-view"]')
|
||||
.locator(
|
||||
'[data-testid="welcome-view"], [data-testid="dashboard-view"], [data-testid="board-view"]'
|
||||
)
|
||||
.first()
|
||||
.waitFor({ state: 'visible', timeout: 30000 });
|
||||
|
||||
@@ -112,7 +114,9 @@ test.describe('Settings startup sync race', () => {
|
||||
await page.waitForLoadState('load');
|
||||
await handleLoginScreenIfPresent(page);
|
||||
await page
|
||||
.locator('[data-testid="welcome-view"], [data-testid="board-view"]')
|
||||
.locator(
|
||||
'[data-testid="welcome-view"], [data-testid="dashboard-view"], [data-testid="board-view"]'
|
||||
)
|
||||
.first()
|
||||
.waitFor({ state: 'visible', timeout: 30000 });
|
||||
|
||||
|
||||
@@ -89,6 +89,7 @@ export const TEST_IDS = {
|
||||
agentView: 'agent-view',
|
||||
settingsView: 'settings-view',
|
||||
welcomeView: 'welcome-view',
|
||||
dashboardView: 'dashboard-view',
|
||||
setupView: 'setup-view',
|
||||
|
||||
// Board View Components
|
||||
|
||||
@@ -75,28 +75,44 @@ export async function handleLoginScreenIfPresent(page: Page): Promise<boolean> {
|
||||
.locator('[data-testid="login-api-key-input"], input[type="password"][placeholder*="API key"]')
|
||||
.first();
|
||||
const appContent = page.locator(
|
||||
'[data-testid="welcome-view"], [data-testid="board-view"], [data-testid="context-view"], [data-testid="agent-view"]'
|
||||
'[data-testid="welcome-view"], [data-testid="dashboard-view"], [data-testid="board-view"], [data-testid="context-view"], [data-testid="agent-view"]'
|
||||
);
|
||||
const loggedOutPage = page.getByRole('heading', { name: /logged out/i });
|
||||
const goToLoginButton = page.locator('button:has-text("Go to login")');
|
||||
|
||||
const maxWaitMs = 15000;
|
||||
|
||||
// Race between login screen, a delayed redirect to /login, and actual content
|
||||
const loginVisible = await Promise.race([
|
||||
// Race between login screen, logged-out page, a delayed redirect to /login, and actual content
|
||||
const result = await Promise.race([
|
||||
page
|
||||
.waitForURL((url) => url.pathname.includes('/login'), { timeout: maxWaitMs })
|
||||
.then(() => true)
|
||||
.catch(() => false),
|
||||
.then(() => 'login-redirect' as const)
|
||||
.catch(() => null),
|
||||
loginInput
|
||||
.waitFor({ state: 'visible', timeout: maxWaitMs })
|
||||
.then(() => true)
|
||||
.catch(() => false),
|
||||
.then(() => 'login-input' as const)
|
||||
.catch(() => null),
|
||||
loggedOutPage
|
||||
.waitFor({ state: 'visible', timeout: maxWaitMs })
|
||||
.then(() => 'logged-out' as const)
|
||||
.catch(() => null),
|
||||
appContent
|
||||
.first()
|
||||
.waitFor({ state: 'visible', timeout: maxWaitMs })
|
||||
.then(() => false)
|
||||
.catch(() => false),
|
||||
.then(() => 'app-content' as const)
|
||||
.catch(() => null),
|
||||
]);
|
||||
|
||||
// Handle logged-out page - click "Go to login" button and then login
|
||||
if (result === 'logged-out') {
|
||||
await goToLoginButton.click();
|
||||
await page.waitForLoadState('load');
|
||||
// Now handle the login screen
|
||||
return handleLoginScreenIfPresent(page);
|
||||
}
|
||||
|
||||
const loginVisible = result === 'login-redirect' || result === 'login-input';
|
||||
|
||||
if (loginVisible) {
|
||||
const apiKey = process.env.AUTOMAKER_API_KEY || 'test-api-key-for-e2e-tests';
|
||||
await loginInput.fill(apiKey);
|
||||
|
||||
@@ -152,7 +152,8 @@ export async function navigateToSetup(page: Page): Promise<void> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigate to the welcome view (clear project selection)
|
||||
* Navigate to the welcome/dashboard view (clear project selection)
|
||||
* Note: The app redirects from / to /dashboard when no project is selected
|
||||
*/
|
||||
export async function navigateToWelcome(page: Page): Promise<void> {
|
||||
// Authenticate before navigating
|
||||
@@ -167,7 +168,11 @@ export async function navigateToWelcome(page: Page): Promise<void> {
|
||||
// Handle login redirect if needed
|
||||
await handleLoginScreenIfPresent(page);
|
||||
|
||||
await waitForElement(page, 'welcome-view', { timeout: 10000 });
|
||||
// Wait for either welcome-view or dashboard-view (app redirects to /dashboard when no project)
|
||||
await page
|
||||
.locator('[data-testid="welcome-view"], [data-testid="dashboard-view"]')
|
||||
.first()
|
||||
.waitFor({ state: 'visible', timeout: 10000 });
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user