wip
This commit is contained in:
91
packages/domain/services/PageStateValidator.ts
Normal file
91
packages/domain/services/PageStateValidator.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
import { Result } from '../../shared/result/Result';
|
||||
|
||||
/**
|
||||
* Configuration for page state validation.
|
||||
* Defines expected and forbidden elements on the current page.
|
||||
*/
|
||||
export interface PageStateValidation {
|
||||
/** Expected wizard step name (e.g., 'cars', 'track') */
|
||||
expectedStep: string;
|
||||
/** Selectors that MUST be present on the page */
|
||||
requiredSelectors: string[];
|
||||
/** Selectors that MUST NOT be present on the page */
|
||||
forbiddenSelectors?: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Result of page state validation.
|
||||
*/
|
||||
export interface PageStateValidationResult {
|
||||
isValid: boolean;
|
||||
message: string;
|
||||
expectedStep: string;
|
||||
missingSelectors?: string[];
|
||||
unexpectedSelectors?: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Domain service for validating page state during wizard navigation.
|
||||
*
|
||||
* Purpose: Prevent navigation bugs by ensuring each step executes on the correct page.
|
||||
*
|
||||
* Clean Architecture: This is pure domain logic with no infrastructure dependencies.
|
||||
* It validates state based on selector presence/absence without knowing HOW to check them.
|
||||
*/
|
||||
export class PageStateValidator {
|
||||
/**
|
||||
* Validate that the page state matches expected conditions.
|
||||
*
|
||||
* @param actualState Function that checks if selectors exist on the page
|
||||
* @param validation Expected page state configuration
|
||||
* @returns Result with validation outcome
|
||||
*/
|
||||
validateState(
|
||||
actualState: (selector: string) => boolean,
|
||||
validation: PageStateValidation
|
||||
): Result<PageStateValidationResult, Error> {
|
||||
try {
|
||||
const { expectedStep, requiredSelectors, forbiddenSelectors = [] } = validation;
|
||||
|
||||
// Check required selectors are present
|
||||
const missingSelectors = requiredSelectors.filter(selector => !actualState(selector));
|
||||
|
||||
if (missingSelectors.length > 0) {
|
||||
const result: PageStateValidationResult = {
|
||||
isValid: false,
|
||||
message: `Page state mismatch: Expected to be on "${expectedStep}" page but missing required elements`,
|
||||
expectedStep,
|
||||
missingSelectors
|
||||
};
|
||||
return Result.ok(result);
|
||||
}
|
||||
|
||||
// Check forbidden selectors are absent
|
||||
const unexpectedSelectors = forbiddenSelectors.filter(selector => actualState(selector));
|
||||
|
||||
if (unexpectedSelectors.length > 0) {
|
||||
const result: PageStateValidationResult = {
|
||||
isValid: false,
|
||||
message: `Page state mismatch: Found unexpected elements on "${expectedStep}" page`,
|
||||
expectedStep,
|
||||
unexpectedSelectors
|
||||
};
|
||||
return Result.ok(result);
|
||||
}
|
||||
|
||||
// All checks passed
|
||||
const result: PageStateValidationResult = {
|
||||
isValid: true,
|
||||
message: `Page state valid for "${expectedStep}"`,
|
||||
expectedStep
|
||||
};
|
||||
return Result.ok(result);
|
||||
} catch (error) {
|
||||
return Result.err(
|
||||
error instanceof Error
|
||||
? error
|
||||
: new Error(`Page state validation failed: ${String(error)}`)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user