Files
gridpilot.gg/tests/e2e/automation.e2e.test.ts
2025-12-04 11:54:42 +01:00

161 lines
4.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import { StepId } from '@gridpilot/automation/domain/value-objects/StepId';
import {
FixtureServer,
PlaywrightAutomationAdapter,
} from 'packages/automation/infrastructure/adapters/automation';
import { IRACING_SELECTORS } from 'packages/automation/infrastructure/adapters/automation/dom/IRacingSelectors';
import { PinoLogAdapter } from 'packages/automation/infrastructure/adapters/logging/PinoLogAdapter';
describe('Real Playwright hosted-session smoke (fixtures, steps 27)', () => {
let server: FixtureServer;
let adapter: PlaywrightAutomationAdapter;
let baseUrl: string;
beforeAll(async () => {
server = new FixtureServer();
const info = await server.start();
baseUrl = info.url;
const logger = new PinoLogAdapter();
adapter = new PlaywrightAutomationAdapter(
{
headless: true,
timeout: 8000,
mode: 'real',
baseUrl,
userDataDir: '',
},
logger,
);
const result = await adapter.connect(false);
expect(result.success).toBe(true);
expect(adapter.isConnected()).toBe(true);
expect(adapter.getPage()).not.toBeNull();
});
afterAll(async () => {
if (adapter) {
await adapter.disconnect();
}
if (server) {
await server.stop();
}
});
async function expectContextOpen(stepLabel: string) {
const page = adapter.getPage();
expect(page, `${stepLabel}: page should exist`).not.toBeNull();
const closed = await page!.isClosed();
expect(closed, `${stepLabel}: page should be open`).toBe(false);
expect(adapter.isConnected(), `${stepLabel}: adapter stays connected`).toBe(true);
}
async function navigateToFixtureStep(
stepNumber: number,
label: string,
stepKey?: keyof typeof IRACING_SELECTORS.wizard.stepContainers,
) {
const page = adapter.getPage();
expect(page).not.toBeNull();
await adapter.navigateToPage(server.getFixtureUrl(stepNumber));
await page!.waitForLoadState('domcontentloaded');
await expectContextOpen(`after navigate step ${stepNumber} (${label})`);
if (stepKey) {
const selector = IRACING_SELECTORS.wizard.stepContainers[stepKey];
const container = page!.locator(selector).first();
const count = await container.count();
expect(
count,
`${label}: expected container ${selector} to exist on fixture HTML`,
).toBeGreaterThan(0);
}
}
it(
'keeps browser context open and reaches Time Limits using real adapter against fixtures',
async () => {
await navigateToFixtureStep(2, 'Create a Race');
const step2Result = await adapter.executeStep(
StepId.create(2),
{} as Record<string, unknown>,
);
expect(step2Result.success).toBe(true);
await expectContextOpen('after step 2');
await navigateToFixtureStep(3, 'Race Information', 'raceInformation');
const step3Result = await adapter.executeStep(
StepId.create(3),
{
sessionName: 'GridPilot Smoke Session',
password: 'smokepw',
description: 'Real Playwright smoke path using fixtures',
} as Record<string, unknown>,
);
expect(step3Result.success).toBe(true);
await expectContextOpen('after step 3');
await navigateToFixtureStep(4, 'Server Details', 'serverDetails');
const step4Result = await adapter.executeStep(
StepId.create(4),
{
region: 'US',
startNow: true,
} as Record<string, unknown>,
);
expect(step4Result.success).toBe(true);
await expectContextOpen('after step 4');
await navigateToFixtureStep(5, 'Set Admins', 'admins');
const step5Result = await adapter.executeStep(
StepId.create(5),
{} as Record<string, unknown>,
);
expect(step5Result.success).toBe(true);
await expectContextOpen('after step 5');
await navigateToFixtureStep(6, 'Admins drawer', 'admins');
const step6Result = await adapter.executeStep(
StepId.create(6),
{
adminSearch: 'Marc',
} as Record<string, unknown>,
);
expect(step6Result.success).toBe(true);
await expectContextOpen('after step 6');
await navigateToFixtureStep(7, 'Time Limits', 'timeLimit');
const step7Result = await adapter.executeStep(
StepId.create(7),
{
practice: 10,
qualify: 10,
race: 20,
} as Record<string, unknown>,
);
expect(step7Result.success).toBe(true);
await expectContextOpen('after step 7');
const page = adapter.getPage();
expect(page).not.toBeNull();
const footerText = await page!.textContent('.wizard-footer');
expect(footerText || '').toMatch(/Cars/i);
const overlay = await page!.$('#gridpilot-overlay');
expect(overlay, 'overlay should be present in real mode').not.toBeNull();
},
60000,
);
});