letsrunit 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +9 -9
- package/dist/bin.js.map +1 -1
- package/dist/index.js +9 -9
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/init.ts +3 -3
- package/src/setup/cucumber.ts +6 -6
package/dist/bin.js
CHANGED
|
@@ -50,7 +50,7 @@ function installCli(env) {
|
|
|
50
50
|
// src/setup/cucumber.ts
|
|
51
51
|
import { existsSync as existsSync3, mkdirSync, readdirSync, readFileSync as readFileSync2, writeFileSync } from "fs";
|
|
52
52
|
import { join as join3 } from "path";
|
|
53
|
-
var BDD_IMPORT = "@letsrunit/
|
|
53
|
+
var BDD_IMPORT = "@letsrunit/cucumber";
|
|
54
54
|
var CUCUMBER_CONFIG = `export default {
|
|
55
55
|
require: ['features/support/**/*.js'],
|
|
56
56
|
worldParameters: {
|
|
@@ -79,13 +79,13 @@ function installBdd(env) {
|
|
|
79
79
|
const pkgPath = join3(env.cwd, "package.json");
|
|
80
80
|
if (!existsSync3(pkgPath)) return false;
|
|
81
81
|
const pkg = JSON.parse(readFileSync2(pkgPath, "utf-8"));
|
|
82
|
-
const alreadyInstalled = "@letsrunit/
|
|
82
|
+
const alreadyInstalled = "@letsrunit/cucumber" in (pkg.devDependencies ?? {}) || "@letsrunit/cucumber" in (pkg.dependencies ?? {});
|
|
83
83
|
if (alreadyInstalled) return false;
|
|
84
84
|
execPm(env, {
|
|
85
|
-
npm: "install --save-dev @letsrunit/
|
|
86
|
-
yarn: "add --dev @letsrunit/
|
|
87
|
-
pnpm: "add -D @letsrunit/
|
|
88
|
-
bun: "add -d @letsrunit/
|
|
85
|
+
npm: "install --save-dev @letsrunit/cucumber",
|
|
86
|
+
yarn: "add --dev @letsrunit/cucumber",
|
|
87
|
+
pnpm: "add -D @letsrunit/cucumber",
|
|
88
|
+
bun: "add -d @letsrunit/cucumber"
|
|
89
89
|
});
|
|
90
90
|
return true;
|
|
91
91
|
}
|
|
@@ -217,7 +217,7 @@ function installPlaywrightBrowsers(env) {
|
|
|
217
217
|
}
|
|
218
218
|
|
|
219
219
|
// src/init.ts
|
|
220
|
-
var BDD_IMPORT2 = "@letsrunit/
|
|
220
|
+
var BDD_IMPORT2 = "@letsrunit/cucumber";
|
|
221
221
|
async function stepInstallCli(env) {
|
|
222
222
|
if (isCliInstalled(env)) {
|
|
223
223
|
log.success("@letsrunit/cli already installed");
|
|
@@ -247,11 +247,11 @@ async function stepEnsureCucumber(env, { yes: yes2 }) {
|
|
|
247
247
|
}
|
|
248
248
|
function stepSetupCucumber(env) {
|
|
249
249
|
const result = setupCucumber(env);
|
|
250
|
-
if (result.bddInstalled) log.success("@letsrunit/
|
|
250
|
+
if (result.bddInstalled) log.success("@letsrunit/cucumber installed");
|
|
251
251
|
if (result.configResult === "created") {
|
|
252
252
|
log.success("features/support/world.js created");
|
|
253
253
|
} else if (result.configResult === "needs-manual-update") {
|
|
254
|
-
log.warn("features/support/world.js exists but does not import @letsrunit/
|
|
254
|
+
log.warn("features/support/world.js exists but does not import @letsrunit/cucumber.");
|
|
255
255
|
note(`Add "import '${BDD_IMPORT2}';" to features/support/world.js`, "Action required");
|
|
256
256
|
}
|
|
257
257
|
if (result.featuresCreated) log.success("features/ directory created with example.feature");
|
package/dist/bin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/init.ts","../src/detect.ts","../src/setup/cli.ts","../src/setup/cucumber.ts","../src/setup/github-actions.ts","../src/setup/playwright.ts","../src/bin.ts"],"sourcesContent":["import { confirm, intro, log, note, outro, spinner } from '@clack/prompts';\nimport { detectEnvironment, type Environment } from './detect.js';\nimport { installCli, isCliInstalled } from './setup/cli.js';\nimport { installCucumber, setupCucumber } from './setup/cucumber.js';\nimport { installGithubAction } from './setup/github-actions.js';\nimport { hasPlaywrightBrowsers, installPlaywrightBrowsers } from './setup/playwright.js';\n\nconst BDD_IMPORT = '@letsrunit/bdd/define';\n\nexport interface InitOptions {\n yes?: boolean;\n}\n\nasync function stepInstallCli(env: Environment): Promise<void> {\n if (isCliInstalled(env)) {\n log.success('@letsrunit/cli already installed');\n return;\n }\n\n const s = spinner();\n s.start('Installing @letsrunit/cli…');\n installCli(env);\n s.stop('@letsrunit/cli installed');\n}\n\nasync function stepEnsureCucumber(env: Environment, { yes }: InitOptions): Promise<boolean> {\n if (env.hasCucumber) return true;\n\n if (!yes && !env.isInteractive) {\n log.warn('@cucumber/cucumber not found. Install it to use letsrunit with Cucumber:');\n note('npm install --save-dev @cucumber/cucumber\\nThen run: npx letsrunit init', 'Setup Cucumber');\n return false;\n }\n\n if (!yes) {\n const install = await confirm({ message: '@cucumber/cucumber not found. Install it now?' });\n if (install !== true) return false;\n }\n\n const s = spinner();\n s.start('Installing @cucumber/cucumber…');\n installCucumber(env);\n s.stop('@cucumber/cucumber installed');\n return true;\n}\n\nfunction stepSetupCucumber(env: Environment): void {\n const result = setupCucumber(env);\n\n if (result.bddInstalled) log.success('@letsrunit/bdd installed');\n\n if (result.configResult === 'created') {\n log.success('features/support/world.js created');\n } else if (result.configResult === 'needs-manual-update') {\n log.warn('features/support/world.js exists but does not import @letsrunit/bdd.');\n note(`Add \"import '${BDD_IMPORT}';\" to features/support/world.js`, 'Action required');\n }\n\n if (result.featuresCreated) log.success('features/ directory created with example.feature');\n}\n\nasync function stepCheckPlaywrightBrowsers(env: Environment, { yes }: InitOptions): Promise<void> {\n if (hasPlaywrightBrowsers(env)) return;\n\n if (!yes && !env.isInteractive) {\n log.warn('Playwright Chromium browser not found.');\n note('npx playwright install chromium', 'Run to install browsers');\n return;\n }\n\n if (!yes) {\n const install = await confirm({ message: 'Playwright Chromium browser not found. Install it now?' });\n if (install !== true) return;\n }\n\n const s = spinner();\n s.start('Installing Playwright Chromium…');\n installPlaywrightBrowsers(env);\n s.stop('Playwright Chromium installed');\n}\n\nasync function stepAddGithubAction(env: Environment, { yes }: InitOptions): Promise<void> {\n if (!yes && !env.isInteractive) return;\n\n if (!yes) {\n const addAction = await confirm({ message: 'Add a GitHub Action to run features on push?' });\n if (addAction !== true) return;\n }\n\n const result = installGithubAction(env);\n if (result === 'created') {\n log.success('.github/workflows/letsrunit.yml created');\n } else {\n log.info('.github/workflows/letsrunit.yml already exists, skipped');\n }\n}\n\nexport async function init(options: InitOptions = {}): Promise<void> {\n intro('letsrunit init');\n\n const env = detectEnvironment();\n\n await stepInstallCli(env);\n\n const hasCucumber = await stepEnsureCucumber(env, options);\n if (hasCucumber) {\n stepSetupCucumber(env);\n await stepCheckPlaywrightBrowsers(env, options);\n await stepAddGithubAction(env, options);\n }\n\n outro('All done! Run npx letsrunit --help to get started.');\n}\n","import { execSync } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\n\nexport type PackageManager = 'yarn' | 'pnpm' | 'bun' | 'npm';\n\nexport interface Environment {\n isInteractive: boolean;\n packageManager: PackageManager;\n nodeVersion: number;\n hasCucumber: boolean;\n cwd: string;\n}\n\nexport interface PackageManagerArgs {\n npm: string;\n yarn: string;\n pnpm: string;\n bun: string;\n}\n\nexport function detectEnvironment(): Environment {\n const cwd = process.cwd();\n const isInteractive = Boolean(process.stdout.isTTY && process.stdin.isTTY);\n\n let packageManager: PackageManager = 'npm';\n if (existsSync(join(cwd, 'yarn.lock'))) packageManager = 'yarn';\n else if (existsSync(join(cwd, 'pnpm-lock.yaml'))) packageManager = 'pnpm';\n else if (existsSync(join(cwd, 'bun.lockb')) || existsSync(join(cwd, 'bun.lock'))) packageManager = 'bun';\n\n const nodeVersion = parseInt(process.version.slice(1), 10);\n const hasCucumber = existsSync(join(cwd, 'node_modules', '@cucumber', 'cucumber', 'package.json'));\n\n return { isInteractive, packageManager, nodeVersion, hasCucumber, cwd };\n}\n\nfunction pmCmd(pm: string, args: PackageManagerArgs): string {\n if (pm === 'yarn') return `yarn ${args.yarn}`;\n if (pm === 'pnpm') return `pnpm ${args.pnpm}`;\n if (pm === 'bun') return `bun ${args.bun}`;\n return `npm ${args.npm}`;\n}\n\nexport function execPm(env: Pick<Environment, 'packageManager' | 'cwd'>, args: PackageManagerArgs) {\n const cmd = pmCmd(env.packageManager, args);\n return execSync(cmd, { stdio: 'inherit', cwd: env.cwd });\n}\n","import { existsSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { type Environment, execPm } from '../detect.js';\n\nexport function isCliInstalled({ cwd }: Pick<Environment, 'cwd'>): boolean {\n const pkgPath = join(cwd, 'package.json');\n if (!existsSync(pkgPath)) return false;\n\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')) as {\n devDependencies?: Record<string, string>;\n dependencies?: Record<string, string>;\n };\n\n return '@letsrunit/cli' in (pkg.devDependencies ?? {}) || '@letsrunit/cli' in (pkg.dependencies ?? {});\n}\n\nexport function installCli(env: Pick<Environment, 'packageManager' | 'cwd'>): void {\n execPm(env, {\n npm: 'install --save-dev @letsrunit/cli',\n yarn: 'add --dev @letsrunit/cli',\n pnpm: 'add -D @letsrunit/cli',\n bun: 'add -d @letsrunit/cli',\n });\n}\n","import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { type Environment, execPm } from '../detect.js';\n\nconst BDD_IMPORT = '@letsrunit/bdd/define';\n\nconst CUCUMBER_CONFIG = `export default {\n require: ['features/support/**/*.js'],\n worldParameters: {\n baseURL: 'http://localhost:3000',\n },\n};\n`;\n\nconst SUPPORT_FILE = `import { setDefaultTimeout } from '@cucumber/cucumber';\nimport '${BDD_IMPORT}';\n\nsetDefaultTimeout(30_000);\n`;\n\nconst EXAMPLE_FEATURE = `Feature: Example\n Scenario: Homepage loads\n Given I'm on the homepage\n`;\n\nexport type CucumberConfigResult = 'created' | 'skipped' | 'needs-manual-update';\n\nexport interface CucumberSetupResult {\n bddInstalled: boolean;\n configResult: CucumberConfigResult;\n featuresCreated: boolean;\n}\n\nexport function installCucumber(env: Pick<Environment, 'packageManager' | 'cwd'>): void {\n execPm(env, {\n npm: 'install --save-dev @cucumber/cucumber',\n yarn: 'add --dev @cucumber/cucumber',\n pnpm: 'add -D @cucumber/cucumber',\n bun: 'add -d @cucumber/cucumber',\n });\n}\n\nfunction installBdd(env: Pick<Environment, 'packageManager' | 'cwd'>): boolean {\n const pkgPath = join(env.cwd, 'package.json');\n if (!existsSync(pkgPath)) return false;\n\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')) as {\n devDependencies?: Record<string, string>;\n dependencies?: Record<string, string>;\n };\n\n const alreadyInstalled =\n '@letsrunit/bdd' in (pkg.devDependencies ?? {}) || '@letsrunit/bdd' in (pkg.dependencies ?? {});\n\n if (alreadyInstalled) return false;\n\n execPm(env, {\n npm: 'install --save-dev @letsrunit/bdd',\n yarn: 'add --dev @letsrunit/bdd',\n pnpm: 'add -D @letsrunit/bdd',\n bun: 'add -d @letsrunit/bdd',\n });\n\n return true;\n}\n\nfunction setupCucumberConfig({ cwd }: Pick<Environment, 'cwd'>): CucumberConfigResult {\n const supportDir = join(cwd, 'features', 'support');\n const supportPath = join(supportDir, 'world.js');\n\n if (existsSync(supportPath)) {\n const content = readFileSync(supportPath, 'utf-8');\n if (content.includes(BDD_IMPORT)) return 'skipped';\n return 'needs-manual-update';\n }\n\n const configPath = join(cwd, 'cucumber.js');\n if (!existsSync(configPath)) {\n writeFileSync(configPath, CUCUMBER_CONFIG, 'utf-8');\n }\n\n mkdirSync(supportDir, { recursive: true });\n writeFileSync(supportPath, SUPPORT_FILE, 'utf-8');\n return 'created';\n}\n\nfunction setupFeaturesDir({ cwd }: Pick<Environment, 'cwd'>): boolean {\n if (existsSync(join(cwd, 'features'))) {\n try {\n const hasFeatureFiles = readdirSync(join(cwd, 'features')).some((f) => f.endsWith('.feature'));\n if (hasFeatureFiles) return false;\n } catch {\n return false;\n }\n }\n\n try {\n const hasFeatureAtRoot = readdirSync(cwd).some((f) => f.endsWith('.feature'));\n if (hasFeatureAtRoot) return false;\n } catch {\n return false;\n }\n\n mkdirSync(join(cwd, 'features'), { recursive: true });\n writeFileSync(join(cwd, 'features', 'example.feature'), EXAMPLE_FEATURE, 'utf-8');\n return true;\n}\n\nexport function setupCucumber(env: Pick<Environment, 'packageManager' | 'cwd'>): CucumberSetupResult {\n const bddInstalled = installBdd(env);\n const configResult = setupCucumberConfig(env);\n const featuresCreated = setupFeaturesDir(env);\n return { bddInstalled, configResult, featuresCreated };\n}\n","import { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { Environment } from '../detect.js';\n\nexport type GithubActionsResult = 'created' | 'skipped';\n\nfunction setupStepsFor({ packageManager, nodeVersion }: Pick<Environment, 'packageManager' | 'nodeVersion'>): string {\n if (packageManager === 'yarn') return `\\\n - name: Enable Corepack\n run: corepack enable\n - uses: actions/setup-node@v4\n with:\n node-version: ${nodeVersion}\n cache: yarn\n - name: Install dependencies\n run: yarn install --immutable`;\n if (packageManager === 'pnpm') return `\\\n - uses: pnpm/action-setup@v4\n - uses: actions/setup-node@v4\n with:\n node-version: ${nodeVersion}\n cache: pnpm\n - name: Install dependencies\n run: pnpm install --frozen-lockfile`;\n if (packageManager === 'bun') return `\\\n - uses: oven-sh/setup-bun@v2\n - name: Install dependencies\n run: bun install --frozen-lockfile`;\n return `\\\n - uses: actions/setup-node@v4\n with:\n node-version: ${nodeVersion}\n cache: npm\n - name: Install dependencies\n run: npm ci`;\n}\n\nfunction workflowYaml(env: Pick<Environment, 'packageManager' | 'nodeVersion'>): string {\n const setupSteps = setupStepsFor(env);\n\n return `name: Features\non:\n push:\n branches: [main]\n pull_request:\n branches: [main]\njobs:\n features:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n${setupSteps}\n - name: Install Playwright browsers\n run: npx playwright install chromium --with-deps\n - name: Run features\n run: npx cucumber-js\n`;\n}\n\nexport function installGithubAction(env: Pick<Environment, 'packageManager' | 'nodeVersion' | 'cwd'>): GithubActionsResult {\n const workflowDir = join(env.cwd, '.github', 'workflows');\n const workflowPath = join(workflowDir, 'letsrunit.yml');\n\n if (existsSync(workflowPath)) return 'skipped';\n\n mkdirSync(workflowDir, { recursive: true });\n writeFileSync(workflowPath, workflowYaml(env), 'utf-8');\n return 'created';\n}\n","import { execSync } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { type Environment, execPm } from '../detect.js';\n\nexport function hasPlaywrightBrowsers({ cwd }: Pick<Environment, 'cwd'>): boolean {\n if (!existsSync(join(cwd, 'node_modules', 'playwright-core', 'package.json'))) {\n return false;\n }\n try {\n const execPath = execSync(\n `node -e \"console.log(require('playwright-core').chromium.executablePath())\"`,\n { cwd, stdio: 'pipe', encoding: 'utf-8' },\n ).trim();\n return existsSync(execPath);\n } catch {\n return false;\n }\n}\n\nexport function installPlaywrightBrowsers(env: Pick<Environment, 'packageManager' | 'cwd'>): void {\n execPm(env, {\n npm: 'exec playwright install chromium',\n yarn: 'exec playwright install chromium',\n pnpm: 'exec playwright install chromium',\n bun: 'x playwright install chromium',\n });\n}\n","import { init } from './init.js';\n\nconst args = process.argv.slice(2);\nconst command = args.find((a) => !a.startsWith('-')) ?? 'init';\nconst yes = args.includes('--yes') || args.includes('-y');\n\nif (command === 'init') {\n init({ yes }).catch((err: unknown) => {\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n });\n} else {\n console.error(`Unknown command: ${command}`);\n console.error('Usage: letsrunit init [--yes]');\n process.exit(1);\n}\n"],"mappings":"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","names":["args","existsSync","join","join","existsSync","existsSync","readFileSync","join","join","existsSync","readFileSync","existsSync","mkdirSync","writeFileSync","join","execSync","existsSync","join","existsSync","join","execSync","BDD_IMPORT","yes"]}
|
|
1
|
+
{"version":3,"sources":["../src/init.ts","../src/detect.ts","../src/setup/cli.ts","../src/setup/cucumber.ts","../src/setup/github-actions.ts","../src/setup/playwright.ts","../src/bin.ts"],"sourcesContent":["import { confirm, intro, log, note, outro, spinner } from '@clack/prompts';\nimport { detectEnvironment, type Environment } from './detect.js';\nimport { installCli, isCliInstalled } from './setup/cli.js';\nimport { installCucumber, setupCucumber } from './setup/cucumber.js';\nimport { installGithubAction } from './setup/github-actions.js';\nimport { hasPlaywrightBrowsers, installPlaywrightBrowsers } from './setup/playwright.js';\n\nconst BDD_IMPORT = '@letsrunit/cucumber';\n\nexport interface InitOptions {\n yes?: boolean;\n}\n\nasync function stepInstallCli(env: Environment): Promise<void> {\n if (isCliInstalled(env)) {\n log.success('@letsrunit/cli already installed');\n return;\n }\n\n const s = spinner();\n s.start('Installing @letsrunit/cli…');\n installCli(env);\n s.stop('@letsrunit/cli installed');\n}\n\nasync function stepEnsureCucumber(env: Environment, { yes }: InitOptions): Promise<boolean> {\n if (env.hasCucumber) return true;\n\n if (!yes && !env.isInteractive) {\n log.warn('@cucumber/cucumber not found. Install it to use letsrunit with Cucumber:');\n note('npm install --save-dev @cucumber/cucumber\\nThen run: npx letsrunit init', 'Setup Cucumber');\n return false;\n }\n\n if (!yes) {\n const install = await confirm({ message: '@cucumber/cucumber not found. Install it now?' });\n if (install !== true) return false;\n }\n\n const s = spinner();\n s.start('Installing @cucumber/cucumber…');\n installCucumber(env);\n s.stop('@cucumber/cucumber installed');\n return true;\n}\n\nfunction stepSetupCucumber(env: Environment): void {\n const result = setupCucumber(env);\n\n if (result.bddInstalled) log.success('@letsrunit/cucumber installed');\n\n if (result.configResult === 'created') {\n log.success('features/support/world.js created');\n } else if (result.configResult === 'needs-manual-update') {\n log.warn('features/support/world.js exists but does not import @letsrunit/cucumber.');\n note(`Add \"import '${BDD_IMPORT}';\" to features/support/world.js`, 'Action required');\n }\n\n if (result.featuresCreated) log.success('features/ directory created with example.feature');\n}\n\nasync function stepCheckPlaywrightBrowsers(env: Environment, { yes }: InitOptions): Promise<void> {\n if (hasPlaywrightBrowsers(env)) return;\n\n if (!yes && !env.isInteractive) {\n log.warn('Playwright Chromium browser not found.');\n note('npx playwright install chromium', 'Run to install browsers');\n return;\n }\n\n if (!yes) {\n const install = await confirm({ message: 'Playwright Chromium browser not found. Install it now?' });\n if (install !== true) return;\n }\n\n const s = spinner();\n s.start('Installing Playwright Chromium…');\n installPlaywrightBrowsers(env);\n s.stop('Playwright Chromium installed');\n}\n\nasync function stepAddGithubAction(env: Environment, { yes }: InitOptions): Promise<void> {\n if (!yes && !env.isInteractive) return;\n\n if (!yes) {\n const addAction = await confirm({ message: 'Add a GitHub Action to run features on push?' });\n if (addAction !== true) return;\n }\n\n const result = installGithubAction(env);\n if (result === 'created') {\n log.success('.github/workflows/letsrunit.yml created');\n } else {\n log.info('.github/workflows/letsrunit.yml already exists, skipped');\n }\n}\n\nexport async function init(options: InitOptions = {}): Promise<void> {\n intro('letsrunit init');\n\n const env = detectEnvironment();\n\n await stepInstallCli(env);\n\n const hasCucumber = await stepEnsureCucumber(env, options);\n if (hasCucumber) {\n stepSetupCucumber(env);\n await stepCheckPlaywrightBrowsers(env, options);\n await stepAddGithubAction(env, options);\n }\n\n outro('All done! Run npx letsrunit --help to get started.');\n}\n","import { execSync } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\n\nexport type PackageManager = 'yarn' | 'pnpm' | 'bun' | 'npm';\n\nexport interface Environment {\n isInteractive: boolean;\n packageManager: PackageManager;\n nodeVersion: number;\n hasCucumber: boolean;\n cwd: string;\n}\n\nexport interface PackageManagerArgs {\n npm: string;\n yarn: string;\n pnpm: string;\n bun: string;\n}\n\nexport function detectEnvironment(): Environment {\n const cwd = process.cwd();\n const isInteractive = Boolean(process.stdout.isTTY && process.stdin.isTTY);\n\n let packageManager: PackageManager = 'npm';\n if (existsSync(join(cwd, 'yarn.lock'))) packageManager = 'yarn';\n else if (existsSync(join(cwd, 'pnpm-lock.yaml'))) packageManager = 'pnpm';\n else if (existsSync(join(cwd, 'bun.lockb')) || existsSync(join(cwd, 'bun.lock'))) packageManager = 'bun';\n\n const nodeVersion = parseInt(process.version.slice(1), 10);\n const hasCucumber = existsSync(join(cwd, 'node_modules', '@cucumber', 'cucumber', 'package.json'));\n\n return { isInteractive, packageManager, nodeVersion, hasCucumber, cwd };\n}\n\nfunction pmCmd(pm: string, args: PackageManagerArgs): string {\n if (pm === 'yarn') return `yarn ${args.yarn}`;\n if (pm === 'pnpm') return `pnpm ${args.pnpm}`;\n if (pm === 'bun') return `bun ${args.bun}`;\n return `npm ${args.npm}`;\n}\n\nexport function execPm(env: Pick<Environment, 'packageManager' | 'cwd'>, args: PackageManagerArgs) {\n const cmd = pmCmd(env.packageManager, args);\n return execSync(cmd, { stdio: 'inherit', cwd: env.cwd });\n}\n","import { existsSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { type Environment, execPm } from '../detect.js';\n\nexport function isCliInstalled({ cwd }: Pick<Environment, 'cwd'>): boolean {\n const pkgPath = join(cwd, 'package.json');\n if (!existsSync(pkgPath)) return false;\n\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')) as {\n devDependencies?: Record<string, string>;\n dependencies?: Record<string, string>;\n };\n\n return '@letsrunit/cli' in (pkg.devDependencies ?? {}) || '@letsrunit/cli' in (pkg.dependencies ?? {});\n}\n\nexport function installCli(env: Pick<Environment, 'packageManager' | 'cwd'>): void {\n execPm(env, {\n npm: 'install --save-dev @letsrunit/cli',\n yarn: 'add --dev @letsrunit/cli',\n pnpm: 'add -D @letsrunit/cli',\n bun: 'add -d @letsrunit/cli',\n });\n}\n","import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { type Environment, execPm } from '../detect.js';\n\nconst BDD_IMPORT = '@letsrunit/cucumber';\n\nconst CUCUMBER_CONFIG = `export default {\n require: ['features/support/**/*.js'],\n worldParameters: {\n baseURL: 'http://localhost:3000',\n },\n};\n`;\n\nconst SUPPORT_FILE = `import { setDefaultTimeout } from '@cucumber/cucumber';\nimport '${BDD_IMPORT}';\n\nsetDefaultTimeout(30_000);\n`;\n\nconst EXAMPLE_FEATURE = `Feature: Example\n Scenario: Homepage loads\n Given I'm on the homepage\n`;\n\nexport type CucumberConfigResult = 'created' | 'skipped' | 'needs-manual-update';\n\nexport interface CucumberSetupResult {\n bddInstalled: boolean;\n configResult: CucumberConfigResult;\n featuresCreated: boolean;\n}\n\nexport function installCucumber(env: Pick<Environment, 'packageManager' | 'cwd'>): void {\n execPm(env, {\n npm: 'install --save-dev @cucumber/cucumber',\n yarn: 'add --dev @cucumber/cucumber',\n pnpm: 'add -D @cucumber/cucumber',\n bun: 'add -d @cucumber/cucumber',\n });\n}\n\nfunction installBdd(env: Pick<Environment, 'packageManager' | 'cwd'>): boolean {\n const pkgPath = join(env.cwd, 'package.json');\n if (!existsSync(pkgPath)) return false;\n\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')) as {\n devDependencies?: Record<string, string>;\n dependencies?: Record<string, string>;\n };\n\n const alreadyInstalled =\n '@letsrunit/cucumber' in (pkg.devDependencies ?? {}) || '@letsrunit/cucumber' in (pkg.dependencies ?? {});\n\n if (alreadyInstalled) return false;\n\n execPm(env, {\n npm: 'install --save-dev @letsrunit/cucumber',\n yarn: 'add --dev @letsrunit/cucumber',\n pnpm: 'add -D @letsrunit/cucumber',\n bun: 'add -d @letsrunit/cucumber',\n });\n\n return true;\n}\n\nfunction setupCucumberConfig({ cwd }: Pick<Environment, 'cwd'>): CucumberConfigResult {\n const supportDir = join(cwd, 'features', 'support');\n const supportPath = join(supportDir, 'world.js');\n\n if (existsSync(supportPath)) {\n const content = readFileSync(supportPath, 'utf-8');\n if (content.includes(BDD_IMPORT)) return 'skipped';\n return 'needs-manual-update';\n }\n\n const configPath = join(cwd, 'cucumber.js');\n if (!existsSync(configPath)) {\n writeFileSync(configPath, CUCUMBER_CONFIG, 'utf-8');\n }\n\n mkdirSync(supportDir, { recursive: true });\n writeFileSync(supportPath, SUPPORT_FILE, 'utf-8');\n return 'created';\n}\n\nfunction setupFeaturesDir({ cwd }: Pick<Environment, 'cwd'>): boolean {\n if (existsSync(join(cwd, 'features'))) {\n try {\n const hasFeatureFiles = readdirSync(join(cwd, 'features')).some((f) => f.endsWith('.feature'));\n if (hasFeatureFiles) return false;\n } catch {\n return false;\n }\n }\n\n try {\n const hasFeatureAtRoot = readdirSync(cwd).some((f) => f.endsWith('.feature'));\n if (hasFeatureAtRoot) return false;\n } catch {\n return false;\n }\n\n mkdirSync(join(cwd, 'features'), { recursive: true });\n writeFileSync(join(cwd, 'features', 'example.feature'), EXAMPLE_FEATURE, 'utf-8');\n return true;\n}\n\nexport function setupCucumber(env: Pick<Environment, 'packageManager' | 'cwd'>): CucumberSetupResult {\n const bddInstalled = installBdd(env);\n const configResult = setupCucumberConfig(env);\n const featuresCreated = setupFeaturesDir(env);\n return { bddInstalled, configResult, featuresCreated };\n}\n","import { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { Environment } from '../detect.js';\n\nexport type GithubActionsResult = 'created' | 'skipped';\n\nfunction setupStepsFor({ packageManager, nodeVersion }: Pick<Environment, 'packageManager' | 'nodeVersion'>): string {\n if (packageManager === 'yarn') return `\\\n - name: Enable Corepack\n run: corepack enable\n - uses: actions/setup-node@v4\n with:\n node-version: ${nodeVersion}\n cache: yarn\n - name: Install dependencies\n run: yarn install --immutable`;\n if (packageManager === 'pnpm') return `\\\n - uses: pnpm/action-setup@v4\n - uses: actions/setup-node@v4\n with:\n node-version: ${nodeVersion}\n cache: pnpm\n - name: Install dependencies\n run: pnpm install --frozen-lockfile`;\n if (packageManager === 'bun') return `\\\n - uses: oven-sh/setup-bun@v2\n - name: Install dependencies\n run: bun install --frozen-lockfile`;\n return `\\\n - uses: actions/setup-node@v4\n with:\n node-version: ${nodeVersion}\n cache: npm\n - name: Install dependencies\n run: npm ci`;\n}\n\nfunction workflowYaml(env: Pick<Environment, 'packageManager' | 'nodeVersion'>): string {\n const setupSteps = setupStepsFor(env);\n\n return `name: Features\non:\n push:\n branches: [main]\n pull_request:\n branches: [main]\njobs:\n features:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n${setupSteps}\n - name: Install Playwright browsers\n run: npx playwright install chromium --with-deps\n - name: Run features\n run: npx cucumber-js\n`;\n}\n\nexport function installGithubAction(env: Pick<Environment, 'packageManager' | 'nodeVersion' | 'cwd'>): GithubActionsResult {\n const workflowDir = join(env.cwd, '.github', 'workflows');\n const workflowPath = join(workflowDir, 'letsrunit.yml');\n\n if (existsSync(workflowPath)) return 'skipped';\n\n mkdirSync(workflowDir, { recursive: true });\n writeFileSync(workflowPath, workflowYaml(env), 'utf-8');\n return 'created';\n}\n","import { execSync } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { type Environment, execPm } from '../detect.js';\n\nexport function hasPlaywrightBrowsers({ cwd }: Pick<Environment, 'cwd'>): boolean {\n if (!existsSync(join(cwd, 'node_modules', 'playwright-core', 'package.json'))) {\n return false;\n }\n try {\n const execPath = execSync(\n `node -e \"console.log(require('playwright-core').chromium.executablePath())\"`,\n { cwd, stdio: 'pipe', encoding: 'utf-8' },\n ).trim();\n return existsSync(execPath);\n } catch {\n return false;\n }\n}\n\nexport function installPlaywrightBrowsers(env: Pick<Environment, 'packageManager' | 'cwd'>): void {\n execPm(env, {\n npm: 'exec playwright install chromium',\n yarn: 'exec playwright install chromium',\n pnpm: 'exec playwright install chromium',\n bun: 'x playwright install chromium',\n });\n}\n","import { init } from './init.js';\n\nconst args = process.argv.slice(2);\nconst command = args.find((a) => !a.startsWith('-')) ?? 'init';\nconst yes = args.includes('--yes') || args.includes('-y');\n\nif (command === 'init') {\n init({ yes }).catch((err: unknown) => {\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n });\n} else {\n console.error(`Unknown command: ${command}`);\n console.error('Usage: letsrunit init [--yes]');\n process.exit(1);\n}\n"],"mappings":"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","names":["args","existsSync","join","join","existsSync","existsSync","readFileSync","join","join","existsSync","readFileSync","existsSync","mkdirSync","writeFileSync","join","execSync","existsSync","join","existsSync","join","execSync","BDD_IMPORT","yes"]}
|
package/dist/index.js
CHANGED
|
@@ -48,7 +48,7 @@ function installCli(env) {
|
|
|
48
48
|
// src/setup/cucumber.ts
|
|
49
49
|
import { existsSync as existsSync3, mkdirSync, readdirSync, readFileSync as readFileSync2, writeFileSync } from "fs";
|
|
50
50
|
import { join as join3 } from "path";
|
|
51
|
-
var BDD_IMPORT = "@letsrunit/
|
|
51
|
+
var BDD_IMPORT = "@letsrunit/cucumber";
|
|
52
52
|
var CUCUMBER_CONFIG = `export default {
|
|
53
53
|
require: ['features/support/**/*.js'],
|
|
54
54
|
worldParameters: {
|
|
@@ -77,13 +77,13 @@ function installBdd(env) {
|
|
|
77
77
|
const pkgPath = join3(env.cwd, "package.json");
|
|
78
78
|
if (!existsSync3(pkgPath)) return false;
|
|
79
79
|
const pkg = JSON.parse(readFileSync2(pkgPath, "utf-8"));
|
|
80
|
-
const alreadyInstalled = "@letsrunit/
|
|
80
|
+
const alreadyInstalled = "@letsrunit/cucumber" in (pkg.devDependencies ?? {}) || "@letsrunit/cucumber" in (pkg.dependencies ?? {});
|
|
81
81
|
if (alreadyInstalled) return false;
|
|
82
82
|
execPm(env, {
|
|
83
|
-
npm: "install --save-dev @letsrunit/
|
|
84
|
-
yarn: "add --dev @letsrunit/
|
|
85
|
-
pnpm: "add -D @letsrunit/
|
|
86
|
-
bun: "add -d @letsrunit/
|
|
83
|
+
npm: "install --save-dev @letsrunit/cucumber",
|
|
84
|
+
yarn: "add --dev @letsrunit/cucumber",
|
|
85
|
+
pnpm: "add -D @letsrunit/cucumber",
|
|
86
|
+
bun: "add -d @letsrunit/cucumber"
|
|
87
87
|
});
|
|
88
88
|
return true;
|
|
89
89
|
}
|
|
@@ -215,7 +215,7 @@ function installPlaywrightBrowsers(env) {
|
|
|
215
215
|
}
|
|
216
216
|
|
|
217
217
|
// src/init.ts
|
|
218
|
-
var BDD_IMPORT2 = "@letsrunit/
|
|
218
|
+
var BDD_IMPORT2 = "@letsrunit/cucumber";
|
|
219
219
|
async function stepInstallCli(env) {
|
|
220
220
|
if (isCliInstalled(env)) {
|
|
221
221
|
log.success("@letsrunit/cli already installed");
|
|
@@ -245,11 +245,11 @@ async function stepEnsureCucumber(env, { yes }) {
|
|
|
245
245
|
}
|
|
246
246
|
function stepSetupCucumber(env) {
|
|
247
247
|
const result = setupCucumber(env);
|
|
248
|
-
if (result.bddInstalled) log.success("@letsrunit/
|
|
248
|
+
if (result.bddInstalled) log.success("@letsrunit/cucumber installed");
|
|
249
249
|
if (result.configResult === "created") {
|
|
250
250
|
log.success("features/support/world.js created");
|
|
251
251
|
} else if (result.configResult === "needs-manual-update") {
|
|
252
|
-
log.warn("features/support/world.js exists but does not import @letsrunit/
|
|
252
|
+
log.warn("features/support/world.js exists but does not import @letsrunit/cucumber.");
|
|
253
253
|
note(`Add "import '${BDD_IMPORT2}';" to features/support/world.js`, "Action required");
|
|
254
254
|
}
|
|
255
255
|
if (result.featuresCreated) log.success("features/ directory created with example.feature");
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/init.ts","../src/detect.ts","../src/setup/cli.ts","../src/setup/cucumber.ts","../src/setup/github-actions.ts","../src/setup/playwright.ts"],"sourcesContent":["import { confirm, intro, log, note, outro, spinner } from '@clack/prompts';\nimport { detectEnvironment, type Environment } from './detect.js';\nimport { installCli, isCliInstalled } from './setup/cli.js';\nimport { installCucumber, setupCucumber } from './setup/cucumber.js';\nimport { installGithubAction } from './setup/github-actions.js';\nimport { hasPlaywrightBrowsers, installPlaywrightBrowsers } from './setup/playwright.js';\n\nconst BDD_IMPORT = '@letsrunit/bdd/define';\n\nexport interface InitOptions {\n yes?: boolean;\n}\n\nasync function stepInstallCli(env: Environment): Promise<void> {\n if (isCliInstalled(env)) {\n log.success('@letsrunit/cli already installed');\n return;\n }\n\n const s = spinner();\n s.start('Installing @letsrunit/cli…');\n installCli(env);\n s.stop('@letsrunit/cli installed');\n}\n\nasync function stepEnsureCucumber(env: Environment, { yes }: InitOptions): Promise<boolean> {\n if (env.hasCucumber) return true;\n\n if (!yes && !env.isInteractive) {\n log.warn('@cucumber/cucumber not found. Install it to use letsrunit with Cucumber:');\n note('npm install --save-dev @cucumber/cucumber\\nThen run: npx letsrunit init', 'Setup Cucumber');\n return false;\n }\n\n if (!yes) {\n const install = await confirm({ message: '@cucumber/cucumber not found. Install it now?' });\n if (install !== true) return false;\n }\n\n const s = spinner();\n s.start('Installing @cucumber/cucumber…');\n installCucumber(env);\n s.stop('@cucumber/cucumber installed');\n return true;\n}\n\nfunction stepSetupCucumber(env: Environment): void {\n const result = setupCucumber(env);\n\n if (result.bddInstalled) log.success('@letsrunit/bdd installed');\n\n if (result.configResult === 'created') {\n log.success('features/support/world.js created');\n } else if (result.configResult === 'needs-manual-update') {\n log.warn('features/support/world.js exists but does not import @letsrunit/bdd.');\n note(`Add \"import '${BDD_IMPORT}';\" to features/support/world.js`, 'Action required');\n }\n\n if (result.featuresCreated) log.success('features/ directory created with example.feature');\n}\n\nasync function stepCheckPlaywrightBrowsers(env: Environment, { yes }: InitOptions): Promise<void> {\n if (hasPlaywrightBrowsers(env)) return;\n\n if (!yes && !env.isInteractive) {\n log.warn('Playwright Chromium browser not found.');\n note('npx playwright install chromium', 'Run to install browsers');\n return;\n }\n\n if (!yes) {\n const install = await confirm({ message: 'Playwright Chromium browser not found. Install it now?' });\n if (install !== true) return;\n }\n\n const s = spinner();\n s.start('Installing Playwright Chromium…');\n installPlaywrightBrowsers(env);\n s.stop('Playwright Chromium installed');\n}\n\nasync function stepAddGithubAction(env: Environment, { yes }: InitOptions): Promise<void> {\n if (!yes && !env.isInteractive) return;\n\n if (!yes) {\n const addAction = await confirm({ message: 'Add a GitHub Action to run features on push?' });\n if (addAction !== true) return;\n }\n\n const result = installGithubAction(env);\n if (result === 'created') {\n log.success('.github/workflows/letsrunit.yml created');\n } else {\n log.info('.github/workflows/letsrunit.yml already exists, skipped');\n }\n}\n\nexport async function init(options: InitOptions = {}): Promise<void> {\n intro('letsrunit init');\n\n const env = detectEnvironment();\n\n await stepInstallCli(env);\n\n const hasCucumber = await stepEnsureCucumber(env, options);\n if (hasCucumber) {\n stepSetupCucumber(env);\n await stepCheckPlaywrightBrowsers(env, options);\n await stepAddGithubAction(env, options);\n }\n\n outro('All done! Run npx letsrunit --help to get started.');\n}\n","import { execSync } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\n\nexport type PackageManager = 'yarn' | 'pnpm' | 'bun' | 'npm';\n\nexport interface Environment {\n isInteractive: boolean;\n packageManager: PackageManager;\n nodeVersion: number;\n hasCucumber: boolean;\n cwd: string;\n}\n\nexport interface PackageManagerArgs {\n npm: string;\n yarn: string;\n pnpm: string;\n bun: string;\n}\n\nexport function detectEnvironment(): Environment {\n const cwd = process.cwd();\n const isInteractive = Boolean(process.stdout.isTTY && process.stdin.isTTY);\n\n let packageManager: PackageManager = 'npm';\n if (existsSync(join(cwd, 'yarn.lock'))) packageManager = 'yarn';\n else if (existsSync(join(cwd, 'pnpm-lock.yaml'))) packageManager = 'pnpm';\n else if (existsSync(join(cwd, 'bun.lockb')) || existsSync(join(cwd, 'bun.lock'))) packageManager = 'bun';\n\n const nodeVersion = parseInt(process.version.slice(1), 10);\n const hasCucumber = existsSync(join(cwd, 'node_modules', '@cucumber', 'cucumber', 'package.json'));\n\n return { isInteractive, packageManager, nodeVersion, hasCucumber, cwd };\n}\n\nfunction pmCmd(pm: string, args: PackageManagerArgs): string {\n if (pm === 'yarn') return `yarn ${args.yarn}`;\n if (pm === 'pnpm') return `pnpm ${args.pnpm}`;\n if (pm === 'bun') return `bun ${args.bun}`;\n return `npm ${args.npm}`;\n}\n\nexport function execPm(env: Pick<Environment, 'packageManager' | 'cwd'>, args: PackageManagerArgs) {\n const cmd = pmCmd(env.packageManager, args);\n return execSync(cmd, { stdio: 'inherit', cwd: env.cwd });\n}\n","import { existsSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { type Environment, execPm } from '../detect.js';\n\nexport function isCliInstalled({ cwd }: Pick<Environment, 'cwd'>): boolean {\n const pkgPath = join(cwd, 'package.json');\n if (!existsSync(pkgPath)) return false;\n\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')) as {\n devDependencies?: Record<string, string>;\n dependencies?: Record<string, string>;\n };\n\n return '@letsrunit/cli' in (pkg.devDependencies ?? {}) || '@letsrunit/cli' in (pkg.dependencies ?? {});\n}\n\nexport function installCli(env: Pick<Environment, 'packageManager' | 'cwd'>): void {\n execPm(env, {\n npm: 'install --save-dev @letsrunit/cli',\n yarn: 'add --dev @letsrunit/cli',\n pnpm: 'add -D @letsrunit/cli',\n bun: 'add -d @letsrunit/cli',\n });\n}\n","import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { type Environment, execPm } from '../detect.js';\n\nconst BDD_IMPORT = '@letsrunit/bdd/define';\n\nconst CUCUMBER_CONFIG = `export default {\n require: ['features/support/**/*.js'],\n worldParameters: {\n baseURL: 'http://localhost:3000',\n },\n};\n`;\n\nconst SUPPORT_FILE = `import { setDefaultTimeout } from '@cucumber/cucumber';\nimport '${BDD_IMPORT}';\n\nsetDefaultTimeout(30_000);\n`;\n\nconst EXAMPLE_FEATURE = `Feature: Example\n Scenario: Homepage loads\n Given I'm on the homepage\n`;\n\nexport type CucumberConfigResult = 'created' | 'skipped' | 'needs-manual-update';\n\nexport interface CucumberSetupResult {\n bddInstalled: boolean;\n configResult: CucumberConfigResult;\n featuresCreated: boolean;\n}\n\nexport function installCucumber(env: Pick<Environment, 'packageManager' | 'cwd'>): void {\n execPm(env, {\n npm: 'install --save-dev @cucumber/cucumber',\n yarn: 'add --dev @cucumber/cucumber',\n pnpm: 'add -D @cucumber/cucumber',\n bun: 'add -d @cucumber/cucumber',\n });\n}\n\nfunction installBdd(env: Pick<Environment, 'packageManager' | 'cwd'>): boolean {\n const pkgPath = join(env.cwd, 'package.json');\n if (!existsSync(pkgPath)) return false;\n\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')) as {\n devDependencies?: Record<string, string>;\n dependencies?: Record<string, string>;\n };\n\n const alreadyInstalled =\n '@letsrunit/bdd' in (pkg.devDependencies ?? {}) || '@letsrunit/bdd' in (pkg.dependencies ?? {});\n\n if (alreadyInstalled) return false;\n\n execPm(env, {\n npm: 'install --save-dev @letsrunit/bdd',\n yarn: 'add --dev @letsrunit/bdd',\n pnpm: 'add -D @letsrunit/bdd',\n bun: 'add -d @letsrunit/bdd',\n });\n\n return true;\n}\n\nfunction setupCucumberConfig({ cwd }: Pick<Environment, 'cwd'>): CucumberConfigResult {\n const supportDir = join(cwd, 'features', 'support');\n const supportPath = join(supportDir, 'world.js');\n\n if (existsSync(supportPath)) {\n const content = readFileSync(supportPath, 'utf-8');\n if (content.includes(BDD_IMPORT)) return 'skipped';\n return 'needs-manual-update';\n }\n\n const configPath = join(cwd, 'cucumber.js');\n if (!existsSync(configPath)) {\n writeFileSync(configPath, CUCUMBER_CONFIG, 'utf-8');\n }\n\n mkdirSync(supportDir, { recursive: true });\n writeFileSync(supportPath, SUPPORT_FILE, 'utf-8');\n return 'created';\n}\n\nfunction setupFeaturesDir({ cwd }: Pick<Environment, 'cwd'>): boolean {\n if (existsSync(join(cwd, 'features'))) {\n try {\n const hasFeatureFiles = readdirSync(join(cwd, 'features')).some((f) => f.endsWith('.feature'));\n if (hasFeatureFiles) return false;\n } catch {\n return false;\n }\n }\n\n try {\n const hasFeatureAtRoot = readdirSync(cwd).some((f) => f.endsWith('.feature'));\n if (hasFeatureAtRoot) return false;\n } catch {\n return false;\n }\n\n mkdirSync(join(cwd, 'features'), { recursive: true });\n writeFileSync(join(cwd, 'features', 'example.feature'), EXAMPLE_FEATURE, 'utf-8');\n return true;\n}\n\nexport function setupCucumber(env: Pick<Environment, 'packageManager' | 'cwd'>): CucumberSetupResult {\n const bddInstalled = installBdd(env);\n const configResult = setupCucumberConfig(env);\n const featuresCreated = setupFeaturesDir(env);\n return { bddInstalled, configResult, featuresCreated };\n}\n","import { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { Environment } from '../detect.js';\n\nexport type GithubActionsResult = 'created' | 'skipped';\n\nfunction setupStepsFor({ packageManager, nodeVersion }: Pick<Environment, 'packageManager' | 'nodeVersion'>): string {\n if (packageManager === 'yarn') return `\\\n - name: Enable Corepack\n run: corepack enable\n - uses: actions/setup-node@v4\n with:\n node-version: ${nodeVersion}\n cache: yarn\n - name: Install dependencies\n run: yarn install --immutable`;\n if (packageManager === 'pnpm') return `\\\n - uses: pnpm/action-setup@v4\n - uses: actions/setup-node@v4\n with:\n node-version: ${nodeVersion}\n cache: pnpm\n - name: Install dependencies\n run: pnpm install --frozen-lockfile`;\n if (packageManager === 'bun') return `\\\n - uses: oven-sh/setup-bun@v2\n - name: Install dependencies\n run: bun install --frozen-lockfile`;\n return `\\\n - uses: actions/setup-node@v4\n with:\n node-version: ${nodeVersion}\n cache: npm\n - name: Install dependencies\n run: npm ci`;\n}\n\nfunction workflowYaml(env: Pick<Environment, 'packageManager' | 'nodeVersion'>): string {\n const setupSteps = setupStepsFor(env);\n\n return `name: Features\non:\n push:\n branches: [main]\n pull_request:\n branches: [main]\njobs:\n features:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n${setupSteps}\n - name: Install Playwright browsers\n run: npx playwright install chromium --with-deps\n - name: Run features\n run: npx cucumber-js\n`;\n}\n\nexport function installGithubAction(env: Pick<Environment, 'packageManager' | 'nodeVersion' | 'cwd'>): GithubActionsResult {\n const workflowDir = join(env.cwd, '.github', 'workflows');\n const workflowPath = join(workflowDir, 'letsrunit.yml');\n\n if (existsSync(workflowPath)) return 'skipped';\n\n mkdirSync(workflowDir, { recursive: true });\n writeFileSync(workflowPath, workflowYaml(env), 'utf-8');\n return 'created';\n}\n","import { execSync } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { type Environment, execPm } from '../detect.js';\n\nexport function hasPlaywrightBrowsers({ cwd }: Pick<Environment, 'cwd'>): boolean {\n if (!existsSync(join(cwd, 'node_modules', 'playwright-core', 'package.json'))) {\n return false;\n }\n try {\n const execPath = execSync(\n `node -e \"console.log(require('playwright-core').chromium.executablePath())\"`,\n { cwd, stdio: 'pipe', encoding: 'utf-8' },\n ).trim();\n return existsSync(execPath);\n } catch {\n return false;\n }\n}\n\nexport function installPlaywrightBrowsers(env: Pick<Environment, 'packageManager' | 'cwd'>): void {\n execPm(env, {\n npm: 'exec playwright install chromium',\n yarn: 'exec playwright install chromium',\n pnpm: 'exec playwright install chromium',\n bun: 'x playwright install chromium',\n });\n}\n"],"mappings":";AAAA,SAAS,SAAS,OAAO,KAAK,MAAM,OAAO,eAAe;;;ACA1D,SAAS,gBAAgB;AACzB,SAAS,kBAAkB;AAC3B,SAAS,YAAY;AAmBd,SAAS,oBAAiC;AAC/C,QAAM,MAAM,QAAQ,IAAI;AACxB,QAAM,gBAAgB,QAAQ,QAAQ,OAAO,SAAS,QAAQ,MAAM,KAAK;AAEzE,MAAI,iBAAiC;AACrC,MAAI,WAAW,KAAK,KAAK,WAAW,CAAC,EAAG,kBAAiB;AAAA,WAChD,WAAW,KAAK,KAAK,gBAAgB,CAAC,EAAG,kBAAiB;AAAA,WAC1D,WAAW,KAAK,KAAK,WAAW,CAAC,KAAK,WAAW,KAAK,KAAK,UAAU,CAAC,EAAG,kBAAiB;AAEnG,QAAM,cAAc,SAAS,QAAQ,QAAQ,MAAM,CAAC,GAAG,EAAE;AACzD,QAAM,cAAc,WAAW,KAAK,KAAK,gBAAgB,aAAa,YAAY,cAAc,CAAC;AAEjG,SAAO,EAAE,eAAe,gBAAgB,aAAa,aAAa,IAAI;AACxE;AAEA,SAAS,MAAM,IAAY,MAAkC;AAC3D,MAAI,OAAO,OAAQ,QAAO,QAAQ,KAAK,IAAI;AAC3C,MAAI,OAAO,OAAQ,QAAO,QAAQ,KAAK,IAAI;AAC3C,MAAI,OAAO,MAAO,QAAO,OAAO,KAAK,GAAG;AACxC,SAAO,OAAO,KAAK,GAAG;AACxB;AAEO,SAAS,OAAO,KAAkD,MAA0B;AACjG,QAAM,MAAM,MAAM,IAAI,gBAAgB,IAAI;AAC1C,SAAO,SAAS,KAAK,EAAE,OAAO,WAAW,KAAK,IAAI,IAAI,CAAC;AACzD;;;AC9CA,SAAS,cAAAA,aAAY,oBAAoB;AACzC,SAAS,QAAAC,aAAY;AAGd,SAAS,eAAe,EAAE,IAAI,GAAsC;AACzE,QAAM,UAAUC,MAAK,KAAK,cAAc;AACxC,MAAI,CAACC,YAAW,OAAO,EAAG,QAAO;AAEjC,QAAM,MAAM,KAAK,MAAM,aAAa,SAAS,OAAO,CAAC;AAKrD,SAAO,qBAAqB,IAAI,mBAAmB,CAAC,MAAM,qBAAqB,IAAI,gBAAgB,CAAC;AACtG;AAEO,SAAS,WAAW,KAAwD;AACjF,SAAO,KAAK;AAAA,IACV,KAAK;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,IACN,KAAK;AAAA,EACP,CAAC;AACH;;;ACvBA,SAAS,cAAAC,aAAY,WAAW,aAAa,gBAAAC,eAAc,qBAAqB;AAChF,SAAS,QAAAC,aAAY;AAGrB,IAAM,aAAa;AAEnB,IAAM,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQxB,IAAM,eAAe;AAAA,UACX,UAAU;AAAA;AAAA;AAAA;AAKpB,IAAM,kBAAkB;AAAA;AAAA;AAAA;AAajB,SAAS,gBAAgB,KAAwD;AACtF,SAAO,KAAK;AAAA,IACV,KAAK;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,IACN,KAAK;AAAA,EACP,CAAC;AACH;AAEA,SAAS,WAAW,KAA2D;AAC7E,QAAM,UAAUC,MAAK,IAAI,KAAK,cAAc;AAC5C,MAAI,CAACC,YAAW,OAAO,EAAG,QAAO;AAEjC,QAAM,MAAM,KAAK,MAAMC,cAAa,SAAS,OAAO,CAAC;AAKrD,QAAM,mBACJ,qBAAqB,IAAI,mBAAmB,CAAC,MAAM,qBAAqB,IAAI,gBAAgB,CAAC;AAE/F,MAAI,iBAAkB,QAAO;AAE7B,SAAO,KAAK;AAAA,IACV,KAAK;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,IACN,KAAK;AAAA,EACP,CAAC;AAED,SAAO;AACT;AAEA,SAAS,oBAAoB,EAAE,IAAI,GAAmD;AACpF,QAAM,aAAaF,MAAK,KAAK,YAAY,SAAS;AAClD,QAAM,cAAcA,MAAK,YAAY,UAAU;AAE/C,MAAIC,YAAW,WAAW,GAAG;AAC3B,UAAM,UAAUC,cAAa,aAAa,OAAO;AACjD,QAAI,QAAQ,SAAS,UAAU,EAAG,QAAO;AACzC,WAAO;AAAA,EACT;AAEA,QAAM,aAAaF,MAAK,KAAK,aAAa;AAC1C,MAAI,CAACC,YAAW,UAAU,GAAG;AAC3B,kBAAc,YAAY,iBAAiB,OAAO;AAAA,EACpD;AAEA,YAAU,YAAY,EAAE,WAAW,KAAK,CAAC;AACzC,gBAAc,aAAa,cAAc,OAAO;AAChD,SAAO;AACT;AAEA,SAAS,iBAAiB,EAAE,IAAI,GAAsC;AACpE,MAAIA,YAAWD,MAAK,KAAK,UAAU,CAAC,GAAG;AACrC,QAAI;AACF,YAAM,kBAAkB,YAAYA,MAAK,KAAK,UAAU,CAAC,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,UAAU,CAAC;AAC7F,UAAI,gBAAiB,QAAO;AAAA,IAC9B,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAEA,MAAI;AACF,UAAM,mBAAmB,YAAY,GAAG,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,UAAU,CAAC;AAC5E,QAAI,iBAAkB,QAAO;AAAA,EAC/B,QAAQ;AACN,WAAO;AAAA,EACT;AAEA,YAAUA,MAAK,KAAK,UAAU,GAAG,EAAE,WAAW,KAAK,CAAC;AACpD,gBAAcA,MAAK,KAAK,YAAY,iBAAiB,GAAG,iBAAiB,OAAO;AAChF,SAAO;AACT;AAEO,SAAS,cAAc,KAAuE;AACnG,QAAM,eAAe,WAAW,GAAG;AACnC,QAAM,eAAe,oBAAoB,GAAG;AAC5C,QAAM,kBAAkB,iBAAiB,GAAG;AAC5C,SAAO,EAAE,cAAc,cAAc,gBAAgB;AACvD;;;ACjHA,SAAS,cAAAG,aAAY,aAAAC,YAAW,iBAAAC,sBAAqB;AACrD,SAAS,QAAAC,aAAY;AAKrB,SAAS,cAAc,EAAE,gBAAgB,YAAY,GAAgE;AACnH,MAAI,mBAAmB,OAAQ,QAAO;AAAA;AAAA;AAAA;AAAA,0BAKd,WAAW;AAAA;AAAA;AAAA;AAInC,MAAI,mBAAmB,OAAQ,QAAO;AAAA;AAAA;AAAA,0BAId,WAAW;AAAA;AAAA;AAAA;AAInC,MAAI,mBAAmB,MAAO,QAAO;AAAA;AAAA;AAIrC,SAAO;AAAA;AAAA,0BAGiB,WAAW;AAAA;AAAA;AAAA;AAIrC;AAEA,SAAS,aAAa,KAAkE;AACtF,QAAM,aAAa,cAAc,GAAG;AAEpC,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWP,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAMZ;AAEO,SAAS,oBAAoB,KAAuF;AACzH,QAAM,cAAcA,MAAK,IAAI,KAAK,WAAW,WAAW;AACxD,QAAM,eAAeA,MAAK,aAAa,eAAe;AAEtD,MAAIH,YAAW,YAAY,EAAG,QAAO;AAErC,EAAAC,WAAU,aAAa,EAAE,WAAW,KAAK,CAAC;AAC1C,EAAAC,eAAc,cAAc,aAAa,GAAG,GAAG,OAAO;AACtD,SAAO;AACT;;;ACpEA,SAAS,YAAAE,iBAAgB;AACzB,SAAS,cAAAC,mBAAkB;AAC3B,SAAS,QAAAC,aAAY;AAGd,SAAS,sBAAsB,EAAE,IAAI,GAAsC;AAChF,MAAI,CAACC,YAAWC,MAAK,KAAK,gBAAgB,mBAAmB,cAAc,CAAC,GAAG;AAC7E,WAAO;AAAA,EACT;AACA,MAAI;AACF,UAAM,WAAWC;AAAA,MACf;AAAA,MACA,EAAE,KAAK,OAAO,QAAQ,UAAU,QAAQ;AAAA,IAC1C,EAAE,KAAK;AACP,WAAOF,YAAW,QAAQ;AAAA,EAC5B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,0BAA0B,KAAwD;AAChG,SAAO,KAAK;AAAA,IACV,KAAK;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,IACN,KAAK;AAAA,EACP,CAAC;AACH;;;ALpBA,IAAMG,cAAa;AAMnB,eAAe,eAAe,KAAiC;AAC7D,MAAI,eAAe,GAAG,GAAG;AACvB,QAAI,QAAQ,kCAAkC;AAC9C;AAAA,EACF;AAEA,QAAM,IAAI,QAAQ;AAClB,IAAE,MAAM,iCAA4B;AACpC,aAAW,GAAG;AACd,IAAE,KAAK,0BAA0B;AACnC;AAEA,eAAe,mBAAmB,KAAkB,EAAE,IAAI,GAAkC;AAC1F,MAAI,IAAI,YAAa,QAAO;AAE5B,MAAI,CAAC,OAAO,CAAC,IAAI,eAAe;AAC9B,QAAI,KAAK,0EAA0E;AACnF,SAAK,2EAA2E,gBAAgB;AAChG,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,KAAK;AACR,UAAM,UAAU,MAAM,QAAQ,EAAE,SAAS,gDAAgD,CAAC;AAC1F,QAAI,YAAY,KAAM,QAAO;AAAA,EAC/B;AAEA,QAAM,IAAI,QAAQ;AAClB,IAAE,MAAM,qCAAgC;AACxC,kBAAgB,GAAG;AACnB,IAAE,KAAK,8BAA8B;AACrC,SAAO;AACT;AAEA,SAAS,kBAAkB,KAAwB;AACjD,QAAM,SAAS,cAAc,GAAG;AAEhC,MAAI,OAAO,aAAc,KAAI,QAAQ,0BAA0B;AAE/D,MAAI,OAAO,iBAAiB,WAAW;AACrC,QAAI,QAAQ,mCAAmC;AAAA,EACjD,WAAW,OAAO,iBAAiB,uBAAuB;AACxD,QAAI,KAAK,sEAAsE;AAC/E,SAAK,gBAAgBA,WAAU,oCAAoC,iBAAiB;AAAA,EACtF;AAEA,MAAI,OAAO,gBAAiB,KAAI,QAAQ,kDAAkD;AAC5F;AAEA,eAAe,4BAA4B,KAAkB,EAAE,IAAI,GAA+B;AAChG,MAAI,sBAAsB,GAAG,EAAG;AAEhC,MAAI,CAAC,OAAO,CAAC,IAAI,eAAe;AAC9B,QAAI,KAAK,wCAAwC;AACjD,SAAK,mCAAmC,yBAAyB;AACjE;AAAA,EACF;AAEA,MAAI,CAAC,KAAK;AACR,UAAM,UAAU,MAAM,QAAQ,EAAE,SAAS,yDAAyD,CAAC;AACnG,QAAI,YAAY,KAAM;AAAA,EACxB;AAEA,QAAM,IAAI,QAAQ;AAClB,IAAE,MAAM,sCAAiC;AACzC,4BAA0B,GAAG;AAC7B,IAAE,KAAK,+BAA+B;AACxC;AAEA,eAAe,oBAAoB,KAAkB,EAAE,IAAI,GAA+B;AACxF,MAAI,CAAC,OAAO,CAAC,IAAI,cAAe;AAEhC,MAAI,CAAC,KAAK;AACR,UAAM,YAAY,MAAM,QAAQ,EAAE,SAAS,+CAA+C,CAAC;AAC3F,QAAI,cAAc,KAAM;AAAA,EAC1B;AAEA,QAAM,SAAS,oBAAoB,GAAG;AACtC,MAAI,WAAW,WAAW;AACxB,QAAI,QAAQ,yCAAyC;AAAA,EACvD,OAAO;AACL,QAAI,KAAK,yDAAyD;AAAA,EACpE;AACF;AAEA,eAAsB,KAAK,UAAuB,CAAC,GAAkB;AACnE,QAAM,gBAAgB;AAEtB,QAAM,MAAM,kBAAkB;AAE9B,QAAM,eAAe,GAAG;AAExB,QAAM,cAAc,MAAM,mBAAmB,KAAK,OAAO;AACzD,MAAI,aAAa;AACf,sBAAkB,GAAG;AACrB,UAAM,4BAA4B,KAAK,OAAO;AAC9C,UAAM,oBAAoB,KAAK,OAAO;AAAA,EACxC;AAEA,QAAM,oDAAoD;AAC5D;","names":["existsSync","join","join","existsSync","existsSync","readFileSync","join","join","existsSync","readFileSync","existsSync","mkdirSync","writeFileSync","join","execSync","existsSync","join","existsSync","join","execSync","BDD_IMPORT"]}
|
|
1
|
+
{"version":3,"sources":["../src/init.ts","../src/detect.ts","../src/setup/cli.ts","../src/setup/cucumber.ts","../src/setup/github-actions.ts","../src/setup/playwright.ts"],"sourcesContent":["import { confirm, intro, log, note, outro, spinner } from '@clack/prompts';\nimport { detectEnvironment, type Environment } from './detect.js';\nimport { installCli, isCliInstalled } from './setup/cli.js';\nimport { installCucumber, setupCucumber } from './setup/cucumber.js';\nimport { installGithubAction } from './setup/github-actions.js';\nimport { hasPlaywrightBrowsers, installPlaywrightBrowsers } from './setup/playwright.js';\n\nconst BDD_IMPORT = '@letsrunit/cucumber';\n\nexport interface InitOptions {\n yes?: boolean;\n}\n\nasync function stepInstallCli(env: Environment): Promise<void> {\n if (isCliInstalled(env)) {\n log.success('@letsrunit/cli already installed');\n return;\n }\n\n const s = spinner();\n s.start('Installing @letsrunit/cli…');\n installCli(env);\n s.stop('@letsrunit/cli installed');\n}\n\nasync function stepEnsureCucumber(env: Environment, { yes }: InitOptions): Promise<boolean> {\n if (env.hasCucumber) return true;\n\n if (!yes && !env.isInteractive) {\n log.warn('@cucumber/cucumber not found. Install it to use letsrunit with Cucumber:');\n note('npm install --save-dev @cucumber/cucumber\\nThen run: npx letsrunit init', 'Setup Cucumber');\n return false;\n }\n\n if (!yes) {\n const install = await confirm({ message: '@cucumber/cucumber not found. Install it now?' });\n if (install !== true) return false;\n }\n\n const s = spinner();\n s.start('Installing @cucumber/cucumber…');\n installCucumber(env);\n s.stop('@cucumber/cucumber installed');\n return true;\n}\n\nfunction stepSetupCucumber(env: Environment): void {\n const result = setupCucumber(env);\n\n if (result.bddInstalled) log.success('@letsrunit/cucumber installed');\n\n if (result.configResult === 'created') {\n log.success('features/support/world.js created');\n } else if (result.configResult === 'needs-manual-update') {\n log.warn('features/support/world.js exists but does not import @letsrunit/cucumber.');\n note(`Add \"import '${BDD_IMPORT}';\" to features/support/world.js`, 'Action required');\n }\n\n if (result.featuresCreated) log.success('features/ directory created with example.feature');\n}\n\nasync function stepCheckPlaywrightBrowsers(env: Environment, { yes }: InitOptions): Promise<void> {\n if (hasPlaywrightBrowsers(env)) return;\n\n if (!yes && !env.isInteractive) {\n log.warn('Playwright Chromium browser not found.');\n note('npx playwright install chromium', 'Run to install browsers');\n return;\n }\n\n if (!yes) {\n const install = await confirm({ message: 'Playwright Chromium browser not found. Install it now?' });\n if (install !== true) return;\n }\n\n const s = spinner();\n s.start('Installing Playwright Chromium…');\n installPlaywrightBrowsers(env);\n s.stop('Playwright Chromium installed');\n}\n\nasync function stepAddGithubAction(env: Environment, { yes }: InitOptions): Promise<void> {\n if (!yes && !env.isInteractive) return;\n\n if (!yes) {\n const addAction = await confirm({ message: 'Add a GitHub Action to run features on push?' });\n if (addAction !== true) return;\n }\n\n const result = installGithubAction(env);\n if (result === 'created') {\n log.success('.github/workflows/letsrunit.yml created');\n } else {\n log.info('.github/workflows/letsrunit.yml already exists, skipped');\n }\n}\n\nexport async function init(options: InitOptions = {}): Promise<void> {\n intro('letsrunit init');\n\n const env = detectEnvironment();\n\n await stepInstallCli(env);\n\n const hasCucumber = await stepEnsureCucumber(env, options);\n if (hasCucumber) {\n stepSetupCucumber(env);\n await stepCheckPlaywrightBrowsers(env, options);\n await stepAddGithubAction(env, options);\n }\n\n outro('All done! Run npx letsrunit --help to get started.');\n}\n","import { execSync } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\n\nexport type PackageManager = 'yarn' | 'pnpm' | 'bun' | 'npm';\n\nexport interface Environment {\n isInteractive: boolean;\n packageManager: PackageManager;\n nodeVersion: number;\n hasCucumber: boolean;\n cwd: string;\n}\n\nexport interface PackageManagerArgs {\n npm: string;\n yarn: string;\n pnpm: string;\n bun: string;\n}\n\nexport function detectEnvironment(): Environment {\n const cwd = process.cwd();\n const isInteractive = Boolean(process.stdout.isTTY && process.stdin.isTTY);\n\n let packageManager: PackageManager = 'npm';\n if (existsSync(join(cwd, 'yarn.lock'))) packageManager = 'yarn';\n else if (existsSync(join(cwd, 'pnpm-lock.yaml'))) packageManager = 'pnpm';\n else if (existsSync(join(cwd, 'bun.lockb')) || existsSync(join(cwd, 'bun.lock'))) packageManager = 'bun';\n\n const nodeVersion = parseInt(process.version.slice(1), 10);\n const hasCucumber = existsSync(join(cwd, 'node_modules', '@cucumber', 'cucumber', 'package.json'));\n\n return { isInteractive, packageManager, nodeVersion, hasCucumber, cwd };\n}\n\nfunction pmCmd(pm: string, args: PackageManagerArgs): string {\n if (pm === 'yarn') return `yarn ${args.yarn}`;\n if (pm === 'pnpm') return `pnpm ${args.pnpm}`;\n if (pm === 'bun') return `bun ${args.bun}`;\n return `npm ${args.npm}`;\n}\n\nexport function execPm(env: Pick<Environment, 'packageManager' | 'cwd'>, args: PackageManagerArgs) {\n const cmd = pmCmd(env.packageManager, args);\n return execSync(cmd, { stdio: 'inherit', cwd: env.cwd });\n}\n","import { existsSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { type Environment, execPm } from '../detect.js';\n\nexport function isCliInstalled({ cwd }: Pick<Environment, 'cwd'>): boolean {\n const pkgPath = join(cwd, 'package.json');\n if (!existsSync(pkgPath)) return false;\n\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')) as {\n devDependencies?: Record<string, string>;\n dependencies?: Record<string, string>;\n };\n\n return '@letsrunit/cli' in (pkg.devDependencies ?? {}) || '@letsrunit/cli' in (pkg.dependencies ?? {});\n}\n\nexport function installCli(env: Pick<Environment, 'packageManager' | 'cwd'>): void {\n execPm(env, {\n npm: 'install --save-dev @letsrunit/cli',\n yarn: 'add --dev @letsrunit/cli',\n pnpm: 'add -D @letsrunit/cli',\n bun: 'add -d @letsrunit/cli',\n });\n}\n","import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { type Environment, execPm } from '../detect.js';\n\nconst BDD_IMPORT = '@letsrunit/cucumber';\n\nconst CUCUMBER_CONFIG = `export default {\n require: ['features/support/**/*.js'],\n worldParameters: {\n baseURL: 'http://localhost:3000',\n },\n};\n`;\n\nconst SUPPORT_FILE = `import { setDefaultTimeout } from '@cucumber/cucumber';\nimport '${BDD_IMPORT}';\n\nsetDefaultTimeout(30_000);\n`;\n\nconst EXAMPLE_FEATURE = `Feature: Example\n Scenario: Homepage loads\n Given I'm on the homepage\n`;\n\nexport type CucumberConfigResult = 'created' | 'skipped' | 'needs-manual-update';\n\nexport interface CucumberSetupResult {\n bddInstalled: boolean;\n configResult: CucumberConfigResult;\n featuresCreated: boolean;\n}\n\nexport function installCucumber(env: Pick<Environment, 'packageManager' | 'cwd'>): void {\n execPm(env, {\n npm: 'install --save-dev @cucumber/cucumber',\n yarn: 'add --dev @cucumber/cucumber',\n pnpm: 'add -D @cucumber/cucumber',\n bun: 'add -d @cucumber/cucumber',\n });\n}\n\nfunction installBdd(env: Pick<Environment, 'packageManager' | 'cwd'>): boolean {\n const pkgPath = join(env.cwd, 'package.json');\n if (!existsSync(pkgPath)) return false;\n\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')) as {\n devDependencies?: Record<string, string>;\n dependencies?: Record<string, string>;\n };\n\n const alreadyInstalled =\n '@letsrunit/cucumber' in (pkg.devDependencies ?? {}) || '@letsrunit/cucumber' in (pkg.dependencies ?? {});\n\n if (alreadyInstalled) return false;\n\n execPm(env, {\n npm: 'install --save-dev @letsrunit/cucumber',\n yarn: 'add --dev @letsrunit/cucumber',\n pnpm: 'add -D @letsrunit/cucumber',\n bun: 'add -d @letsrunit/cucumber',\n });\n\n return true;\n}\n\nfunction setupCucumberConfig({ cwd }: Pick<Environment, 'cwd'>): CucumberConfigResult {\n const supportDir = join(cwd, 'features', 'support');\n const supportPath = join(supportDir, 'world.js');\n\n if (existsSync(supportPath)) {\n const content = readFileSync(supportPath, 'utf-8');\n if (content.includes(BDD_IMPORT)) return 'skipped';\n return 'needs-manual-update';\n }\n\n const configPath = join(cwd, 'cucumber.js');\n if (!existsSync(configPath)) {\n writeFileSync(configPath, CUCUMBER_CONFIG, 'utf-8');\n }\n\n mkdirSync(supportDir, { recursive: true });\n writeFileSync(supportPath, SUPPORT_FILE, 'utf-8');\n return 'created';\n}\n\nfunction setupFeaturesDir({ cwd }: Pick<Environment, 'cwd'>): boolean {\n if (existsSync(join(cwd, 'features'))) {\n try {\n const hasFeatureFiles = readdirSync(join(cwd, 'features')).some((f) => f.endsWith('.feature'));\n if (hasFeatureFiles) return false;\n } catch {\n return false;\n }\n }\n\n try {\n const hasFeatureAtRoot = readdirSync(cwd).some((f) => f.endsWith('.feature'));\n if (hasFeatureAtRoot) return false;\n } catch {\n return false;\n }\n\n mkdirSync(join(cwd, 'features'), { recursive: true });\n writeFileSync(join(cwd, 'features', 'example.feature'), EXAMPLE_FEATURE, 'utf-8');\n return true;\n}\n\nexport function setupCucumber(env: Pick<Environment, 'packageManager' | 'cwd'>): CucumberSetupResult {\n const bddInstalled = installBdd(env);\n const configResult = setupCucumberConfig(env);\n const featuresCreated = setupFeaturesDir(env);\n return { bddInstalled, configResult, featuresCreated };\n}\n","import { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { Environment } from '../detect.js';\n\nexport type GithubActionsResult = 'created' | 'skipped';\n\nfunction setupStepsFor({ packageManager, nodeVersion }: Pick<Environment, 'packageManager' | 'nodeVersion'>): string {\n if (packageManager === 'yarn') return `\\\n - name: Enable Corepack\n run: corepack enable\n - uses: actions/setup-node@v4\n with:\n node-version: ${nodeVersion}\n cache: yarn\n - name: Install dependencies\n run: yarn install --immutable`;\n if (packageManager === 'pnpm') return `\\\n - uses: pnpm/action-setup@v4\n - uses: actions/setup-node@v4\n with:\n node-version: ${nodeVersion}\n cache: pnpm\n - name: Install dependencies\n run: pnpm install --frozen-lockfile`;\n if (packageManager === 'bun') return `\\\n - uses: oven-sh/setup-bun@v2\n - name: Install dependencies\n run: bun install --frozen-lockfile`;\n return `\\\n - uses: actions/setup-node@v4\n with:\n node-version: ${nodeVersion}\n cache: npm\n - name: Install dependencies\n run: npm ci`;\n}\n\nfunction workflowYaml(env: Pick<Environment, 'packageManager' | 'nodeVersion'>): string {\n const setupSteps = setupStepsFor(env);\n\n return `name: Features\non:\n push:\n branches: [main]\n pull_request:\n branches: [main]\njobs:\n features:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n${setupSteps}\n - name: Install Playwright browsers\n run: npx playwright install chromium --with-deps\n - name: Run features\n run: npx cucumber-js\n`;\n}\n\nexport function installGithubAction(env: Pick<Environment, 'packageManager' | 'nodeVersion' | 'cwd'>): GithubActionsResult {\n const workflowDir = join(env.cwd, '.github', 'workflows');\n const workflowPath = join(workflowDir, 'letsrunit.yml');\n\n if (existsSync(workflowPath)) return 'skipped';\n\n mkdirSync(workflowDir, { recursive: true });\n writeFileSync(workflowPath, workflowYaml(env), 'utf-8');\n return 'created';\n}\n","import { execSync } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { type Environment, execPm } from '../detect.js';\n\nexport function hasPlaywrightBrowsers({ cwd }: Pick<Environment, 'cwd'>): boolean {\n if (!existsSync(join(cwd, 'node_modules', 'playwright-core', 'package.json'))) {\n return false;\n }\n try {\n const execPath = execSync(\n `node -e \"console.log(require('playwright-core').chromium.executablePath())\"`,\n { cwd, stdio: 'pipe', encoding: 'utf-8' },\n ).trim();\n return existsSync(execPath);\n } catch {\n return false;\n }\n}\n\nexport function installPlaywrightBrowsers(env: Pick<Environment, 'packageManager' | 'cwd'>): void {\n execPm(env, {\n npm: 'exec playwright install chromium',\n yarn: 'exec playwright install chromium',\n pnpm: 'exec playwright install chromium',\n bun: 'x playwright install chromium',\n });\n}\n"],"mappings":"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","names":["existsSync","join","join","existsSync","existsSync","readFileSync","join","join","existsSync","readFileSync","existsSync","mkdirSync","writeFileSync","join","execSync","existsSync","join","existsSync","join","execSync","BDD_IMPORT"]}
|
package/package.json
CHANGED
package/src/init.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { installCucumber, setupCucumber } from './setup/cucumber.js';
|
|
|
5
5
|
import { installGithubAction } from './setup/github-actions.js';
|
|
6
6
|
import { hasPlaywrightBrowsers, installPlaywrightBrowsers } from './setup/playwright.js';
|
|
7
7
|
|
|
8
|
-
const BDD_IMPORT = '@letsrunit/
|
|
8
|
+
const BDD_IMPORT = '@letsrunit/cucumber';
|
|
9
9
|
|
|
10
10
|
export interface InitOptions {
|
|
11
11
|
yes?: boolean;
|
|
@@ -47,12 +47,12 @@ async function stepEnsureCucumber(env: Environment, { yes }: InitOptions): Promi
|
|
|
47
47
|
function stepSetupCucumber(env: Environment): void {
|
|
48
48
|
const result = setupCucumber(env);
|
|
49
49
|
|
|
50
|
-
if (result.bddInstalled) log.success('@letsrunit/
|
|
50
|
+
if (result.bddInstalled) log.success('@letsrunit/cucumber installed');
|
|
51
51
|
|
|
52
52
|
if (result.configResult === 'created') {
|
|
53
53
|
log.success('features/support/world.js created');
|
|
54
54
|
} else if (result.configResult === 'needs-manual-update') {
|
|
55
|
-
log.warn('features/support/world.js exists but does not import @letsrunit/
|
|
55
|
+
log.warn('features/support/world.js exists but does not import @letsrunit/cucumber.');
|
|
56
56
|
note(`Add "import '${BDD_IMPORT}';" to features/support/world.js`, 'Action required');
|
|
57
57
|
}
|
|
58
58
|
|
package/src/setup/cucumber.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from
|
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { type Environment, execPm } from '../detect.js';
|
|
4
4
|
|
|
5
|
-
const BDD_IMPORT = '@letsrunit/
|
|
5
|
+
const BDD_IMPORT = '@letsrunit/cucumber';
|
|
6
6
|
|
|
7
7
|
const CUCUMBER_CONFIG = `export default {
|
|
8
8
|
require: ['features/support/**/*.js'],
|
|
@@ -50,15 +50,15 @@ function installBdd(env: Pick<Environment, 'packageManager' | 'cwd'>): boolean {
|
|
|
50
50
|
};
|
|
51
51
|
|
|
52
52
|
const alreadyInstalled =
|
|
53
|
-
'@letsrunit/
|
|
53
|
+
'@letsrunit/cucumber' in (pkg.devDependencies ?? {}) || '@letsrunit/cucumber' in (pkg.dependencies ?? {});
|
|
54
54
|
|
|
55
55
|
if (alreadyInstalled) return false;
|
|
56
56
|
|
|
57
57
|
execPm(env, {
|
|
58
|
-
npm: 'install --save-dev @letsrunit/
|
|
59
|
-
yarn: 'add --dev @letsrunit/
|
|
60
|
-
pnpm: 'add -D @letsrunit/
|
|
61
|
-
bun: 'add -d @letsrunit/
|
|
58
|
+
npm: 'install --save-dev @letsrunit/cucumber',
|
|
59
|
+
yarn: 'add --dev @letsrunit/cucumber',
|
|
60
|
+
pnpm: 'add -D @letsrunit/cucumber',
|
|
61
|
+
bun: 'add -d @letsrunit/cucumber',
|
|
62
62
|
});
|
|
63
63
|
|
|
64
64
|
return true;
|