From ffd18627f27eb97ce0629a34213593fe83ecc46e Mon Sep 17 00:00:00 2001 From: Pilar Martinez Date: Thu, 29 Jan 2026 16:31:18 -0300 Subject: [PATCH] feat: add guardrail for playwright install warning [red-79] --- .../__tests__/playwright-check.spec.ts | 74 +++++++++++++++++++ .../cli/src/constructs/playwright-check.ts | 23 ++++++ 2 files changed, 97 insertions(+) diff --git a/packages/cli/src/constructs/__tests__/playwright-check.spec.ts b/packages/cli/src/constructs/__tests__/playwright-check.spec.ts index ee62e750b..e4b3eb8b3 100644 --- a/packages/cli/src/constructs/__tests__/playwright-check.spec.ts +++ b/packages/cli/src/constructs/__tests__/playwright-check.spec.ts @@ -445,6 +445,80 @@ describe('PlaywrightCheck', () => { }), ])) }) + + it('should warn when installCommand contains playwright install', async () => { + Session.basePath = path.resolve(__dirname, './fixtures/playwright-check') + Session.project = new Project('project-id', { + name: 'Test Project', + repoUrl: 'https://github.com/checkly/checkly-cli', + }) + + const check = new PlaywrightCheck('foo', { + name: 'Test Check', + playwrightConfigPath: path.resolve(__dirname, './fixtures/playwright-check/playwright.config.ts'), + installCommand: 'npm ci && npx playwright install chromium', + }) + + const diags = new Diagnostics() + await check.validate(diags) + + expect(diags.isFatal()).toEqual(false) + expect(diags.observations).toEqual(expect.arrayContaining([ + expect.objectContaining({ + title: 'Unnecessary browser installation detected', + message: expect.stringContaining('installCommand contains "playwright install"'), + }), + ])) + }) + + it('should warn when testCommand contains playwright install', async () => { + Session.basePath = path.resolve(__dirname, './fixtures/playwright-check') + Session.project = new Project('project-id', { + name: 'Test Project', + repoUrl: 'https://github.com/checkly/checkly-cli', + }) + + const check = new PlaywrightCheck('foo', { + name: 'Test Check', + playwrightConfigPath: path.resolve(__dirname, './fixtures/playwright-check/playwright.config.ts'), + testCommand: 'npx playwright install && npx playwright test', + }) + + const diags = new Diagnostics() + await check.validate(diags) + + expect(diags.isFatal()).toEqual(false) + expect(diags.observations).toEqual(expect.arrayContaining([ + expect.objectContaining({ + title: 'Unnecessary browser installation detected', + message: expect.stringContaining('testCommand contains "playwright install"'), + }), + ])) + }) + + it('should not warn when commands do not contain playwright install', async () => { + Session.basePath = path.resolve(__dirname, './fixtures/playwright-check') + Session.project = new Project('project-id', { + name: 'Test Project', + repoUrl: 'https://github.com/checkly/checkly-cli', + }) + + const check = new PlaywrightCheck('foo', { + name: 'Test Check', + playwrightConfigPath: path.resolve(__dirname, './fixtures/playwright-check/playwright.config.ts'), + installCommand: 'npm ci', + testCommand: 'npx playwright test', + }) + + const diags = new Diagnostics() + await check.validate(diags) + + expect(diags.observations).not.toEqual(expect.arrayContaining([ + expect.objectContaining({ + title: 'Unnecessary browser installation detected', + }), + ])) + }) }) describe('defaults', () => { diff --git a/packages/cli/src/constructs/playwright-check.ts b/packages/cli/src/constructs/playwright-check.ts index dcf8bf8f3..784012975 100644 --- a/packages/cli/src/constructs/playwright-check.ts +++ b/packages/cli/src/constructs/playwright-check.ts @@ -313,6 +313,28 @@ export class PlaywrightCheck extends RuntimeCheck { } } + protected validateBrowserInstallCommand (diagnostics: Diagnostics): void { + const playwrightInstallPattern = /playwright\s+install/i + + const commands = [ + { name: 'installCommand', value: this.installCommand }, + { name: 'testCommand', value: this.testCommand }, + ] + + for (const { name, value } of commands) { + if (value && playwrightInstallPattern.test(value)) { + diagnostics.add(new WarningDiagnostic({ + title: 'Unnecessary browser installation detected', + message: + `The ${name} contains "playwright install" which is not needed. ` + + `Checkly automatically installs browsers based on your pwProjects configuration. ` + + `Consider removing the browser installation from ${name}.`, + })) + break + } + } + } + async validate (diagnostics: Diagnostics): Promise { await super.validate(diagnostics) await this.validateRetryStrategy(diagnostics) @@ -328,6 +350,7 @@ export class PlaywrightCheck extends RuntimeCheck { } await this.validateHeadlessMode(diagnostics) + this.validateBrowserInstallCommand(diagnostics) this.#validateGroupReferences(diagnostics) }