108 lines
3.7 KiB
TypeScript
108 lines
3.7 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import { PageStateValidator } from 'apps/companion/main/automation/domain/services/PageStateValidator';
|
|
import { StepTransitionValidator } from 'apps/companion/main/automation/domain/services/StepTransitionValidator';
|
|
import { StepId } from 'apps/companion/main/automation/domain/value-objects/StepId';
|
|
import { SessionState } from 'apps/companion/main/automation/domain/value-objects/SessionState';
|
|
|
|
describe('Validator conformance (integration)', () => {
|
|
describe('PageStateValidator with hosted-session selectors', () => {
|
|
it('reports missing DOM markers with descriptive message', () => {
|
|
const validator = new PageStateValidator();
|
|
|
|
const actualState = (selector: string) => {
|
|
return selector === '#set-cars';
|
|
};
|
|
|
|
const result = validator.validateState(actualState, {
|
|
expectedStep: 'track',
|
|
requiredSelectors: ['#set-track', '#track-search'],
|
|
});
|
|
|
|
expect(result.isOk()).toBe(true);
|
|
const value = result.unwrap();
|
|
expect(value.isValid).toBe(false);
|
|
expect(value.expectedStep).toBe('track');
|
|
expect(value.missingSelectors).toEqual(['#set-track', '#track-search']);
|
|
expect(value.message).toBe(
|
|
'Page state mismatch: Expected to be on "track" page but missing required elements',
|
|
);
|
|
});
|
|
|
|
it('reports unexpected DOM markers when forbidden selectors are present', () => {
|
|
const validator = new PageStateValidator();
|
|
|
|
const actualState = (selector: string) => {
|
|
return ['#set-cars', '#set-track'].includes(selector);
|
|
};
|
|
|
|
const result = validator.validateState(actualState, {
|
|
expectedStep: 'cars',
|
|
requiredSelectors: ['#set-cars'],
|
|
forbiddenSelectors: ['#set-track'],
|
|
});
|
|
|
|
expect(result.isOk()).toBe(true);
|
|
const value = result.unwrap();
|
|
expect(value.isValid).toBe(false);
|
|
expect(value.expectedStep).toBe('cars');
|
|
expect(value.unexpectedSelectors).toEqual(['#set-track']);
|
|
expect(value.message).toBe(
|
|
'Page state mismatch: Found unexpected elements on "cars" page',
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('StepTransitionValidator with hosted-session steps', () => {
|
|
it('rejects illegal forward jumps with clear error', () => {
|
|
const currentStep = StepId.create(3);
|
|
const nextStep = StepId.create(9);
|
|
const state = SessionState.create('IN_PROGRESS');
|
|
|
|
const result = StepTransitionValidator.canTransition(
|
|
currentStep,
|
|
nextStep,
|
|
state,
|
|
);
|
|
|
|
expect(result.isValid).toBe(false);
|
|
expect(result.error).toBe(
|
|
'Cannot skip steps - must progress sequentially',
|
|
);
|
|
});
|
|
|
|
it('rejects backward jumps with clear error', () => {
|
|
const currentStep = StepId.create(11);
|
|
const nextStep = StepId.create(8);
|
|
const state = SessionState.create('IN_PROGRESS');
|
|
|
|
const result = StepTransitionValidator.canTransition(
|
|
currentStep,
|
|
nextStep,
|
|
state,
|
|
);
|
|
|
|
expect(result.isValid).toBe(false);
|
|
expect(result.error).toBe(
|
|
'Cannot move backward - steps must progress forward only',
|
|
);
|
|
});
|
|
|
|
it('provides descriptive step descriptions for hosted steps', () => {
|
|
const step3 = StepTransitionValidator.getStepDescription(
|
|
StepId.create(3),
|
|
);
|
|
const step11 = StepTransitionValidator.getStepDescription(
|
|
StepId.create(11),
|
|
);
|
|
const finalStep = StepTransitionValidator.getStepDescription(
|
|
StepId.create(17),
|
|
);
|
|
|
|
expect(step3).toBe('Fill Race Information');
|
|
expect(step11).toBe('Set Track');
|
|
expect(finalStep).toBe(
|
|
'Track Conditions (STOP - Manual Submit Required)',
|
|
);
|
|
});
|
|
});
|
|
}); |