Ctrl K
ComunidadGuías…

scripts/e2e-tier-scope.mjs

Rama develop · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
#!/usr/bin/env node
/**
 * Builds the Playwright spec pattern for a given set of fixture/spec
 * tiers (e.g. just "pr-check", or "pr-check"+"nightly-check" for the
 * nightly build): every diagram's curated tier-subfolder hand-written
 * specs under e2e/rendering, the cross-cutting specs under e2e/other
 * (xss, ghsa, configuration, etc. — only ever has a pr-check/ subfolder
 * today), plus the global mmd snapshot runner (which is separately
 * tier-filtered to each diagram's matching fixtures under e2e/diagrams
 * at runtime, via MERMAID_E2E_FIXTURE_TIER — pass it the same tier list,
 * comma-separated).
 *
 * Convention: every diagram folder under e2e/rendering may have a
 * subfolder per tier (pr-check/nightly-check/visual-check). No hardcoded
 * diagram list — discovered at runtime, same as
 * scripts/e2e-diagram-scope.mjs.
 *
 * Used by:
 *   - .github/workflows/e2e.yml's detect-scope job, tier ["pr-check"],
 *     when a PR on this fork carries the "run pr tests" label (develop);
 *     tiers ["pr-check","nightly-check"] for the "run release test" label
 *     (master) — visual-check is deliberately excluded from this
 *     automated gate; see that workflow's comments.
 *   - .github/workflows/nightly-e2e.yml, tiers ["pr-check","nightly-check"].
 *
 * CLI usage (one or more tier names; defaults to "pr-check" if none given):
 *   node scripts/e2e-tier-scope.mjs pr-check
 *   node scripts/e2e-tier-scope.mjs pr-check nightly-check
 *
 * Module usage:
 *   import { buildTierSpecPattern } from './e2e-tier-scope.mjs';
 *   buildTierSpecPattern(['pr-check', 'nightly-check']);
 */

import { existsSync, readdirSync } from 'fs';
import { fileURLToPath } from 'url';

export const SPEC_BASE_DIR = 'e2e/rendering';
export const MMD_SNAPSHOTS_SPEC = `${SPEC_BASE_DIR}/mmd-snapshots.spec.ts`;
// e2e/other/ holds cross-cutting specs (xss, ghsa, configuration, iife,
// interaction, rerender, external-diagrams) — not a per-diagram folder, so
// it isn't discovered by the e2e/rendering scan below and is checked
// explicitly instead.
export const OTHER_DIR = 'e2e/other';

/**
 * @param {string} tier
 * @returns {string} e2e/other's subfolder for that tier (e.g. 'e2e/other/pr').
 */
export const otherTierDir = (tier) => `${OTHER_DIR}/${tier}`;

/**
 * @param {readonly string[]} tiers - one or more tier names, e.g. ['pr'] or ['pr', 'nightly'].
 * @param {string} [specBaseDir]
 * @returns {string} Comma-separated, sorted spec pattern for `playwright test`.
 */
export function buildTierSpecPattern(tiers, specBaseDir = SPEC_BASE_DIR) {
  if (!tiers || tiers.length === 0) {
    throw new Error('buildTierSpecPattern requires at least one tier name');
  }

  const specs = new Set();

  let entries;
  try {
    entries = readdirSync(specBaseDir, { withFileTypes: true });
  } catch {
    entries = [];
  }

  for (const entry of entries) {
    if (!entry.isDirectory()) {
      continue;
    }
    for (const tier of tiers) {
      const tierDir = `${specBaseDir}/${entry.name}/${tier}`;
      if (existsSync(tierDir)) {
        specs.add(`${tierDir}/`);
      }
    }
  }

  for (const tier of tiers) {
    const otherDir = otherTierDir(tier);
    if (existsSync(otherDir)) {
      specs.add(`${otherDir}/`);
    }
  }

  specs.add(MMD_SNAPSHOTS_SPEC);

  return [...specs].sort().join(',');
}

/** Back-compat convenience wrapper for the single-tier "pr-check" case. */
export function buildPrTierSpecPattern(specBaseDir = SPEC_BASE_DIR) {
  return buildTierSpecPattern(['pr-check'], specBaseDir);
}

if (process.argv[1] === fileURLToPath(import.meta.url)) {
  const tiers = process.argv.slice(2);
  process.stdout.write(buildTierSpecPattern(tiers.length > 0 ? tiers : ['pr-check']));
}