diff --git a/packages/cli/src/services/__tests__/util.spec.ts b/packages/cli/src/services/__tests__/util.spec.ts index be035c8e8..ee7945915 100644 --- a/packages/cli/src/services/__tests__/util.spec.ts +++ b/packages/cli/src/services/__tests__/util.spec.ts @@ -5,7 +5,9 @@ import { pathToPosix, isFileSync, getPlaywrightVersionFromPackage, + getAutoIncludes, } from '../util' +import { PackageManager } from '../check-parser/package-files/package-manager' describe('util', () => { describe('pathToPosix()', () => { @@ -29,6 +31,54 @@ describe('util', () => { }) }) + describe('getAutoIncludes()', () => { + const basePath = path.resolve('/project') + const makePm = (name: string): PackageManager => ({ + name, + representativeLockfile: undefined, + representativeConfigFile: undefined, + installCommand: () => ({ executable: name, args: ['install'], unsafeDisplayCommand: `${name} install` }), + execCommand: (args: string[]) => ({ executable: name, args, unsafeDisplayCommand: `${name} ${args.join(' ')}` }), + lookupWorkspace: () => Promise.resolve(undefined), + detector: () => ({}) as any, + }) + + it('should return patches/*.patch for pnpm', () => { + const result = getAutoIncludes(basePath, makePm('pnpm'), []) + expect(result).toEqual(['patches/*.patch']) + }) + + it('should return empty for npm', () => { + const result = getAutoIncludes(basePath, makePm('npm'), []) + expect(result).toEqual([]) + }) + + it('should return empty for yarn', () => { + const result = getAutoIncludes(basePath, makePm('yarn'), []) + expect(result).toEqual([]) + }) + + it('should skip when user already includes patches/*.patch', () => { + const result = getAutoIncludes(basePath, makePm('pnpm'), ['patches/*.patch']) + expect(result).toEqual([]) + }) + + it('should skip when user already includes a patches/ subpath', () => { + const result = getAutoIncludes(basePath, makePm('pnpm'), ['patches/some-patch.patch']) + expect(result).toEqual([]) + }) + + it('should skip when user includes ./patches/**', () => { + const result = getAutoIncludes(basePath, makePm('pnpm'), ['./patches/**']) + expect(result).toEqual([]) + }) + + it('should skip when user includes absolute patches path', () => { + const result = getAutoIncludes(basePath, makePm('pnpm'), [path.join(basePath, 'patches/**')]) + expect(result).toEqual([]) + }) + }) + describe('getPlaywrightVersionFromPackage()', () => { it('should throw error when playwright package is not found', async () => { // Use a directory that doesn't have playwright installed diff --git a/packages/cli/src/services/util.ts b/packages/cli/src/services/util.ts index ec68c40fc..5e09f2fc9 100644 --- a/packages/cli/src/services/util.ts +++ b/packages/cli/src/services/util.ts @@ -12,7 +12,7 @@ import { PlaywrightConfig } from './playwright-config' import { Session } from '../constructs/project' import semver from 'semver' import { existsSync } from 'fs' -import { detectNearestPackageJson } from './check-parser/package-files/package-manager' +import { detectNearestPackageJson, PackageManager } from './check-parser/package-files/package-manager' export interface GitInformation { commitId: string @@ -143,6 +143,25 @@ export function normalizeVersion (v?: string | undefined): string | undefined { return cleaned && semver.valid(cleaned) ? cleaned : undefined } +export function getAutoIncludes ( + basePath: string, + packageManager: PackageManager, + existingIncludes: string[], +): string[] { + const autoIncludes: string[] = [] + + if (packageManager.name === 'pnpm') { + const patchesPattern = 'patches/*.patch' + const patchesDir = path.join(basePath, 'patches') + const alreadyIncluded = existingIncludes.some(p => path.resolve(basePath, p).startsWith(patchesDir)) + if (!alreadyIncluded) { + autoIncludes.push(patchesPattern) + } + } + + return autoIncludes +} + export async function bundlePlayWrightProject ( playwrightConfig: string, include: string[], @@ -195,10 +214,13 @@ export async function bundlePlayWrightProject ( } } + const autoIncludes = getAutoIncludes(Session.basePath!, Session.packageManager, include) + const effectiveIncludes = [...include, ...autoIncludes] + const includedFiles = await findFilesWithPattern( // FIXME: Shouldn't the pattern be relative to the Playwright check? Session.basePath!, - include, + effectiveIncludes, ignoredFiles, )