All files / generators viewport-suite.generator.ts

100% Statements 74/74
100% Branches 11/11
100% Functions 2/2
100% Lines 74/74

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 751x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 70x 77x 77x 77x 77x 77x 77x 77x 77x 70x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 1x  
import { STANDARD_VIEWPORT_LIST } from '../contracts/_collections/constants/standard-viewports.const';
import { DyE2E_Viewport_Interface } from '../contracts/_models/interfaces/viewport.interface';
import { DyE2E_RouteDescriptor_Interface } from './_models/route-descriptor.interface';
import { DyE2E_ViewportSuiteGenerate_Options } from './_models/viewport-suite-generate-options.interface';
import { DyE2E_SpecEmission_Util } from './_collections/spec-emission.util';
import { DyE2E_ViewportEmission_Util } from './_collections/viewport-emission.util';
 
/**
 * MP-04 — Viewport-suite generator.
 *
 * Bemenet: route-lista + viewport-katalógus (default: 7 standard) + theme-set
 * (default: `['dark']`). Kimenet: Playwright `spec.ts` string.
 *
 * Sample:
 * ```ts
 * const spec: string = DyE2E_ViewportSuite_Generator.emit({
 *   routes: [{ key: 'home', path: '/' }, { key: 'login', path: '/login' }],
 *   checkTouchTargets: true,
 *   themes: ['dark', 'light'],
 * });
 * ```
 */
export class DyE2E_ViewportSuite_Generator {
 
  static readonly STAMP_BUILT_AT: string = 'WAVE-2-STAMP';
 
  static emit(options: DyE2E_ViewportSuiteGenerate_Options): string {
    const viewports: DyE2E_Viewport_Interface[] = options.viewports ?? STANDARD_VIEWPORT_LIST;
    const themes: ('dark' | 'light')[] = options.themes ?? ['dark'];
    const takeScreenshot: boolean = options.takeScreenshot ?? true;
    const checkOverflow: boolean = options.checkOverflow ?? true;
    const checkTouchTargets: boolean = options.checkTouchTargets ?? false;
    const touchTargetMinPx: number = options.touchTargetMinPx ?? 44;
    const screenshotDir: string = options.screenshotDir ?? 'e2e/screenshots';
 
    const header: string = DyE2E_SpecEmission_Util.headerComment(
      'viewport-audit',
      options.routes.map((r: DyE2E_RouteDescriptor_Interface): string => r.path).join(', '),
      DyE2E_ViewportSuite_Generator.STAMP_BUILT_AT,
      options.headerComment,
    );
 
    const blocks: string[] = [];
    for (const route of options.routes) {
      const inner: string[] = [];
      for (const vp of viewports) {
        for (const theme of themes) {
          inner.push(DyE2E_ViewportEmission_Util.emitRouteViewportBlock(route, vp, theme, {
            takeScreenshot,
            checkOverflow,
            checkTouchTargets,
            touchTargetMinPx,
            screenshotDir,
          }));
        }
      }
      blocks.push(`test.describe('Route: ${DyE2E_SpecEmission_Util.escapeString(route.label ?? route.key)} (${DyE2E_SpecEmission_Util.escapeString(route.path)})', (): void => {
${DyE2E_SpecEmission_Util.indent(inner.join('\n\n'), 1)}
});`);
    }
 
    const describePrefix: string = options.describePrefix ?? 'Viewport audit';
 
    return `${header}
import { test, expect } from '@playwright/test';
 
test.describe('${DyE2E_SpecEmission_Util.escapeString(describePrefix)}', (): void => {
 
${blocks.join('\n\n')}
 
});
`;
  }
}