wip
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
||||
import type { StepHarness } from '../support/StepHarness';
|
||||
import { createStepHarness } from '../support/StepHarness';
|
||||
import { IRACING_SELECTORS } from 'packages/infrastructure/adapters/automation/dom/IRacingSelectors';
|
||||
|
||||
describe('Step 2 – create race', () => {
|
||||
let harness: StepHarness;
|
||||
@@ -13,20 +14,37 @@ describe('Step 2 – create race', () => {
|
||||
await harness.dispose();
|
||||
});
|
||||
|
||||
it('clicks Create a Race on Hosted Racing page', async () => {
|
||||
await harness.navigateToFixtureStep(1);
|
||||
it('opens the real Create Race confirmation modal with Last Settings / New Race options', async () => {
|
||||
await harness.navigateToFixtureStep(2);
|
||||
const page = harness.adapter.getPage();
|
||||
expect(page).not.toBeNull();
|
||||
|
||||
|
||||
const bodyTextBefore = await page!.textContent('body');
|
||||
expect(bodyTextBefore).toContain('Create a Race');
|
||||
|
||||
|
||||
const result = await harness.executeStep(2, {});
|
||||
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.error).toBeUndefined();
|
||||
|
||||
const bodyTextAfter = await page!.textContent('body');
|
||||
expect(bodyTextAfter).toMatch(/Last Settings/i);
|
||||
|
||||
await page!.waitForSelector(
|
||||
IRACING_SELECTORS.hostedRacing.createRaceModal,
|
||||
);
|
||||
|
||||
const modalText = await page!.textContent(
|
||||
IRACING_SELECTORS.hostedRacing.createRaceModal,
|
||||
);
|
||||
expect(modalText).toMatch(/Last Settings/i);
|
||||
expect(modalText).toMatch(/New Race/i);
|
||||
|
||||
const lastSettingsButton = await page!.$(
|
||||
IRACING_SELECTORS.hostedRacing.lastSettingsButton,
|
||||
);
|
||||
const newRaceButton = await page!.$(
|
||||
IRACING_SELECTORS.hostedRacing.newRaceButton,
|
||||
);
|
||||
|
||||
expect(lastSettingsButton).not.toBeNull();
|
||||
expect(newRaceButton).not.toBeNull();
|
||||
});
|
||||
});
|
||||
@@ -1,6 +1,7 @@
|
||||
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
||||
import type { StepHarness } from '../support/StepHarness';
|
||||
import { createStepHarness } from '../support/StepHarness';
|
||||
import { IRACING_SELECTORS } from 'packages/infrastructure/adapters/automation/dom/IRacingSelectors';
|
||||
|
||||
describe('Step 3 – race information', () => {
|
||||
let harness: StepHarness;
|
||||
@@ -13,26 +14,46 @@ describe('Step 3 – race information', () => {
|
||||
await harness.dispose();
|
||||
});
|
||||
|
||||
it('fills race information on Race Information page', async () => {
|
||||
it('fills race information on Race Information page and persists values in form fields', async () => {
|
||||
await harness.navigateToFixtureStep(3);
|
||||
|
||||
|
||||
const page = harness.adapter.getPage();
|
||||
expect(page).not.toBeNull();
|
||||
|
||||
|
||||
const sidebarRaceInfo = await page!.textContent(
|
||||
'#wizard-sidebar-link-set-session-information',
|
||||
);
|
||||
expect(sidebarRaceInfo).toContain('Race Information');
|
||||
|
||||
const result = await harness.executeStep(3, {
|
||||
|
||||
const config = {
|
||||
sessionName: 'GridPilot E2E Session',
|
||||
password: 'secret',
|
||||
description: 'Step 3 race information E2E',
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
const result = await harness.executeStep(3, config);
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.error).toBeUndefined();
|
||||
|
||||
|
||||
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();
|
||||
|
||||
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);
|
||||
|
||||
const footerText = await page!.textContent('.wizard-footer');
|
||||
expect(footerText).toMatch(/Server Details|Admins/i);
|
||||
});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
||||
import type { StepHarness } from '../support/StepHarness';
|
||||
import { createStepHarness } from '../support/StepHarness';
|
||||
import { IRACING_SELECTORS } from 'packages/infrastructure/adapters/automation/dom/IRacingSelectors';
|
||||
|
||||
describe('Step 4 – server details', () => {
|
||||
let harness: StepHarness;
|
||||
@@ -13,22 +14,41 @@ describe('Step 4 – server details', () => {
|
||||
await harness.dispose();
|
||||
});
|
||||
|
||||
it('executes on Server Details page and progresses toward Admins', async () => {
|
||||
it('executes on Server Details page, applies region/start toggle, and progresses toward Admins', async () => {
|
||||
await harness.navigateToFixtureStep(4);
|
||||
|
||||
|
||||
const page = harness.adapter.getPage();
|
||||
expect(page).not.toBeNull();
|
||||
|
||||
|
||||
const sidebarServerDetails = await page!.textContent(
|
||||
'#wizard-sidebar-link-set-server-details',
|
||||
);
|
||||
expect(sidebarServerDetails).toContain('Server Details');
|
||||
|
||||
const result = await harness.executeStep(4, {});
|
||||
|
||||
|
||||
const config = {
|
||||
region: 'US-East-OH',
|
||||
startNow: true,
|
||||
};
|
||||
|
||||
const result = await harness.executeStep(4, config);
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.error).toBeUndefined();
|
||||
|
||||
|
||||
const currentServerHeader = await page!
|
||||
.locator('#set-server-details button:has-text("Current Server")')
|
||||
.first()
|
||||
.innerText();
|
||||
expect(currentServerHeader.toLowerCase()).toContain('us-east');
|
||||
|
||||
const startToggle = page!
|
||||
.locator(IRACING_SELECTORS.steps.startNow)
|
||||
.first();
|
||||
const startNowChecked =
|
||||
(await startToggle.getAttribute('checked')) !== null ||
|
||||
(await startToggle.getAttribute('aria-checked')) === 'true';
|
||||
expect(startNowChecked).toBe(true);
|
||||
|
||||
const footerText = await page!.textContent('.wizard-footer');
|
||||
expect(footerText).toMatch(/Admins/i);
|
||||
});
|
||||
|
||||
@@ -13,25 +13,31 @@ describe('Step 5 – set admins', () => {
|
||||
await harness.dispose();
|
||||
});
|
||||
|
||||
it('executes on Set Admins page and progresses to Time Limit', async () => {
|
||||
it('executes on Set Admins page and leaves at least one admin in the selected admins table when progressing to Time Limit', async () => {
|
||||
await harness.navigateToFixtureStep(5);
|
||||
|
||||
|
||||
const page = harness.adapter.getPage();
|
||||
expect(page).not.toBeNull();
|
||||
|
||||
|
||||
const sidebarAdmins = await page!.textContent(
|
||||
'#wizard-sidebar-link-set-admins',
|
||||
);
|
||||
expect(sidebarAdmins).toContain('Admins');
|
||||
|
||||
|
||||
const bodyText = await page!.textContent('body');
|
||||
expect(bodyText).toContain('Add an Admin');
|
||||
|
||||
|
||||
const result = await harness.executeStep(5, {});
|
||||
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.error).toBeUndefined();
|
||||
|
||||
|
||||
const selectedAdminsText =
|
||||
(await page!.textContent(
|
||||
'#set-admins tbody[data-testid="admin-display-name-list"]',
|
||||
)) ?? '';
|
||||
expect(selectedAdminsText.trim()).not.toEqual('');
|
||||
|
||||
const footerText = await page!.textContent('.wizard-footer');
|
||||
expect(footerText).toContain('Time Limit');
|
||||
});
|
||||
|
||||
@@ -13,7 +13,7 @@ describe('Step 6 – admins', () => {
|
||||
await harness.dispose();
|
||||
});
|
||||
|
||||
it('completes successfully from Set Admins page', async () => {
|
||||
it('completes successfully from Set Admins page and leaves selected admins populated', async () => {
|
||||
await harness.navigateToFixtureStep(5);
|
||||
const page = harness.adapter.getPage();
|
||||
expect(page).not.toBeNull();
|
||||
@@ -27,11 +27,17 @@ describe('Step 6 – admins', () => {
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
|
||||
const selectedAdminsText =
|
||||
(await page!.textContent(
|
||||
'#set-admins tbody[data-testid="admin-display-name-list"]',
|
||||
)) ?? '';
|
||||
expect(selectedAdminsText.trim()).not.toEqual('');
|
||||
|
||||
const footerText = await page!.textContent('.wizard-footer');
|
||||
expect(footerText).toContain('Time Limit');
|
||||
});
|
||||
|
||||
it('handles Add Admin drawer state without regression', async () => {
|
||||
it('handles Add Admin drawer state without regression and preserves selected admins list', async () => {
|
||||
await harness.navigateToFixtureStep(6);
|
||||
const page = harness.adapter.getPage();
|
||||
expect(page).not.toBeNull();
|
||||
@@ -45,6 +51,12 @@ describe('Step 6 – admins', () => {
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
|
||||
const selectedAdminsText =
|
||||
(await page!.textContent(
|
||||
'#set-admins tbody[data-testid="admin-display-name-list"]',
|
||||
)) ?? '';
|
||||
expect(selectedAdminsText.trim()).not.toEqual('');
|
||||
|
||||
const footerText = await page!.textContent('.wizard-footer');
|
||||
expect(footerText).toContain('Time Limit');
|
||||
});
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
||||
import type { StepHarness } from '../support/StepHarness';
|
||||
import { createStepHarness } from '../support/StepHarness';
|
||||
|
||||
import { IRACING_SELECTORS } from 'packages/infrastructure/adapters/automation/dom/IRacingSelectors';
|
||||
|
||||
describe('Step 7 – time limits', () => {
|
||||
let harness: StepHarness;
|
||||
|
||||
@@ -13,24 +14,36 @@ describe('Step 7 – time limits', () => {
|
||||
await harness.dispose();
|
||||
});
|
||||
|
||||
it('executes on Time Limits page and navigates to Cars', async () => {
|
||||
it('executes on Time Limits page, applies sliders, and navigates to Cars', async () => {
|
||||
await harness.navigateToFixtureStep(7);
|
||||
const page = harness.adapter.getPage();
|
||||
expect(page).not.toBeNull();
|
||||
|
||||
const stepIndicatorBefore = await page!.textContent('[data-indicator]');
|
||||
expect(stepIndicatorBefore).toContain('Time Limits');
|
||||
|
||||
|
||||
const timeLimitContainer = page!
|
||||
.locator(IRACING_SELECTORS.wizard.stepContainers.timeLimit)
|
||||
.first();
|
||||
expect(await timeLimitContainer.count()).toBeGreaterThan(0);
|
||||
|
||||
const result = await harness.executeStep(7, {
|
||||
practice: 10,
|
||||
qualify: 10,
|
||||
race: 20,
|
||||
});
|
||||
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.error).toBeUndefined();
|
||||
|
||||
const stepIndicatorAfter = await page!.textContent('[data-indicator]');
|
||||
expect(stepIndicatorAfter).toContain('Set Cars');
|
||||
|
||||
const raceSlider = page!
|
||||
.locator(IRACING_SELECTORS.steps.race)
|
||||
.first();
|
||||
const raceSliderExists = await raceSlider.count();
|
||||
expect(raceSliderExists).toBeGreaterThan(0);
|
||||
const raceValueAttr =
|
||||
(await raceSlider.getAttribute('data-value')) ??
|
||||
(await raceSlider.inputValue().catch(() => null));
|
||||
expect(raceValueAttr).toBe('20');
|
||||
|
||||
const footerText = await page!.textContent('.wizard-footer');
|
||||
expect(footerText).toMatch(/Cars/i);
|
||||
});
|
||||
});
|
||||
@@ -1,7 +1,8 @@
|
||||
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
||||
import type { StepHarness } from '../support/StepHarness';
|
||||
import { createStepHarness } from '../support/StepHarness';
|
||||
|
||||
import { IRACING_SELECTORS } from 'packages/infrastructure/adapters/automation/dom/IRacingSelectors';
|
||||
|
||||
describe('Step 8 – cars', () => {
|
||||
let harness: StepHarness;
|
||||
|
||||
@@ -14,17 +15,25 @@ describe('Step 8 – cars', () => {
|
||||
});
|
||||
|
||||
describe('alignment', () => {
|
||||
it('executes on Cars page in mock wizard', async () => {
|
||||
it('executes on Cars page in mock wizard and exposes Add Car UI', async () => {
|
||||
await harness.navigateToFixtureStep(8);
|
||||
|
||||
|
||||
const page = harness.adapter.getPage();
|
||||
expect(page).not.toBeNull();
|
||||
|
||||
const stepIndicatorBefore = await page!.textContent('[data-indicator]');
|
||||
expect(stepIndicatorBefore).toContain('Set Cars');
|
||||
|
||||
|
||||
const carsContainer = page!
|
||||
.locator(IRACING_SELECTORS.wizard.stepContainers.cars)
|
||||
.first();
|
||||
expect(await carsContainer.count()).toBeGreaterThan(0);
|
||||
|
||||
const addCarButton = page!
|
||||
.locator(IRACING_SELECTORS.steps.addCarButton)
|
||||
.first();
|
||||
const addCarText = await addCarButton.innerText();
|
||||
expect(addCarText.toLowerCase()).toContain('add a car');
|
||||
|
||||
const result = await harness.executeStep(8, {});
|
||||
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.error).toBeUndefined();
|
||||
});
|
||||
|
||||
@@ -14,21 +14,28 @@ describe('Step 9 – add car', () => {
|
||||
});
|
||||
|
||||
describe('happy path', () => {
|
||||
it('executes on Add Car modal from Cars step', async () => {
|
||||
await harness.navigateToFixtureStep(9);
|
||||
it('adds a real car using the JSON-backed car list on Cars page', async () => {
|
||||
await harness.navigateToFixtureStep(8);
|
||||
await harness.adapter.getPage()?.waitForLoadState('domcontentloaded');
|
||||
|
||||
const page = harness.adapter.getPage();
|
||||
expect(page).not.toBeNull();
|
||||
|
||||
const modalTitleBefore = await page!.textContent('[data-indicator="add-car"]');
|
||||
expect(modalTitleBefore).toContain('Add a Car');
|
||||
|
||||
const result = await harness.executeStep(9, {
|
||||
carSearch: 'Porsche 911 GT3 R',
|
||||
carSearch: 'Acura ARX-06',
|
||||
});
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.error).toBeUndefined();
|
||||
|
||||
const carsTable = page!
|
||||
.locator('#select-car-set-cars table.table.table-striped')
|
||||
.first();
|
||||
|
||||
expect(await carsTable.count()).toBeGreaterThan(0);
|
||||
|
||||
const acuraCell = carsTable.locator('tbody tr td >> text=Acura ARX-06 GTP');
|
||||
expect(await acuraCell.count()).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -52,7 +59,7 @@ describe('Step 9 – add car', () => {
|
||||
await harness.executeStep(9, {
|
||||
carSearch: 'Porsche 911',
|
||||
});
|
||||
}).rejects.toThrow(/Expected cars step/i);
|
||||
}).rejects.toThrow(/Step 9 FAILED validation/i);
|
||||
});
|
||||
|
||||
it('detects when Track container is present instead of Cars page', async () => {
|
||||
@@ -63,7 +70,7 @@ describe('Step 9 – add car', () => {
|
||||
await harness.executeStep(9, {
|
||||
carSearch: 'Ferrari 488',
|
||||
});
|
||||
}).rejects.toThrow(/3 steps ahead|Track page/i);
|
||||
}).rejects.toThrow(/Step 9 FAILED validation/i);
|
||||
});
|
||||
|
||||
it('passes validation when on Cars page', async () => {
|
||||
@@ -71,10 +78,22 @@ describe('Step 9 – add car', () => {
|
||||
await harness.adapter.getPage()?.waitForLoadState('domcontentloaded');
|
||||
|
||||
const result = await harness.executeStep(9, {
|
||||
carSearch: 'Mazda MX-5',
|
||||
carSearch: 'Acura ARX-06',
|
||||
});
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
|
||||
const page = harness.adapter.getPage();
|
||||
expect(page).not.toBeNull();
|
||||
|
||||
const carsTable = page!
|
||||
.locator('#select-car-set-cars table.table.table-striped')
|
||||
.first();
|
||||
|
||||
expect(await carsTable.count()).toBeGreaterThan(0);
|
||||
|
||||
const acuraCell = carsTable.locator('tbody tr td >> text=Acura ARX-06 GTP');
|
||||
expect(await acuraCell.count()).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('provides detailed error context in validation failure', async () => {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
||||
import type { StepHarness } from '../support/StepHarness';
|
||||
import { createStepHarness } from '../support/StepHarness';
|
||||
import { IRACING_SELECTORS } from 'packages/infrastructure/adapters/automation/dom/IRacingSelectors';
|
||||
|
||||
describe('Step 14 – time of day', () => {
|
||||
let harness: StepHarness;
|
||||
@@ -13,22 +14,40 @@ describe('Step 14 – time of day', () => {
|
||||
await harness.dispose();
|
||||
});
|
||||
|
||||
it('executes on Time of Day page in mock wizard', async () => {
|
||||
it('executes on Time of Day page and applies time-of-day slider from config', async () => {
|
||||
await harness.navigateToFixtureStep(14);
|
||||
|
||||
const page = harness.adapter.getPage();
|
||||
expect(page).not.toBeNull();
|
||||
|
||||
const container = page!
|
||||
.locator(IRACING_SELECTORS.wizard.stepContainers.timeOfDay)
|
||||
.first();
|
||||
expect(await container.count()).toBeGreaterThan(0);
|
||||
|
||||
const sidebarTimeOfDay = await page!.textContent(
|
||||
'#wizard-sidebar-link-set-time-of-day',
|
||||
);
|
||||
expect(sidebarTimeOfDay).toContain('Time of Day');
|
||||
|
||||
const result = await harness.executeStep(14, {});
|
||||
const config = { timeOfDay: 800 };
|
||||
|
||||
const result = await harness.executeStep(14, config);
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.error).toBeUndefined();
|
||||
|
||||
const timeSlider = page!
|
||||
.locator(IRACING_SELECTORS.steps.timeOfDay)
|
||||
.first();
|
||||
const sliderExists = await timeSlider.count();
|
||||
expect(sliderExists).toBeGreaterThan(0);
|
||||
|
||||
const valueAttr =
|
||||
(await timeSlider.getAttribute('data-value')) ??
|
||||
(await timeSlider.inputValue().catch(() => null));
|
||||
expect(valueAttr).toBe(String(config.timeOfDay));
|
||||
|
||||
const footerText = await page!.textContent('.wizard-footer');
|
||||
expect(footerText).toMatch(/Weather/i);
|
||||
});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
||||
import type { StepHarness } from '../support/StepHarness';
|
||||
import { createStepHarness } from '../support/StepHarness';
|
||||
import { IRACING_SELECTORS } from 'packages/infrastructure/adapters/automation/dom/IRacingSelectors';
|
||||
|
||||
describe('Step 15 – weather', () => {
|
||||
let harness: StepHarness;
|
||||
@@ -13,7 +14,7 @@ describe('Step 15 – weather', () => {
|
||||
await harness.dispose();
|
||||
});
|
||||
|
||||
it('executes on Weather page in mock wizard', async () => {
|
||||
it('executes on Weather page in mock wizard and applies weather config from JSON-backed controls', async () => {
|
||||
await harness.navigateToFixtureStep(15);
|
||||
|
||||
const page = harness.adapter.getPage();
|
||||
@@ -27,9 +28,44 @@ describe('Step 15 – weather', () => {
|
||||
const bodyText = await page!.textContent('body');
|
||||
expect(bodyText).toMatch(/Weather Mode|Event weather/i);
|
||||
|
||||
const result = await harness.executeStep(15, { timeOfDay: 800 });
|
||||
const config = {
|
||||
weatherType: '2',
|
||||
temperature: 650,
|
||||
};
|
||||
|
||||
const result = await harness.executeStep(15, config);
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.error).toBeUndefined();
|
||||
|
||||
const weatherSelect = page!
|
||||
.locator(IRACING_SELECTORS.steps.weatherType)
|
||||
.first();
|
||||
const weatherSelectCount = await weatherSelect.count();
|
||||
|
||||
if (weatherSelectCount > 0) {
|
||||
const selectedWeatherValue =
|
||||
(await weatherSelect.getAttribute('value')) ??
|
||||
(await weatherSelect.textContent().catch(() => null));
|
||||
expect(
|
||||
(selectedWeatherValue ?? '').toLowerCase(),
|
||||
).toMatch(/static|forecast|timeline|2/);
|
||||
} else {
|
||||
const radioGroup = page!.locator('[role="radiogroup"] input[type="radio"]').first();
|
||||
const radioCount = await radioGroup.count();
|
||||
expect(radioCount).toBeGreaterThan(0);
|
||||
}
|
||||
|
||||
const tempSlider = page!
|
||||
.locator(IRACING_SELECTORS.steps.temperature)
|
||||
.first();
|
||||
const tempExists = await tempSlider.count();
|
||||
|
||||
if (tempExists > 0) {
|
||||
const tempValue =
|
||||
(await tempSlider.getAttribute('data-value')) ??
|
||||
(await tempSlider.inputValue().catch(() => null));
|
||||
expect(tempValue).toBe(String(config.temperature));
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -13,7 +13,7 @@ describe('Step 18 – track conditions (manual stop)', () => {
|
||||
await harness.dispose();
|
||||
});
|
||||
|
||||
it('does not automate Track Conditions and surfaces unknown-step result', async () => {
|
||||
it('treats Track Conditions as manual stop without invoking automation step 18', async () => {
|
||||
await harness.navigateToFixtureStep(18);
|
||||
|
||||
const page = harness.adapter.getPage();
|
||||
@@ -24,9 +24,10 @@ describe('Step 18 – track conditions (manual stop)', () => {
|
||||
);
|
||||
expect(sidebarTrackConditions).toContain('Track Conditions');
|
||||
|
||||
const result = await harness.executeStep(18, {});
|
||||
const trackConditionsContainer = page!.locator('#set-track-conditions').first();
|
||||
expect(await trackConditionsContainer.count()).toBeGreaterThan(0);
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error).toContain('Unknown step: 18');
|
||||
const bodyText = await page!.textContent('body');
|
||||
expect(bodyText).toMatch(/Track Conditions|Starting Track State/i);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user