feat: improve test setup and authentication handling

- Added `dev:test` script to package.json for streamlined testing without file watching.
- Introduced `kill-test-servers` script to ensure no existing servers are running on test ports before executing tests.
- Enhanced Playwright configuration to use mock agent for tests, ensuring consistent API responses and disabling rate limiting.
- Updated various test files to include authentication steps and handle login screens, improving reliability and reducing flakiness in tests.
- Added `global-setup` for e2e tests to ensure proper initialization before test execution.
This commit is contained in:
Test User
2025-12-30 00:06:27 -05:00
parent 59a6a23f9b
commit 46caae05d2
22 changed files with 376 additions and 33 deletions

View File

@@ -1,4 +1,4 @@
import { Page } from '@playwright/test';
import { Page, expect } from '@playwright/test';
import { getByTestId, getButtonByText } from './elements';
/**
@@ -48,6 +48,72 @@ export async function pressShortcut(page: Page, key: string): Promise<void> {
await page.keyboard.press(key);
}
/**
* Navigate to a URL with authentication
* This wrapper ensures authentication happens before navigation
*/
export async function gotoWithAuth(page: Page, url: string): Promise<void> {
const { authenticateForTests } = await import('../api/client');
await authenticateForTests(page);
await page.goto(url);
}
/**
* Handle login screen if it appears after navigation
* Returns true if login was handled, false if no login screen was found
*/
export async function handleLoginScreenIfPresent(page: Page): Promise<boolean> {
// Check for login screen by waiting for either login input or app-container to be visible
// Use data-testid selector (preferred) with fallback to the old selector
const loginInput = page
.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"]'
);
// Race between login screen and actual content
const loginVisible = await Promise.race([
loginInput
.waitFor({ state: 'visible', timeout: 5000 })
.then(() => true)
.catch(() => false),
appContent
.first()
.waitFor({ state: 'visible', timeout: 5000 })
.then(() => false)
.catch(() => false),
]);
if (loginVisible) {
const apiKey = process.env.AUTOMAKER_API_KEY || 'test-api-key-for-e2e-tests';
await loginInput.fill(apiKey);
// Wait a moment for the button to become enabled
await page.waitForTimeout(100);
// Wait for button to be enabled (it's disabled when input is empty)
const loginButton = page
.locator('[data-testid="login-submit-button"], button:has-text("Login")')
.first();
await expect(loginButton).toBeEnabled({ timeout: 5000 });
await loginButton.click();
// Wait for navigation away from login - either to content or URL change
await Promise.race([
page.waitForURL((url) => !url.pathname.includes('/login'), { timeout: 10000 }),
appContent.first().waitFor({ state: 'visible', timeout: 10000 }),
]).catch(() => {});
// Wait for page to load
await page.waitForLoadState('load');
return true;
}
return false;
}
/**
* Press a number key (0-9) on the keyboard
*/