All files / runtime/_services login-flow-helper.base.ts

100% Statements 82/82
83.33% Branches 5/6
100% Functions 3/3
100% Lines 82/82

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 75 76 77 78 79 80 81 82 831x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 1x 1x 5x 5x 5x 5x 5x 5x 5x 4x 4x 4x 3x 3x 3x 3x 3x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 4x 5x  
import type { Page } from '@playwright/test';
 
/**
 * MP-07 SP-C lift — generic login-flow template-method.
 *
 * A `fdp-e2e-helpers@v2.0`-ban a `FDPLoginFlowHelper` ezt fogja extends-eli
 * az FDP-auth-service-specifikus URL + form-key-k impl-jével.
 *
 * Template-method (Gang of Four pattern): a `login()` definiált flow-t fut,
 * a subclass csak a "step-konfigurációt" (selectors + success-route) adja.
 */
export interface DyE2E_LoginFlowResult {
  success: boolean;
  /** Időtartam ms-ben. */
  durationMs: number;
  /** Opcionális token-extrakció eredménye. */
  authState?: { token?: string; refreshToken?: string; [extra: string]: unknown };
  /** Hiba, ha success === false. */
  error?: string;
}
 
export abstract class DyE2E_LoginFlowHelper_Base {
 
  /** A login form gyökér-eleme — a fill-ek scope-ját adja. */
  abstract loginFormSelector: string;
 
  /** Az email/username input testId-je. */
  abstract emailInputTestId: string;
 
  /** A password input testId-je. */
  abstract passwordInputTestId: string;
 
  /** A submit button testId-je. */
  abstract submitButtonTestId: string;
 
  /** A success-route regex-e (pl. `/dashboard`). A `waitForURL` ezzel megy. */
  abstract successRouteRegex: RegExp;
 
  /** Login-route ahova navigálunk (default: `/login`). */
  loginRoute: string = '/login';
 
  /** Timeout ms-ben (default 15000). */
  loginTimeoutMs: number = 15_000;
 
  /**
   * Hook: a sikeres login után a sub-class kiolvashatja a tokent (pl.
   * `localStorage` vagy cookies). Default: üres token.
   */
  protected async extractAuthState(_page: Page): Promise<DyE2E_LoginFlowResult['authState']> {
    return undefined;
  }
 
  /**
   * Template-method: fill + submit + wait-for-success-route + extract-token.
   *
   * NEM dob hibára — `DyE2E_LoginFlowResult.success: false`-szel jelzi.
   */
  async login(page: Page, email: string, password: string): Promise<DyE2E_LoginFlowResult> {
    const start: number = Date.now();
    try {
      await page.goto(this.loginRoute, { timeout: this.loginTimeoutMs });
      await page.locator(this.loginFormSelector).first().waitFor({ state: 'visible', timeout: this.loginTimeoutMs });
      await page.getByTestId(this.emailInputTestId).fill(email);
      await page.getByTestId(this.passwordInputTestId).fill(password);
      await page.getByTestId(this.submitButtonTestId).click();
      await page.waitForURL(this.successRouteRegex, { timeout: this.loginTimeoutMs });
      const authState = await this.extractAuthState(page);
      return {
        success: true,
        durationMs: Date.now() - start,
        authState: authState,
      };
    } catch (e: unknown) {
      const errorMsg: string = (e && typeof e === 'object' && 'message' in e) ? String((e as { message: unknown }).message) : String(e);
      return {
        success: false,
        durationMs: Date.now() - start,
        error: errorMsg,
      };
    }
  }
}