wip
This commit is contained in:
162
tests/e2e/hosted-real/step-03-race-information.real.e2e.test.ts
Normal file
162
tests/e2e/hosted-real/step-03-race-information.real.e2e.test.ts
Normal file
@@ -0,0 +1,162 @@
|
||||
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
|
||||
import { promises as fs } from 'fs';
|
||||
import path from 'path';
|
||||
import { StepId } from 'packages/domain/value-objects/StepId';
|
||||
import {
|
||||
PlaywrightAutomationAdapter,
|
||||
} from 'packages/infrastructure/adapters/automation';
|
||||
import {
|
||||
IRACING_SELECTORS,
|
||||
IRACING_TIMEOUTS,
|
||||
} from 'packages/infrastructure/adapters/automation/dom/IRacingSelectors';
|
||||
import { PinoLogAdapter } from 'packages/infrastructure/adapters/logging/PinoLogAdapter';
|
||||
|
||||
const shouldRun = process.env.HOSTED_REAL_E2E === '1';
|
||||
const describeMaybe = shouldRun ? describe : describe.skip;
|
||||
|
||||
describeMaybe('Real-site hosted session – Race Information step (members.iracing.com)', () => {
|
||||
let adapter: PlaywrightAutomationAdapter;
|
||||
|
||||
beforeAll(async () => {
|
||||
const logger = new PinoLogAdapter();
|
||||
|
||||
adapter = new PlaywrightAutomationAdapter(
|
||||
{
|
||||
headless: true,
|
||||
timeout: IRACING_TIMEOUTS.navigation,
|
||||
mode: 'real',
|
||||
baseUrl: '',
|
||||
userDataDir: '',
|
||||
},
|
||||
logger,
|
||||
);
|
||||
|
||||
const result = await adapter.connect(false);
|
||||
expect(result.success).toBe(true);
|
||||
expect(adapter.isConnected()).toBe(true);
|
||||
|
||||
const step1Result = await adapter.executeStep(StepId.create(1), {});
|
||||
expect(step1Result.success).toBe(true);
|
||||
|
||||
const step2Result = await adapter.executeStep(StepId.create(2), {});
|
||||
expect(step2Result.success).toBe(true);
|
||||
|
||||
const page = adapter.getPage();
|
||||
expect(page).not.toBeNull();
|
||||
|
||||
const createRaceButton = page!
|
||||
.locator(IRACING_SELECTORS.hostedRacing.createRaceButton)
|
||||
.first();
|
||||
await expect(
|
||||
createRaceButton.count(),
|
||||
'Create Race button should exist on Hosted Racing page',
|
||||
).resolves.toBeGreaterThan(0);
|
||||
|
||||
await createRaceButton.click({ timeout: IRACING_TIMEOUTS.elementWait });
|
||||
|
||||
const raceInfoContainer = page!
|
||||
.locator(IRACING_SELECTORS.wizard.stepContainers.raceInformation)
|
||||
.first();
|
||||
await raceInfoContainer.waitFor({
|
||||
state: 'attached',
|
||||
timeout: IRACING_TIMEOUTS.elementWait,
|
||||
});
|
||||
expect(await raceInfoContainer.count()).toBeGreaterThan(0);
|
||||
}, 300_000);
|
||||
|
||||
afterAll(async () => {
|
||||
if (adapter) {
|
||||
await adapter.disconnect();
|
||||
}
|
||||
});
|
||||
|
||||
it(
|
||||
'shows Race Information sidebar text matching fixtures and keeps text inputs writable',
|
||||
async () => {
|
||||
const page = adapter.getPage();
|
||||
expect(page).not.toBeNull();
|
||||
|
||||
const sidebarLink = page!
|
||||
.locator(IRACING_SELECTORS.wizard.sidebarLinks.raceInformation)
|
||||
.first();
|
||||
await sidebarLink.waitFor({
|
||||
state: 'attached',
|
||||
timeout: IRACING_TIMEOUTS.elementWait,
|
||||
});
|
||||
const sidebarText = (await sidebarLink.innerText()).trim();
|
||||
expect(sidebarText.length).toBeGreaterThan(0);
|
||||
|
||||
let fixtureSidebarText: string | null = null;
|
||||
try {
|
||||
const fixturePath = path.join(
|
||||
process.cwd(),
|
||||
'html-dumps-optimized',
|
||||
'iracing-hosted-sessions',
|
||||
'03-race-information.json',
|
||||
);
|
||||
const raw = await fs.readFile(fixturePath, 'utf8');
|
||||
const items = JSON.parse(raw) as any[];
|
||||
const sidebarItem =
|
||||
items.find(
|
||||
(i) =>
|
||||
i.i === 'wizard-sidebar-link-set-session-information' &&
|
||||
typeof i.t === 'string',
|
||||
) ?? null;
|
||||
if (sidebarItem) {
|
||||
fixtureSidebarText = sidebarItem.t as string;
|
||||
}
|
||||
} catch {
|
||||
fixtureSidebarText = null;
|
||||
}
|
||||
|
||||
if (fixtureSidebarText) {
|
||||
const expected = fixtureSidebarText.toLowerCase();
|
||||
const actual = sidebarText.toLowerCase();
|
||||
expect(
|
||||
actual.includes('race') || actual.includes(expected.slice(0, 4)),
|
||||
).toBe(true);
|
||||
}
|
||||
|
||||
const config = {
|
||||
sessionName: 'GridPilot Real – Race Information',
|
||||
password: 'real-site-secret',
|
||||
description: 'Real-site Race Information writable fields check',
|
||||
};
|
||||
|
||||
const result = await adapter.executeStep(StepId.create(3), config);
|
||||
expect(result.success).toBe(true);
|
||||
|
||||
const sessionNameInput = page!
|
||||
.locator(IRACING_SELECTORS.steps.sessionName)
|
||||
.first();
|
||||
const passwordInput = page!
|
||||
.locator(IRACING_SELECTORS.steps.password)
|
||||
.first();
|
||||
const descriptionInput = page!
|
||||
.locator(IRACING_SELECTORS.steps.description)
|
||||
.first();
|
||||
|
||||
await sessionNameInput.waitFor({
|
||||
state: 'attached',
|
||||
timeout: IRACING_TIMEOUTS.elementWait,
|
||||
});
|
||||
await passwordInput.waitFor({
|
||||
state: 'attached',
|
||||
timeout: IRACING_TIMEOUTS.elementWait,
|
||||
});
|
||||
await descriptionInput.waitFor({
|
||||
state: 'attached',
|
||||
timeout: IRACING_TIMEOUTS.elementWait,
|
||||
});
|
||||
|
||||
const sessionNameValue = await sessionNameInput.inputValue();
|
||||
const passwordValue = await passwordInput.inputValue();
|
||||
const descriptionValue = await descriptionInput.inputValue();
|
||||
|
||||
expect(sessionNameValue).toBe(config.sessionName);
|
||||
expect(passwordValue).toBe(config.password);
|
||||
expect(descriptionValue).toBe(config.description);
|
||||
},
|
||||
300_000,
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user