teqo-backup/scripts/lib/playwright-e2e-args.mjs
Francisco Solla 8c915e59fc fix(S6-FOLLOWUP): test:e2e:affected rodava a suíte completa — --no-deps desliga o closure de deps dos projects em runs filtrados
Causa raiz (medida com o binário 1.58.2, config real): commander parseia
posicionais e -g/--list funcionam; o que arrastava a suíte era o closure de
dependências do dev mode (setup<-campaign<-frontend<-admin): filtrar um spec
do frontend puxava campaign(160)+setup(2). run-e2e-affected.mjs agora gera
test:e2e <passthrough verbatim> --no-deps -- <paths> via helpers puros em
scripts/lib/playwright-e2e-args.mjs (unit-pinned); passthrough corrigido
(pnpm consome o -- e o path era descartado); run-e2e-affected.mjs entrou em
HIGH_RISK_EXACT. Docs: receitas de filtro no playwright.config.ts, AGENTS.md,
changelog.
2026-08-18 19:09:12 -03:00

51 lines
2.2 KiB
JavaScript

/**
* Pure argv helpers for the local e2e runner (S6-FOLLOWUP, 2026-08-18).
* `run-e2e-affected.mjs` consumes them; unit-pinned in
* tests/unit/playwrightE2eArgs.unit.spec.ts.
*
* Why `--no-deps` + `--`: positional paths ARE parsed correctly by the
* Playwright CLI (commander), but in DEV mode the project dependency chain
* (setup -> campaign -> frontend -> admin, playwright.config.ts) makes the
* runner drag ALL files of every dependency project into a selected run via
* buildProjectsClosure — filtering to one frontend spec runs the whole
* campaign family. `--no-deps` disables that closure for FILTERED runs only;
* a full run keeps the dev chain (OPS34 cold-compile prewarm ordering). The
* `--` separator guards the generated scope paths from flag parsing.
*/
/** Flags that filter the run by themselves (not just runner knobs). */
const FILTER_FLAG_RE = /^(?:--project|-g|--grep|--grep-invert)(?:=.*)?$/
/**
* Passthrough args from the process argv, minus the script path. pnpm
* consumes its own `--` separator, so a leading `--` in argv only appears on
* direct `node scripts/...` invocations — strip exactly one, forward the rest
* verbatim (flag values must not be re-classified, e.g. `-g grade`).
* @param {string[]} argv process.argv
* @returns {string[]}
*/
export const parsePassthroughArgs = (argv) => {
const rest = argv.slice(2)
return rest[0] === '--' ? rest.slice(1) : rest
}
/**
* @param {{ scopeSpecPaths?: string[], passthroughArgs?: string[] }} input
* scopeSpecPaths — repo-relative spec paths selected by the affected manifest.
* passthroughArgs — extra args forwarded by the user.
* @returns {string[]} pnpm argv for the e2e run, e.g.
* ['test:e2e', '--no-deps', '--', 'tests/e2e/foo.e2e.spec.ts']
*/
export const buildPlaywrightE2eArgs = ({ scopeSpecPaths = [], passthroughArgs = [] }) => {
const filtered =
scopeSpecPaths.length > 0 ||
passthroughArgs.some((arg) => !arg.startsWith('-') || FILTER_FLAG_RE.test(arg))
const args = ['test:e2e', ...passthroughArgs]
if (filtered && !passthroughArgs.includes('--no-deps')) {
args.push('--no-deps')
}
if (scopeSpecPaths.length > 0) {
args.push('--', ...scopeSpecPaths)
}
return args
}