From aae8a6daaf522b27c7d11dd42e5e772c6953292e Mon Sep 17 00:00:00 2001 From: Colin McDonnell Date: Mon, 14 Aug 2023 17:48:40 -0700 Subject: [PATCH] feat: detect bun package manager --- .github/workflows/ci.yml | 33 ++++----- .gitignore | 8 ++- README.md | 2 + package-lock.json | 61 +++++++++++----- package.json | 2 +- playwright.config.ts | 24 ++++--- src/generator.ts | 4 +- src/packageManager.ts | 98 ++++++++++++++++---------- tests/baseFixtures.ts | 31 ++++++--- tests/integration.spec.ts | 142 +++++++++++++++++++++++++++++++------- 10 files changed, 290 insertions(+), 115 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 82a0a77..5c9699b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,9 +1,9 @@ name: create-playwright CI on: push: - branches: [ main ] + branches: [main] pull_request: - branches: [ main ] + branches: [main] jobs: build: runs-on: ${{ matrix.os }} @@ -13,17 +13,18 @@ jobs: node-version: [16.x, 18.x, 20.x] os: [ubuntu-latest, windows-latest, macos-latest] steps: - - uses: actions/checkout@v3 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 - with: - node-version: ${{ matrix.node-version }} - cache: 'npm' - - run: npm i -g npm@8 - - run: npm i -g yarn@1 - - run: npm i -g pnpm@7 - - run: npm ci - - run: npx playwright install-deps - - run: npm run build - - run: npx tsc --noEmit - - run: npm run test + - uses: actions/checkout@v3 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + cache: 'npm' + - run: npm i -g npm@8 + - run: npm i -g yarn@1 + - run: npm i -g pnpm@7 + - run: npm i -g bun + - run: npm ci + - run: npx playwright install-deps + - run: npm run build + - run: npx tsc --noEmit + - run: npm run test diff --git a/.gitignore b/.gitignore index ef05e24..1383cfd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,9 @@ node_modules/ lib/ -test-results/ \ No newline at end of file +test-results/ +/test-results/ +/playwright-report/ +/playwright/.cache/ +/test-results/ +/playwright-report/ +/playwright/.cache/ diff --git a/README.md b/README.md index 7a38622..03c0f69 100644 --- a/README.md +++ b/README.md @@ -11,4 +11,6 @@ npm init playwright@latest yarn create playwright # Or for pnpm pnpm dlx create-playwright +# Or for Bun +bunx create-playwright ``` diff --git a/package-lock.json b/package-lock.json index 0216eac..d0be9e5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "create-playwright": "index.js" }, "devDependencies": { - "@playwright/test": "^1.30.0", + "@playwright/test": "^1.37.0", "@types/node": "^16.11.11", "ansi-colors": "^4.1.1", "enquirer": "^2.3.6", @@ -24,19 +24,22 @@ } }, "node_modules/@playwright/test": { - "version": "1.30.0", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.30.0.tgz", - "integrity": "sha512-SVxkQw1xvn/Wk/EvBnqWIq6NLo1AppwbYOjNLmyU0R1RoQ3rLEBtmjTnElcnz8VEtn11fptj1ECxK0tgURhajw==", + "version": "1.37.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.37.0.tgz", + "integrity": "sha512-181WBLk4SRUyH1Q96VZl7BP6HcK0b7lbdeKisn3N/vnjitk+9HbdlFz/L5fey05vxaAhldIDnzo8KUoy8S3mmQ==", "dev": true, "dependencies": { "@types/node": "*", - "playwright-core": "1.30.0" + "playwright-core": "1.37.0" }, "bin": { "playwright": "cli.js" }, "engines": { - "node": ">=14" + "node": ">=16" + }, + "optionalDependencies": { + "fsevents": "2.3.2" } }, "node_modules/@types/node": { @@ -421,16 +424,30 @@ "node": ">=12" } }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/playwright-core": { - "version": "1.30.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.30.0.tgz", - "integrity": "sha512-7AnRmTCf+GVYhHbLJsGUtskWTE33SwMZkybJ0v6rqR1boxq2x36U7p1vDRV7HO2IwTZgmycracLxPEJI49wu4g==", + "version": "1.37.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.37.0.tgz", + "integrity": "sha512-1c46jhTH/myQw6sesrcuHVtLoSNfJv8Pfy9t3rs6subY7kARv0HRw5PpyfPYPpPtQvBOmgbE6K+qgYUpj81LAA==", "dev": true, "bin": { - "playwright": "cli.js" + "playwright-core": "cli.js" }, "engines": { - "node": ">=14" + "node": ">=16" } }, "node_modules/typescript": { @@ -449,13 +466,14 @@ }, "dependencies": { "@playwright/test": { - "version": "1.30.0", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.30.0.tgz", - "integrity": "sha512-SVxkQw1xvn/Wk/EvBnqWIq6NLo1AppwbYOjNLmyU0R1RoQ3rLEBtmjTnElcnz8VEtn11fptj1ECxK0tgURhajw==", + "version": "1.37.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.37.0.tgz", + "integrity": "sha512-181WBLk4SRUyH1Q96VZl7BP6HcK0b7lbdeKisn3N/vnjitk+9HbdlFz/L5fey05vxaAhldIDnzo8KUoy8S3mmQ==", "dev": true, "requires": { "@types/node": "*", - "playwright-core": "1.30.0" + "fsevents": "2.3.2", + "playwright-core": "1.37.0" } }, "@types/node": { @@ -647,10 +665,17 @@ "dev": true, "optional": true }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, "playwright-core": { - "version": "1.30.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.30.0.tgz", - "integrity": "sha512-7AnRmTCf+GVYhHbLJsGUtskWTE33SwMZkybJ0v6rqR1boxq2x36U7p1vDRV7HO2IwTZgmycracLxPEJI49wu4g==", + "version": "1.37.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.37.0.tgz", + "integrity": "sha512-1c46jhTH/myQw6sesrcuHVtLoSNfJv8Pfy9t3rs6subY7kARv0HRw5PpyfPYPpPtQvBOmgbE6K+qgYUpj81LAA==", "dev": true }, "typescript": { diff --git a/package.json b/package.json index 4051411..410b6d6 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "prepublish": "npm run build" }, "devDependencies": { - "@playwright/test": "^1.30.0", + "@playwright/test": "^1.37.0", "@types/node": "^16.11.11", "ansi-colors": "^4.1.1", "enquirer": "^2.3.6", diff --git a/playwright.config.ts b/playwright.config.ts index cf87857..fd543c5 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -13,8 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { defineConfig } from '@playwright/test'; -import type { TestFixtures } from './tests/baseFixtures'; +import {defineConfig} from '@playwright/test'; +import type {TestFixtures} from './tests/baseFixtures'; export default defineConfig({ timeout: 120 * 1000, @@ -25,20 +25,26 @@ export default defineConfig({ { name: 'npm', use: { - packageManager: 'npm' - } + packageManager: 'npm', + }, }, { name: 'yarn', use: { - packageManager: 'yarn' - } + packageManager: 'yarn', + }, }, { name: 'pnpm', use: { - packageManager: 'pnpm' - } + packageManager: 'pnpm', + }, }, - ] + { + name: 'bun', + use: { + packageManager: 'bun', + }, + }, + ], }); diff --git a/src/generator.ts b/src/generator.ts index a6a4460..6534b55 100644 --- a/src/generator.ts +++ b/src/generator.ts @@ -252,7 +252,9 @@ export class Generator { const extension = languageToFileExtension(answers.language); if (answers.framework) packageJSON.scripts['test-ct'] = `playwright test -c playwright-ct.config.${extension}`; - + // force commonjs because playwright.config.js uses `require` + if(answers.language === 'JavaScript') + delete packageJSON.type; const files = new Map(); files.set('package.json', JSON.stringify(packageJSON, null, 2) + '\n'); // NPM keeps a trailing new-line await createFiles(this.rootDir, files, true); diff --git a/src/packageManager.ts b/src/packageManager.ts index c6c5648..cc0fe2a 100644 --- a/src/packageManager.ts +++ b/src/packageManager.ts @@ -1,36 +1,36 @@ interface PackageManager { cli: string; - name: string - init(): string - npx(command: string, args: string): string - ci(): string - installDevDependency(name: string): string - runPlaywrightTest(args?: string): string - run(script: string): string + name: string; + init(): string; + npx(command: string, args: string): string; + ci(): string; + installDevDependency(name: string): string; + runPlaywrightTest(args?: string): string; + run(script: string): string; } class NPM implements PackageManager { - name = 'NPM' - cli = 'npm' + name = 'NPM'; + cli = 'npm'; init(): string { - return 'npm init -y' + return 'npm init -y'; } npx(command: string, args: string): string { - return `npx ${command} ${args}` + return `npx ${command} ${args}`; } ci(): string { - return 'npm ci' + return 'npm ci'; } installDevDependency(name: string): string { - return `npm install --save-dev ${name}` + return `npm install --save-dev ${name}`; } runPlaywrightTest(args: string): string { - return this.npx('playwright', `test${args ? (' ' + args) : ''}`); + return this.npx('playwright', `test${args ? ' ' + args : ''}`); } run(script: string): string { @@ -39,56 +39,56 @@ class NPM implements PackageManager { } class Yarn implements PackageManager { - name = 'Yarn' - cli = 'yarn' + name = 'Yarn'; + cli = 'yarn'; init(): string { - return 'yarn init -y' + return 'yarn init -y'; } npx(command: string, args: string): string { - return `yarn ${command} ${args}` + return `yarn ${command} ${args}`; } ci(): string { - return 'yarn' + return 'yarn'; } installDevDependency(name: string): string { - return `yarn add --dev ${name}` + return `yarn add --dev ${name}`; } runPlaywrightTest(args: string): string { - return this.npx('playwright', `test${args ? (' ' + args) : ''}`); + return this.npx('playwright', `test${args ? ' ' + args : ''}`); } - + run(script: string): string { return `yarn ${script}`; } } class PNPM implements PackageManager { - name = 'pnpm' - cli = 'pnpm' + name = 'pnpm'; + cli = 'pnpm'; init(): string { - return 'pnpm init' + return 'pnpm init'; } npx(command: string, args: string): string { - return `pnpm exec ${command} ${args}` + return `pnpm exec ${command} ${args}`; } ci(): string { - return 'pnpm install' + return 'pnpm install'; } installDevDependency(name: string): string { - return `pnpm add --save-dev ${name}` + return `pnpm add --save-dev ${name}`; } runPlaywrightTest(args: string): string { - return this.npx('playwright', `test${args ? (' ' + args) : ''}`); + return this.npx('playwright', `test${args ? ' ' + args : ''}`); } run(script: string): string { @@ -96,15 +96,43 @@ class PNPM implements PackageManager { } } +class BunPM implements PackageManager { + name = 'bun'; + cli = 'bun'; + + init(): string { + return 'bun init -y'; + } + + npx(command: string, args: string): string { + return `bunx ${command} ${args}`; + } + + ci(): string { + return 'bun install'; + } + + installDevDependency(name: string): string { + return `bun add --dev ${name}`; + } + + runPlaywrightTest(args: string): string { + return this.npx('playwright', `test${args ? ' ' + args : ''}`); + } + + run(script: string): string { + return `bun run ${script}`; + } +} + function determinePackageManager(): PackageManager { if (process.env.npm_config_user_agent) { - if (process.env.npm_config_user_agent.includes('yarn')) - return new Yarn() - if (process.env.npm_config_user_agent.includes('pnpm')) - return new PNPM() - return new NPM() + if (process.env.npm_config_user_agent.includes('yarn')) return new Yarn(); + if (process.env.npm_config_user_agent.includes('pnpm')) return new PNPM(); + if (process.env.npm_config_user_agent.includes('bun')) return new BunPM(); + return new NPM(); } - return new NPM() + return new NPM(); } export const packageManager = determinePackageManager(); diff --git a/tests/baseFixtures.ts b/tests/baseFixtures.ts index dd993b0..19cea79 100644 --- a/tests/baseFixtures.ts +++ b/tests/baseFixtures.ts @@ -20,7 +20,7 @@ import path from 'path'; import fs from 'fs'; import { PromptOptions } from '../src/generator'; -export type PackageManager = 'npm' | 'pnpm' | 'yarn' +export type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun' export type TestFixtures = { packageManager: PackageManager; @@ -58,15 +58,26 @@ export const test = base.extend({ run: async ({ packageManager }, use, testInfo) => { await use(async (parameters: string[], options: PromptOptions): Promise => { fs.mkdirSync(testInfo.outputDir, { recursive: true }); - const result = await spawnAsync('node', [path.join(__dirname, '..'), ...parameters], { - shell: true, - cwd: testInfo.outputDir, - env: { - ...process.env, - 'npm_config_user_agent': packageManager === 'yarn' ? 'yarn' : packageManager === 'pnpm' ? 'pnpm/0.0.0' : undefined, - 'TEST_OPTIONS': JSON.stringify(options), + const result = await spawnAsync( + 'node', + [path.join(__dirname, '..'), ...parameters], + { + shell: true, + cwd: testInfo.outputDir, + env: { + ...process.env, + npm_config_user_agent: + packageManager === 'yarn' + ? 'yarn' + : packageManager === 'pnpm' + ? 'pnpm/0.0.0' + : packageManager === 'bun' + ? 'bun' + : undefined, + TEST_OPTIONS: JSON.stringify(options), + }, } - }); + ); const execWrapper = (cmd: string, args: string[], options?: SpawnOptionsWithoutStdio): ReturnType => { return spawnAsync(cmd, args, { ...options, @@ -91,6 +102,8 @@ export function assertLockFilesExist(dir: string, packageManager: PackageManager expect(fs.existsSync(path.join(dir, 'yarn.lock'))).toBeTruthy(); else if (packageManager === 'pnpm') expect(fs.existsSync(path.join(dir, 'pnpm-lock.yaml'))).toBeTruthy(); + else if (packageManager === 'bun') + expect(fs.existsSync(path.join(dir, 'bun.lockb'))).toBeTruthy(); } export const expect = test.expect; diff --git a/tests/integration.spec.ts b/tests/integration.spec.ts index 997d646..067ad89 100644 --- a/tests/integration.spec.ts +++ b/tests/integration.spec.ts @@ -13,86 +13,176 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { test, expect, PackageManager, assertLockFilesExist } from './baseFixtures'; +import { + test, + expect, + PackageManager, + assertLockFilesExist, +} from './baseFixtures'; import path from 'path'; import fs from 'fs'; -test('should generate a project in the current directory', async ({ run, packageManager }) => { +test('should generate a project in the current directory', async ({ + run, + packageManager, +}) => { test.slow(); - const { exitCode, dir, stdout } = await run([], { installGitHubActions: true, testDir: 'tests', language: 'TypeScript', installPlaywrightDependencies: false, installPlaywrightBrowsers: true }); + const {exitCode, dir, stdout} = await run([], { + installGitHubActions: true, + testDir: 'tests', + language: 'TypeScript', + installPlaywrightDependencies: false, + installPlaywrightBrowsers: true, + }); expect(exitCode).toBe(0); expect(fs.existsSync(path.join(dir, 'tests/example.spec.ts'))).toBeTruthy(); expect(fs.existsSync(path.join(dir, 'package.json'))).toBeTruthy(); assertLockFilesExist(dir, packageManager); expect(fs.existsSync(path.join(dir, 'playwright.config.ts'))).toBeTruthy(); - const playwrightConfigContent = fs.readFileSync(path.join(dir, 'playwright.config.ts'), 'utf8'); + const playwrightConfigContent = fs.readFileSync( + path.join(dir, 'playwright.config.ts'), + 'utf8' + ); expect(playwrightConfigContent).toContain('tests'); - expect(fs.existsSync(path.join(dir, '.github/workflows/playwright.yml'))).toBeTruthy(); + expect( + fs.existsSync(path.join(dir, '.github/workflows/playwright.yml')) + ).toBeTruthy(); expect(fs.existsSync(path.join(dir, '.gitignore'))).toBeTruthy(); if (packageManager === 'npm') { expect(stdout).toContain('Initializing NPM project (npm init -y)…'); - expect(stdout).toContain('Installing Playwright Test (npm install --save-dev @playwright/test)…'); + expect(stdout).toContain( + 'Installing Playwright Test (npm install --save-dev @playwright/test)…' + ); } else if (packageManager === 'yarn') { expect(stdout).toContain('Initializing Yarn project (yarn init -y)…'); - expect(stdout).toContain('Installing Playwright Test (yarn add --dev @playwright/test)…'); + expect(stdout).toContain( + 'Installing Playwright Test (yarn add --dev @playwright/test)…' + ); } else if (packageManager === 'pnpm') { expect(stdout).toContain('pnpm init'); // pnpm command outputs name in different case, hence we are not testing the whole string - expect(stdout).toContain('Installing Playwright Test (pnpm add --save-dev @playwright/test)…'); + expect(stdout).toContain( + 'Installing Playwright Test (pnpm add --save-dev @playwright/test)…' + ); + } else if (packageManager === 'bun') { + expect(stdout).toContain('bun init'); // pnpm command outputs name in different case, hence we are not testing the whole string + expect(stdout).toContain( + 'Installing Playwright Test (bun add --dev @playwright/test)…' + ); } - expect(stdout).toContain('npx playwright install' + process.platform === 'linux' ? ' --with-deps' : ''); + expect(stdout).toContain( + 'npx playwright install' + process.platform === 'linux' + ? ' --with-deps' + : '' + ); }); -test('should generate a project in a given directory', async ({ run, packageManager }) => { - const { exitCode, dir } = await run(['foobar'], { installGitHubActions: true, testDir: 'tests', language: 'TypeScript', installPlaywrightDependencies: false, installPlaywrightBrowsers: true }); +test('should generate a project in a given directory', async ({ + run, + packageManager, +}) => { + const {exitCode, dir} = await run(['foobar'], { + installGitHubActions: true, + testDir: 'tests', + language: 'TypeScript', + installPlaywrightDependencies: false, + installPlaywrightBrowsers: true, + }); expect(exitCode).toBe(0); - expect(fs.existsSync(path.join(dir, 'foobar/tests/example.spec.ts'))).toBeTruthy(); + expect( + fs.existsSync(path.join(dir, 'foobar/tests/example.spec.ts')) + ).toBeTruthy(); expect(fs.existsSync(path.join(dir, 'foobar/package.json'))).toBeTruthy(); assertLockFilesExist(path.join(dir, 'foobar'), packageManager); - expect(fs.existsSync(path.join(dir, 'foobar/playwright.config.ts'))).toBeTruthy(); - expect(fs.existsSync(path.join(dir, 'foobar/.github/workflows/playwright.yml'))).toBeTruthy(); + expect( + fs.existsSync(path.join(dir, 'foobar/playwright.config.ts')) + ).toBeTruthy(); + expect( + fs.existsSync(path.join(dir, 'foobar/.github/workflows/playwright.yml')) + ).toBeTruthy(); }); -test('should generate a project with JavaScript and without GHA', async ({ run, packageManager }) => { - const { exitCode, dir } = await run([], { installGitHubActions: false, testDir: 'tests', language: 'JavaScript', installPlaywrightDependencies: false, installPlaywrightBrowsers: true }); +test('should generate a project with JavaScript and without GHA', async ({ + run, + packageManager, +}) => { + const {exitCode, dir} = await run([], { + installGitHubActions: false, + testDir: 'tests', + language: 'JavaScript', + installPlaywrightDependencies: false, + installPlaywrightBrowsers: true, + }); expect(exitCode).toBe(0); expect(fs.existsSync(path.join(dir, 'tests/example.spec.js'))).toBeTruthy(); expect(fs.existsSync(path.join(dir, 'package.json'))).toBeTruthy(); assertLockFilesExist(dir, packageManager); expect(fs.existsSync(path.join(dir, 'playwright.config.js'))).toBeTruthy(); - expect(fs.existsSync(path.join(dir, '.github/workflows/playwright.yml'))).toBeFalsy(); + expect( + fs.existsSync(path.join(dir, '.github/workflows/playwright.yml')) + ).toBeFalsy(); }); -test('should generate be able to run TS examples successfully', async ({ run, packageManager }) => { +test('should generate be able to run TS examples successfully', async ({ + run, + packageManager, +}) => { test.slow(); - const { exitCode, dir, exec } = await run([], { installGitHubActions: false, testDir: 'tests', language: 'TypeScript', installPlaywrightDependencies: false, installPlaywrightBrowsers: true }); + const {exitCode, dir, exec} = await run([], { + installGitHubActions: false, + testDir: 'tests', + language: 'TypeScript', + installPlaywrightDependencies: false, + installPlaywrightBrowsers: true, + }); expect(exitCode).toBe(0); expect(fs.existsSync(path.join(dir, 'tests/example.spec.ts'))).toBeTruthy(); expect(fs.existsSync(path.join(dir, 'package.json'))).toBeTruthy(); expect(fs.existsSync(path.join(dir, 'playwright.config.ts'))).toBeTruthy(); { - const { code } = await exec(packageManagerToNpxCommand(packageManager), ['playwright', 'install-deps']); + const {code} = await exec(packageManagerToNpxCommand(packageManager), [ + 'playwright', + 'install-deps', + ]); expect(code).toBe(0); } - const { code } = await exec(packageManagerToNpxCommand(packageManager), ['playwright', 'test']); + const {code} = await exec(packageManagerToNpxCommand(packageManager), [ + 'playwright', + 'test', + ]); expect(code).toBe(0); }); -test('should generate be able to run JS examples successfully', async ({ run, packageManager }) => { +test('should generate be able to run JS examples successfully', async ({ + run, + packageManager, +}) => { test.slow(); - const { exitCode, dir, exec } = await run([], { installGitHubActions: false, testDir: 'tests', language: 'JavaScript', installPlaywrightDependencies: false, installPlaywrightBrowsers: true }); + const {exitCode, dir, exec} = await run([], { + installGitHubActions: false, + testDir: 'tests', + language: 'JavaScript', + installPlaywrightDependencies: false, + installPlaywrightBrowsers: true, + }); expect(exitCode).toBe(0); expect(fs.existsSync(path.join(dir, 'tests/example.spec.js'))).toBeTruthy(); expect(fs.existsSync(path.join(dir, 'package.json'))).toBeTruthy(); expect(fs.existsSync(path.join(dir, 'playwright.config.js'))).toBeTruthy(); { - const { code } = await exec(packageManagerToNpxCommand(packageManager), ['playwright', 'install-deps']); + const {code} = await exec(packageManagerToNpxCommand(packageManager), [ + 'playwright', + 'install-deps', + ]); expect(code).toBe(0); } - const { code } = await exec(packageManagerToNpxCommand(packageManager), ['playwright', 'test']); + const {code} = await exec( + packageManagerToNpxCommand(packageManager), + ['playwright', 'test'] + ); expect(code).toBe(0); }); @@ -104,5 +194,7 @@ function packageManagerToNpxCommand(packageManager: PackageManager): string { return 'yarn'; case 'pnpm': return 'pnpm dlx'; + case 'bun': + return 'bunx'; } }