161 lines
4.9 KiB
TypeScript
161 lines
4.9 KiB
TypeScript
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
|
||
import { StepId } from '@gridpilot/automation/domain/value-objects/StepId';
|
||
import {
|
||
FixtureServer,
|
||
PlaywrightAutomationAdapter,
|
||
} from 'core/automation/infrastructure//automation';
|
||
import { IRACING_SELECTORS } from 'core/automation/infrastructure//automation/dom/IRacingSelectors';
|
||
import { PinoLogAdapter } from 'core/automation/infrastructure//logging/PinoLogAdapter';
|
||
|
||
describe('Real Playwright hosted-session smoke (fixtures, steps 2–7)', () => {
|
||
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,
|
||
);
|
||
});
|