wip
This commit is contained in:
167
tests/unit/domain/services/PageStateValidator.test.ts
Normal file
167
tests/unit/domain/services/PageStateValidator.test.ts
Normal file
@@ -0,0 +1,167 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { PageStateValidator } from '../../../../packages/domain/services/PageStateValidator';
|
||||
|
||||
describe('PageStateValidator', () => {
|
||||
const validator = new PageStateValidator();
|
||||
|
||||
describe('validateState', () => {
|
||||
it('should return valid when all required selectors are present', () => {
|
||||
// Arrange
|
||||
const actualState = (selector: string) => {
|
||||
return ['#add-car-button', '#cars-list'].includes(selector);
|
||||
};
|
||||
|
||||
// Act
|
||||
const result = validator.validateState(actualState, {
|
||||
expectedStep: 'cars',
|
||||
requiredSelectors: ['#add-car-button', '#cars-list']
|
||||
});
|
||||
|
||||
// Assert
|
||||
expect(result.isOk()).toBe(true);
|
||||
const value = result.unwrap();
|
||||
expect(value.isValid).toBe(true);
|
||||
expect(value.expectedStep).toBe('cars');
|
||||
expect(value.message).toContain('Page state valid');
|
||||
});
|
||||
|
||||
it('should return invalid when required selectors are missing', () => {
|
||||
// Arrange
|
||||
const actualState = (selector: string) => {
|
||||
return selector === '#add-car-button'; // Only one of two selectors present
|
||||
};
|
||||
|
||||
// Act
|
||||
const result = validator.validateState(actualState, {
|
||||
expectedStep: 'cars',
|
||||
requiredSelectors: ['#add-car-button', '#cars-list']
|
||||
});
|
||||
|
||||
// Assert
|
||||
expect(result.isOk()).toBe(true);
|
||||
const value = result.unwrap();
|
||||
expect(value.isValid).toBe(false);
|
||||
expect(value.expectedStep).toBe('cars');
|
||||
expect(value.missingSelectors).toEqual(['#cars-list']);
|
||||
expect(value.message).toContain('missing required elements');
|
||||
});
|
||||
|
||||
it('should return invalid when forbidden selectors are present', () => {
|
||||
// Arrange
|
||||
const actualState = (selector: string) => {
|
||||
return ['#add-car-button', '#set-track'].includes(selector);
|
||||
};
|
||||
|
||||
// Act
|
||||
const result = validator.validateState(actualState, {
|
||||
expectedStep: 'cars',
|
||||
requiredSelectors: ['#add-car-button'],
|
||||
forbiddenSelectors: ['#set-track'] // Should NOT be on track page yet
|
||||
});
|
||||
|
||||
// Assert
|
||||
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).toContain('unexpected elements');
|
||||
});
|
||||
|
||||
it('should handle empty forbidden selectors array', () => {
|
||||
// Arrange
|
||||
const actualState = (selector: string) => {
|
||||
return selector === '#add-car-button';
|
||||
};
|
||||
|
||||
// Act
|
||||
const result = validator.validateState(actualState, {
|
||||
expectedStep: 'cars',
|
||||
requiredSelectors: ['#add-car-button'],
|
||||
forbiddenSelectors: []
|
||||
});
|
||||
|
||||
// Assert
|
||||
expect(result.isOk()).toBe(true);
|
||||
const value = result.unwrap();
|
||||
expect(value.isValid).toBe(true);
|
||||
});
|
||||
|
||||
it('should handle undefined forbidden selectors', () => {
|
||||
// Arrange
|
||||
const actualState = (selector: string) => {
|
||||
return selector === '#add-car-button';
|
||||
};
|
||||
|
||||
// Act
|
||||
const result = validator.validateState(actualState, {
|
||||
expectedStep: 'cars',
|
||||
requiredSelectors: ['#add-car-button']
|
||||
// forbiddenSelectors is undefined
|
||||
});
|
||||
|
||||
// Assert
|
||||
expect(result.isOk()).toBe(true);
|
||||
const value = result.unwrap();
|
||||
expect(value.isValid).toBe(true);
|
||||
});
|
||||
|
||||
it('should return error result when actualState function throws', () => {
|
||||
// Arrange
|
||||
const actualState = (selector: string) => {
|
||||
throw new Error('Selector evaluation failed');
|
||||
};
|
||||
|
||||
// Act
|
||||
const result = validator.validateState(actualState, {
|
||||
expectedStep: 'cars',
|
||||
requiredSelectors: ['#add-car-button']
|
||||
});
|
||||
|
||||
// Assert
|
||||
expect(result.isErr()).toBe(true);
|
||||
const error = result.unwrapErr();
|
||||
expect(error.message).toContain('Selector evaluation failed');
|
||||
});
|
||||
|
||||
it('should provide clear error messages for missing selectors', () => {
|
||||
// Arrange
|
||||
const actualState = () => false; // Nothing present
|
||||
|
||||
// Act
|
||||
const result = validator.validateState(actualState, {
|
||||
expectedStep: 'track',
|
||||
requiredSelectors: ['#set-track', '#track-search']
|
||||
});
|
||||
|
||||
// Assert
|
||||
expect(result.isOk()).toBe(true);
|
||||
const value = result.unwrap();
|
||||
expect(value.isValid).toBe(false);
|
||||
expect(value.message).toBe('Page state mismatch: Expected to be on "track" page but missing required elements');
|
||||
expect(value.missingSelectors).toEqual(['#set-track', '#track-search']);
|
||||
});
|
||||
|
||||
it('should validate complex state with both required and forbidden selectors', () => {
|
||||
// Arrange - Simulate being on Cars page but Track page elements leaked through
|
||||
const actualState = (selector: string) => {
|
||||
const presentSelectors = ['#add-car-button', '#cars-list', '#set-track'];
|
||||
return presentSelectors.includes(selector);
|
||||
};
|
||||
|
||||
// Act
|
||||
const result = validator.validateState(actualState, {
|
||||
expectedStep: 'cars',
|
||||
requiredSelectors: ['#add-car-button', '#cars-list'],
|
||||
forbiddenSelectors: ['#set-track', '#track-search']
|
||||
});
|
||||
|
||||
// Assert
|
||||
expect(result.isOk()).toBe(true);
|
||||
const value = result.unwrap();
|
||||
expect(value.isValid).toBe(false); // Invalid due to forbidden selector
|
||||
expect(value.unexpectedSelectors).toEqual(['#set-track']);
|
||||
expect(value.message).toContain('unexpected elements');
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user