From 4d02345dadff50af82aaa37d77459c6944367691 Mon Sep 17 00:00:00 2001 From: jycouet Date: Wed, 17 Sep 2025 23:40:31 +0200 Subject: [PATCH 01/30] test with tailwindcss & prettier --- packages/addons/_tests/_setup/suite.ts | 63 +++++++++++++------ packages/addons/_tests/prettier/test.ts | 11 ++-- packages/addons/_tests/tailwindcss/test.ts | 72 +++++++++++----------- 3 files changed, 86 insertions(+), 60 deletions(-) diff --git a/packages/addons/_tests/_setup/suite.ts b/packages/addons/_tests/_setup/suite.ts index d8d951488..19cd5778a 100644 --- a/packages/addons/_tests/_setup/suite.ts +++ b/packages/addons/_tests/_setup/suite.ts @@ -21,12 +21,21 @@ export const execAsync = promisify(exec); type Fixtures = { page: Page; - run(variant: ProjectVariant, options: OptionMap): Promise; + run(flavor: Flavor): string; +}; + +type Flavor = { + variant: ProjectVariant; + kind: { type: string; options: OptionMap }; }; export function setupTest( addons: Addons, - options?: { browser?: boolean } + options?: { + kinds: Array['kind']>; + filter?: (flavor: Flavor) => boolean; + browser?: boolean; + } ) { const test = vitest.test.extend>({} as any); @@ -44,8 +53,18 @@ export function setupTest( }); } - vitest.beforeAll(({ name }) => { - const testName = path.dirname(name).split('/').at(-1)!; + const flavors: Array> = []; + for (const kind of options?.kinds ?? []) { + for (const variant of variants) { + const flavor = { variant, kind }; + if (!options?.filter || options?.filter?.(flavor)) { + flavors.push(flavor); + } + } + } + let testName: string; + vitest.beforeAll(async ({ name }) => { + testName = path.dirname(name).split('/').at(-1)!; // constructs a builder for create test projects create = createProject({ cwd, templatesDir, testName }); @@ -65,32 +84,36 @@ export function setupTest( private: true }) ); - }); - // runs before each test case - vitest.beforeEach>(async (ctx) => { - let browserCtx: BrowserContext; - if (withBrowser) { - browserCtx = await browser.newContext(); - ctx.page = await browserCtx.newPage(); - } - ctx.run = async (variant, options) => { - const cwd = create({ testId: ctx.task.id, variant }); + for (const { variant, kind } of flavors) { + const cwd = create({ testId: `${kind.type}-${variant}`, variant }); // test metadata const metaPath = path.resolve(cwd, 'meta.json'); - fs.writeFileSync(metaPath, JSON.stringify({ variant, options }, null, '\t'), 'utf8'); + fs.writeFileSync(metaPath, JSON.stringify({ variant, kind }, null, '\t'), 'utf8'); - // run addon const { pnpmBuildDependencies } = await installAddon({ cwd, addons, - options, + options: kind.options, packageManager: 'pnpm' }); addPnpmBuildDependencies(cwd, 'pnpm', ['esbuild', ...pnpmBuildDependencies]); + } + + execSync('pnpm install', { cwd: path.resolve(cwd, testName), stdio: 'pipe' }); + }); + + // runs before each test case + vitest.beforeEach>(async (ctx) => { + let browserCtx: BrowserContext; + if (withBrowser) { + browserCtx = await browser.newContext(); + ctx.page = await browserCtx.newPage(); + } - return cwd; + ctx.run = (flavor) => { + return path.join(cwd, testName, `${flavor.kind.type}-${flavor.variant}`); }; return async () => { @@ -101,7 +124,7 @@ export function setupTest( }; }); - return { test, variants, prepareServer }; + return { test, variants, prepareServer, flavors }; } type PrepareServerOptions = { @@ -118,7 +141,7 @@ async function prepareServer( page, previewCommand = 'npm run preview', buildCommand = 'npm run build', - installCommand = 'pnpm install --no-frozen-lockfile' + installCommand }: PrepareServerOptions, afterInstall?: () => Promise | any ) { diff --git a/packages/addons/_tests/prettier/test.ts b/packages/addons/_tests/prettier/test.ts index 26435367f..65cf486ae 100644 --- a/packages/addons/_tests/prettier/test.ts +++ b/packages/addons/_tests/prettier/test.ts @@ -4,16 +4,17 @@ import { execSync } from 'node:child_process'; import { setupTest } from '../_setup/suite.ts'; import prettier from '../../prettier/index.ts'; -const { test, variants } = setupTest({ prettier }, { browser: false }); +const { test, flavors } = setupTest( + { prettier }, + { kinds: [{ type: 'default', options: { prettier: {} } }], browser: false } +); -test.concurrent.for(variants)('core - %s', async (variant, { expect, ...ctx }) => { - const cwd = await ctx.run(variant, { prettier: {} }); +test.concurrent.for(flavors)('core - %variant', (flavor, { expect, ...ctx }) => { + const cwd = ctx.run(flavor); const unformattedFile = 'const foo = "bar"'; fs.writeFileSync(path.resolve(cwd, 'src/lib/foo.js'), unformattedFile, 'utf8'); - expect(() => execSync('pnpm install', { cwd, stdio: 'pipe' })).not.toThrow(); - expect(() => execSync('pnpm lint', { cwd, stdio: 'pipe' })).toThrow(); expect(() => execSync('pnpm format', { cwd, stdio: 'pipe' })).not.toThrow(); diff --git a/packages/addons/_tests/tailwindcss/test.ts b/packages/addons/_tests/tailwindcss/test.ts index 9025e297f..cfde379b5 100644 --- a/packages/addons/_tests/tailwindcss/test.ts +++ b/packages/addons/_tests/tailwindcss/test.ts @@ -3,38 +3,40 @@ import { setupTest } from '../_setup/suite.ts'; import { addFixture } from './fixtures.ts'; import tailwindcss from '../../tailwindcss/index.ts'; -const { test, variants, prepareServer } = setupTest({ tailwindcss }); - -test.concurrent.for(variants)('none - %s', async (variant, { page, ...ctx }) => { - const cwd = await ctx.run(variant, { tailwindcss: { plugins: [] } }); - - // ...add test files - addFixture(cwd, variant); - - const { close } = await prepareServer({ cwd, page }); - // kill server process when we're done - ctx.onTestFinished(async () => await close()); - - const el = page.getByTestId('base'); - await expect(el).toHaveCSS('background-color', 'oklch(0.446 0.043 257.281)'); - await expect(el).toHaveCSS('border-color', 'oklch(0.985 0.002 247.839)'); - await expect(el).toHaveCSS('border-width', '4px'); - await expect(el).toHaveCSS('margin-top', '4px'); -}); - -test.concurrent.for(variants)('typography - %s', async (variant, { page, ...ctx }) => { - const cwd = await ctx.run(variant, { tailwindcss: { plugins: ['typography'] } }); - - // ...add files - addFixture(cwd, variant); - - const { close } = await prepareServer({ cwd, page }); - // kill server process when we're done - ctx.onTestFinished(async () => await close()); - - const el = page.getByTestId('typography'); - await expect(el).toHaveCSS('font-size', '18px'); - await expect(el).toHaveCSS('line-height', '28px'); - await expect(el).toHaveCSS('text-align', 'right'); - await expect(el).toHaveCSS('text-decoration-line', 'line-through'); -}); +const { test, prepareServer, flavors } = setupTest( + { tailwindcss }, + { + kinds: [ + { type: 'none', options: { tailwindcss: { plugins: [] } } }, + { type: 'typography', options: { tailwindcss: { plugins: ['typography'] } } } + ] + } +); + +test.concurrent.for(flavors)( + 'tailwindcss $kind.type $variant ', + async (flavor, { page, ...ctx }) => { + const cwd = ctx.run(flavor); + + // ...add test files + addFixture(cwd, flavor.variant); + + const { close } = await prepareServer({ cwd, page }); + // kill server process when we're done + ctx.onTestFinished(async () => await close()); + + if (flavor.kind.type === 'none') { + const el = page.getByTestId('base'); + await expect(el).toHaveCSS('background-color', 'oklch(0.446 0.043 257.281)'); + await expect(el).toHaveCSS('border-color', 'oklch(0.985 0.002 247.839)'); + await expect(el).toHaveCSS('border-width', '4px'); + await expect(el).toHaveCSS('margin-top', '4px'); + } else if (flavor.kind.type === 'typography') { + const el = page.getByTestId('typography'); + await expect(el).toHaveCSS('font-size', '18px'); + await expect(el).toHaveCSS('line-height', '28px'); + await expect(el).toHaveCSS('text-align', 'right'); + await expect(el).toHaveCSS('text-decoration-line', 'line-through'); + } + } +); From ea217b57f653159002a59a144f5d9b928c061009 Mon Sep 17 00:00:00 2001 From: jycouet Date: Thu, 18 Sep 2025 00:06:03 +0200 Subject: [PATCH 02/30] switch things around! --- packages/addons/_tests/_setup/suite.ts | 2 +- packages/addons/_tests/all-addons/test.ts | 9 ++- packages/addons/_tests/devtools-json/test.ts | 11 ++- packages/addons/_tests/drizzle/test.ts | 79 +++++++++++-------- packages/addons/_tests/eslint/test.ts | 11 +-- packages/addons/_tests/lucia/test.ts | 28 +++++-- packages/addons/_tests/mdsvex/test.ts | 11 ++- packages/addons/_tests/paraglide/test.ts | 25 ++++-- packages/addons/_tests/playwright/test.ts | 11 ++- packages/addons/_tests/prettier/test.ts | 2 +- packages/addons/_tests/storybook/test.ts | 35 ++++---- .../addons/_tests/sveltekit-adapter/test.ts | 44 ++++++----- packages/addons/_tests/tailwindcss/test.ts | 2 +- packages/addons/_tests/vitest/test.ts | 9 ++- 14 files changed, 165 insertions(+), 114 deletions(-) diff --git a/packages/addons/_tests/_setup/suite.ts b/packages/addons/_tests/_setup/suite.ts index 19cd5778a..3ea37d9b6 100644 --- a/packages/addons/_tests/_setup/suite.ts +++ b/packages/addons/_tests/_setup/suite.ts @@ -124,7 +124,7 @@ export function setupTest( }; }); - return { test, variants, prepareServer, flavors }; + return { test, flavors, prepareServer }; } type PrepareServerOptions = { diff --git a/packages/addons/_tests/all-addons/test.ts b/packages/addons/_tests/all-addons/test.ts index 845f468ff..423332b47 100644 --- a/packages/addons/_tests/all-addons/test.ts +++ b/packages/addons/_tests/all-addons/test.ts @@ -16,11 +16,12 @@ const defaultOptions = officialAddons.reduce>((options, return options; }, {}); -const { test, variants, prepareServer } = setupTest(addons); +const { test, flavors, prepareServer } = setupTest(addons, { + kinds: [{ type: 'default', options: defaultOptions }] +}); -const kitOnly = variants.filter((v) => v.startsWith('kit')); -test.concurrent.for(kitOnly)('run all addons - %s', async (variant, { page, ...ctx }) => { - const cwd = await ctx.run(variant, defaultOptions); +test.concurrent.for(flavors)('run all addons - $variant', async (flavor, { page, ...ctx }) => { + const cwd = ctx.run(flavor); const { close } = await prepareServer({ cwd, page }); // kill server process when we're done diff --git a/packages/addons/_tests/devtools-json/test.ts b/packages/addons/_tests/devtools-json/test.ts index 26bacca3a..59dbb10b2 100644 --- a/packages/addons/_tests/devtools-json/test.ts +++ b/packages/addons/_tests/devtools-json/test.ts @@ -4,12 +4,15 @@ import devtoolsJson from '../../devtools-json/index.ts'; import fs from 'node:fs'; import path from 'node:path'; -const { test, variants } = setupTest({ devtoolsJson }, { browser: false }); +const { test, flavors } = setupTest( + { devtoolsJson }, + { kinds: [{ type: 'default', options: { devtoolsJson: {} } }], browser: false } +); -test.concurrent.for(variants)('default - %s', async (variant, ctx) => { - const cwd = await ctx.run(variant, { devtoolsJson: {} }); +test.concurrent.for(flavors)('devtools-json $variant', (flavor, ctx) => { + const cwd = ctx.run(flavor); - const ext = variant.includes('ts') ? 'ts' : 'js'; + const ext = flavor.variant.includes('ts') ? 'ts' : 'js'; const viteFile = path.resolve(cwd, `vite.config.${ext}`); const viteContent = fs.readFileSync(viteFile, 'utf8'); diff --git a/packages/addons/_tests/drizzle/test.ts b/packages/addons/_tests/drizzle/test.ts index f88f283bc..3bc729ab2 100644 --- a/packages/addons/_tests/drizzle/test.ts +++ b/packages/addons/_tests/drizzle/test.ts @@ -9,11 +9,34 @@ import { setupTest } from '../_setup/suite.ts'; import drizzle from '../../drizzle/index.ts'; import { pageServer, pageComp } from './fixtures.ts'; -const { test, variants, prepareServer } = setupTest({ drizzle }); - // only linux is supported for running docker containers in github runners const noDocker = process.env.CI && process.platform !== 'linux'; +const { test, flavors, prepareServer } = setupTest( + { drizzle }, + { + kinds: [ + { + type: 'better-sqlite3', + options: { drizzle: { database: 'sqlite', sqlite: 'better-sqlite3' } } + }, + { + type: 'libsql', + options: { drizzle: { database: 'sqlite', sqlite: 'libsql' } } + }, + { + type: 'mysql2', + options: { drizzle: { database: 'mysql', mysql: 'mysql2', docker: true } } + }, + { + type: 'postgres.js', + options: { drizzle: { database: 'postgresql', postgresql: 'postgres.js', docker: true } } + } + ], + filter: (flavor) => flavor.variant.includes('kit') + } +); + beforeAll(() => { if (noDocker) return; const cwd = path.dirname(fileURLToPath(import.meta.url)); @@ -29,41 +52,27 @@ beforeAll(() => { }; }); -const kitOnly = variants.filter((v) => v.includes('kit')); -const testCases = [ - { name: 'better-sqlite3', options: { database: 'sqlite', sqlite: 'better-sqlite3' } }, - { name: 'libsql', options: { database: 'sqlite', sqlite: 'libsql' } }, - { name: 'mysql2', options: { database: 'mysql', mysql: 'mysql2', docker: true } }, - { - name: 'postgres.js', - options: { database: 'postgresql', postgresql: 'postgres.js', docker: true } - } -].flatMap((opts) => kitOnly.map((variant) => ({ ...opts, variant }))); - -test.concurrent.for(testCases)( - 'queries database - $name - $variant', - async ({ options, variant }, { page, ...ctx }) => { - if (options.docker && noDocker) ctx.skip(); - const cwd = await ctx.run(variant, { drizzle: options as any }); +test.concurrent.for(flavors)('drizzle $kind.type $variant', async (flavor, { page, ...ctx }) => { + if (flavor.kind.options.drizzle.docker && noDocker) ctx.skip(); + const cwd = ctx.run(flavor); - const ts = variant === 'kit-ts'; - const drizzleConfig = path.resolve(cwd, `drizzle.config.${ts ? 'ts' : 'js'}`); - const content = fs.readFileSync(drizzleConfig, 'utf8').replace(/strict: true[,\s]/, ''); - fs.writeFileSync(drizzleConfig, content, 'utf8'); + const ts = flavor.variant === 'kit-ts'; + const drizzleConfig = path.resolve(cwd, `drizzle.config.${ts ? 'ts' : 'js'}`); + const content = fs.readFileSync(drizzleConfig, 'utf8').replace(/strict: true[,\s]/, ''); + fs.writeFileSync(drizzleConfig, content, 'utf8'); - const routes = path.resolve(cwd, 'src', 'routes'); - const pagePath = path.resolve(routes, '+page.svelte'); - fs.writeFileSync(pagePath, pageComp, 'utf8'); + const routes = path.resolve(cwd, 'src', 'routes'); + const pagePath = path.resolve(routes, '+page.svelte'); + fs.writeFileSync(pagePath, pageComp, 'utf8'); - const pageServerPath = path.resolve(routes, `+page.server.${ts ? 'ts' : 'js'}`); - fs.writeFileSync(pageServerPath, pageServer, 'utf8'); + const pageServerPath = path.resolve(routes, `+page.server.${ts ? 'ts' : 'js'}`); + fs.writeFileSync(pageServerPath, pageServer, 'utf8'); - const { close } = await prepareServer({ cwd, page }, () => { - execSync('npm run db:push', { cwd, stdio: 'pipe' }); - }); - // kill server process when we're done - ctx.onTestFinished(async () => await close()); + const { close } = await prepareServer({ cwd, page }, () => { + execSync('npm run db:push', { cwd, stdio: 'pipe' }); + }); + // kill server process when we're done + ctx.onTestFinished(async () => await close()); - expect(page.locator('[data-testid]')).toBeTruthy(); - } -); + expect(page.locator('[data-testid]')).toBeTruthy(); +}); diff --git a/packages/addons/_tests/eslint/test.ts b/packages/addons/_tests/eslint/test.ts index aa0ad8c88..3567d93de 100644 --- a/packages/addons/_tests/eslint/test.ts +++ b/packages/addons/_tests/eslint/test.ts @@ -4,16 +4,17 @@ import { execSync } from 'node:child_process'; import { setupTest } from '../_setup/suite.ts'; import eslint from '../../eslint/index.ts'; -const { test, variants } = setupTest({ eslint }, { browser: false }); +const { test, flavors } = setupTest( + { eslint }, + { kinds: [{ type: 'default', options: { eslint: {} } }], browser: false } +); -test.concurrent.for(variants)('core - %s', async (variant, { expect, ...ctx }) => { - const cwd = await ctx.run(variant, { eslint: {} }); +test.concurrent.for(flavors)('eslint $variant', (flavor, { expect, ...ctx }) => { + const cwd = ctx.run(flavor); const unlintedFile = 'let foo = "";\nif (Boolean(foo)) {\n//\n}'; fs.writeFileSync(path.resolve(cwd, 'src/lib/foo.js'), unlintedFile, 'utf8'); - expect(() => execSync('pnpm install', { cwd, stdio: 'pipe' })).not.toThrow(); - expect(() => execSync('pnpm lint', { cwd, stdio: 'pipe' })).toThrow(); expect(() => execSync('pnpm eslint --fix .', { cwd, stdio: 'pipe' })).not.toThrow(); diff --git a/packages/addons/_tests/lucia/test.ts b/packages/addons/_tests/lucia/test.ts index c95ac959f..a1147df76 100644 --- a/packages/addons/_tests/lucia/test.ts +++ b/packages/addons/_tests/lucia/test.ts @@ -2,19 +2,31 @@ import { expect } from '@playwright/test'; import { setupTest } from '../_setup/suite.ts'; import lucia from '../../lucia/index.ts'; import drizzle from '../../drizzle/index.ts'; +import path from 'node:path'; +import fs from 'node:fs'; -const { test, variants, prepareServer } = setupTest({ drizzle, lucia }); +const { test, flavors, prepareServer } = setupTest( + { drizzle, lucia }, + { + kinds: [ + { + type: 'default', + options: { drizzle: { database: 'sqlite', sqlite: 'libsql' }, lucia: { demo: true } } + } + ], + filter: (flavor) => flavor.variant.includes('kit') + } +); -const kitOnly = variants.filter((v) => v.includes('kit')); -test.concurrent.for(kitOnly)('core - %s', async (variant, { page, ...ctx }) => { - const cwd = await ctx.run(variant, { - drizzle: { database: 'sqlite', sqlite: 'libsql' }, - lucia: { demo: true } - }); +test.concurrent.for(flavors)('lucia $variant', async (flavor, { page, ...ctx }) => { + const cwd = ctx.run(flavor); const { close } = await prepareServer({ cwd, page }); // kill server process when we're done ctx.onTestFinished(async () => await close()); - expect(true).toBe(true); + const ext = flavor.variant.includes('ts') ? 'ts' : 'js'; + const filePath = path.resolve(cwd, `src/routes/demo/lucia/+page.server.${ext}`); + const fileContent = fs.readFileSync(filePath, 'utf8'); + expect(fileContent).toContain(`export const actions`); }); diff --git a/packages/addons/_tests/mdsvex/test.ts b/packages/addons/_tests/mdsvex/test.ts index 630fb6d97..e6a5c9ece 100644 --- a/packages/addons/_tests/mdsvex/test.ts +++ b/packages/addons/_tests/mdsvex/test.ts @@ -8,13 +8,16 @@ import { setupTest } from '../_setup/suite.ts'; import { svxFile } from './fixtures.ts'; import mdsvex from '../../mdsvex/index.ts'; -const { test, variants, prepareServer } = setupTest({ mdsvex }); +const { test, flavors, prepareServer } = setupTest( + { mdsvex }, + { kinds: [{ type: 'default', options: { mdsvex: {} } }] } +); -test.concurrent.for(variants)('core - %s', async (variant, { page, ...ctx }) => { - const cwd = await ctx.run(variant, { mdsvex: {} }); +test.concurrent.for(flavors)('mdsvex $variant', async (flavor, { page, ...ctx }) => { + const cwd = ctx.run(flavor); // ...add test files - addFixture(cwd, variant); + addFixture(cwd, flavor.variant); const { close } = await prepareServer({ cwd, page }); // kill server process when we're done diff --git a/packages/addons/_tests/paraglide/test.ts b/packages/addons/_tests/paraglide/test.ts index 67c68eff9..64746ebcb 100644 --- a/packages/addons/_tests/paraglide/test.ts +++ b/packages/addons/_tests/paraglide/test.ts @@ -1,16 +1,31 @@ import { expect } from '@playwright/test'; import { setupTest } from '../_setup/suite.ts'; import paraglide from '../../paraglide/index.ts'; +import fs from 'node:fs'; +import path from 'node:path'; -const { test, variants, prepareServer } = setupTest({ paraglide }); +const langs = ['en', 'fr', 'hu']; -const kitOnly = variants.filter((v) => v.includes('kit')); -test.concurrent.for(kitOnly)('core - %s', async (variant, { page, ...ctx }) => { - const cwd = await ctx.run(variant, { paraglide: { demo: true, languageTags: 'en' } }); +const { test, flavors, prepareServer } = setupTest( + { paraglide }, + { + kinds: [ + { type: 'default', options: { paraglide: { demo: true, languageTags: langs.join(',') } } } + ], + filter: (flavor) => flavor.variant.includes('kit') + } +); + +test.concurrent.for(flavors)('paraglide $variant', async (flavor, { page, ...ctx }) => { + const cwd = ctx.run(flavor); const { close } = await prepareServer({ cwd, page }); // kill server process when we're done ctx.onTestFinished(async () => await close()); - expect(true).toBe(true); + for (const lang of langs) { + const filePath = path.resolve(cwd, `src/lib/paraglide/messages/${lang}.js`); + const fileContent = fs.readFileSync(filePath, 'utf8'); + expect(fileContent).toContain(`hello_world`); + } }); diff --git a/packages/addons/_tests/playwright/test.ts b/packages/addons/_tests/playwright/test.ts index f47720023..cc0fe8155 100644 --- a/packages/addons/_tests/playwright/test.ts +++ b/packages/addons/_tests/playwright/test.ts @@ -3,12 +3,15 @@ import path from 'node:path'; import { setupTest } from '../_setup/suite.ts'; import playwright from '../../playwright/index.ts'; -const { test, variants } = setupTest({ playwright }, { browser: false }); +const { test, flavors } = setupTest( + { playwright }, + { kinds: [{ type: 'default', options: { playwright: {} } }], browser: false } +); -test.concurrent.for(variants)('core - %s', async (variant, { expect, ...ctx }) => { - const cwd = await ctx.run(variant, { playwright: {} }); +test.concurrent.for(flavors)('playwright $variant', (flavor, { expect, ...ctx }) => { + const cwd = ctx.run(flavor); - const ext = variant.includes('ts') ? 'ts' : 'js'; + const ext = flavor.variant.includes('ts') ? 'ts' : 'js'; const playwrightConfig = path.resolve(cwd, `playwright.config.${ext}`); const configContent = fs.readFileSync(playwrightConfig, 'utf8'); diff --git a/packages/addons/_tests/prettier/test.ts b/packages/addons/_tests/prettier/test.ts index 65cf486ae..ff2b74d8b 100644 --- a/packages/addons/_tests/prettier/test.ts +++ b/packages/addons/_tests/prettier/test.ts @@ -9,7 +9,7 @@ const { test, flavors } = setupTest( { kinds: [{ type: 'default', options: { prettier: {} } }], browser: false } ); -test.concurrent.for(flavors)('core - %variant', (flavor, { expect, ...ctx }) => { +test.concurrent.for(flavors)('prettier $variant', (flavor, { expect, ...ctx }) => { const cwd = ctx.run(flavor); const unformattedFile = 'const foo = "bar"'; diff --git a/packages/addons/_tests/storybook/test.ts b/packages/addons/_tests/storybook/test.ts index 2c5878b5f..6dfa714c8 100644 --- a/packages/addons/_tests/storybook/test.ts +++ b/packages/addons/_tests/storybook/test.ts @@ -7,7 +7,10 @@ import storybook from '../../storybook/index.ts'; import eslint from '../../eslint/index.ts'; // we're including the `eslint` add-on to prevent `storybook` from modifying this repo's `eslint.config.js` -const { test, variants, prepareServer } = setupTest({ storybook, eslint }); +const { test, flavors, prepareServer } = setupTest( + { storybook, eslint }, + { kinds: [{ type: 'default', options: { storybook: {}, eslint: {} } }] } +); let port = 6006; const CI = Boolean(process.env.CI); @@ -19,22 +22,18 @@ beforeAll(() => { } }); -test.for(variants)( - 'storybook loaded - %s', - { concurrent: !CI }, - async (variant, { page, ...ctx }) => { - const cwd = await ctx.run(variant, { storybook: {}, eslint: {} }); +test.for(flavors)('storybook $variant', { concurrent: !CI }, async (flavor, { page, ...ctx }) => { + const cwd = ctx.run(flavor); - const { close } = await prepareServer({ - cwd, - page, - previewCommand: `pnpm storybook -p ${++port} --ci`, - buildCommand: '' - }); - // kill server process when we're done - ctx.onTestFinished(async () => await close()); + const { close } = await prepareServer({ + cwd, + page, + previewCommand: `pnpm storybook -p ${++port} --ci`, + buildCommand: '' + }); + // kill server process when we're done + ctx.onTestFinished(async () => await close()); - expect(page.locator('main .sb-bar')).toBeTruthy(); - expect(page.locator('#storybook-preview-wrapper')).toBeTruthy(); - } -); + expect(page.locator('main .sb-bar')).toBeTruthy(); + expect(page.locator('#storybook-preview-wrapper')).toBeTruthy(); +}); diff --git a/packages/addons/_tests/sveltekit-adapter/test.ts b/packages/addons/_tests/sveltekit-adapter/test.ts index 9534e65a6..d8c18b914 100644 --- a/packages/addons/_tests/sveltekit-adapter/test.ts +++ b/packages/addons/_tests/sveltekit-adapter/test.ts @@ -5,31 +5,33 @@ import sveltekitAdapter from '../../sveltekit-adapter/index.ts'; import { setupTest } from '../_setup/suite.ts'; const addonId = sveltekitAdapter.id; -const { test, variants, prepareServer } = setupTest({ [addonId]: sveltekitAdapter }); +const { test, flavors, prepareServer } = setupTest( + { [addonId]: sveltekitAdapter }, + { + kinds: [ + { type: 'node', options: { [addonId]: { adapter: 'node' } } }, + { type: 'auto', options: { [addonId]: { adapter: 'auto' } } } + ], + filter: (flavor) => flavor.variant.includes('kit') + } +); -const kitOnly = variants.filter((v) => v.includes('kit')); -test.concurrent.for(kitOnly)('core - %s', async (variant, { page, ...ctx }) => { - const cwd = await ctx.run(variant, { [addonId]: { adapter: 'node' } }); +test.concurrent.for(flavors)('adapter $kind.type $variant', async (flavor, { page, ...ctx }) => { + const cwd = ctx.run(flavor); const { close } = await prepareServer({ cwd, page }); // kill server process when we're done ctx.onTestFinished(async () => await close()); - expect(await readFile(join(cwd, 'svelte.config.js'), 'utf8')).not.toMatch('adapter-auto'); - expect(await readFile(join(cwd, 'svelte.config.js'), 'utf8')).not.toMatch( - 'adapter-auto only supports some environments' - ); -}); - -test.concurrent.for(kitOnly)('core - %s', async (variant, { page, ...ctx }) => { - const cwd = await ctx.run(variant, { [addonId]: { adapter: 'auto' } }); - - const { close } = await prepareServer({ cwd, page }); - // kill server process when we're done - ctx.onTestFinished(async () => await close()); - - expect(await readFile(join(cwd, 'svelte.config.js'), 'utf8')).toMatch('adapter-auto'); - expect(await readFile(join(cwd, 'svelte.config.js'), 'utf8')).toMatch( - 'adapter-auto only supports some environments' - ); + if (flavor.kind.type === 'node') { + expect(await readFile(join(cwd, 'svelte.config.js'), 'utf8')).not.toMatch('adapter-auto'); + expect(await readFile(join(cwd, 'svelte.config.js'), 'utf8')).not.toMatch( + 'adapter-auto only supports some environments' + ); + } else if (flavor.kind.type === 'auto') { + expect(await readFile(join(cwd, 'svelte.config.js'), 'utf8')).toMatch('adapter-auto'); + expect(await readFile(join(cwd, 'svelte.config.js'), 'utf8')).toMatch( + 'adapter-auto only supports some environments' + ); + } }); diff --git a/packages/addons/_tests/tailwindcss/test.ts b/packages/addons/_tests/tailwindcss/test.ts index cfde379b5..dacf45f58 100644 --- a/packages/addons/_tests/tailwindcss/test.ts +++ b/packages/addons/_tests/tailwindcss/test.ts @@ -14,7 +14,7 @@ const { test, prepareServer, flavors } = setupTest( ); test.concurrent.for(flavors)( - 'tailwindcss $kind.type $variant ', + 'tailwindcss $kind.type $variant', async (flavor, { page, ...ctx }) => { const cwd = ctx.run(flavor); diff --git a/packages/addons/_tests/vitest/test.ts b/packages/addons/_tests/vitest/test.ts index aa39b0633..404f3cf24 100644 --- a/packages/addons/_tests/vitest/test.ts +++ b/packages/addons/_tests/vitest/test.ts @@ -2,10 +2,13 @@ import { execSync } from 'node:child_process'; import { setupTest } from '../_setup/suite.ts'; import vitest from '../../vitest-addon/index.ts'; -const { test, variants } = setupTest({ vitest }, { browser: false }); +const { test, flavors } = setupTest( + { vitest }, + { kinds: [{ type: 'default', options: { vitest: {} } }], browser: false } +); -test.concurrent.for(variants)('core - %s', async (variant, { expect, ...ctx }) => { - const cwd = await ctx.run(variant, { vitest: {} }); +test.concurrent.for(flavors)('vitest %variant', (flavor, { expect, ...ctx }) => { + const cwd = ctx.run(flavor); expect(() => execSync('pnpm install', { cwd, stdio: 'pipe' })).not.toThrow(); From 9114c74f58a9ac646d7aa9c76d32ce270b19d46d Mon Sep 17 00:00:00 2001 From: jycouet Date: Thu, 18 Sep 2025 00:07:45 +0200 Subject: [PATCH 03/30] rmv ps-tree --- packages/cli/lib/testing.ts | 34 +++++------------ packages/cli/package.json | 2 - pnpm-lock.yaml | 74 ------------------------------------- 3 files changed, 10 insertions(+), 100 deletions(-) diff --git a/packages/cli/lib/testing.ts b/packages/cli/lib/testing.ts index 98f5cdae4..998e95424 100644 --- a/packages/cli/lib/testing.ts +++ b/packages/cli/lib/testing.ts @@ -4,7 +4,6 @@ import process from 'node:process'; import degit from 'degit'; import { exec } from 'tinyexec'; import { create } from '@sveltejs/create'; -import pstree, { type PS } from 'ps-tree'; export { addPnpmBuildDependencies } from '../utils/package-manager.ts'; export type ProjectVariant = 'kit-js' | 'kit-ts' | 'vite-js' | 'vite-ts'; @@ -122,31 +121,18 @@ export async function startPreview({ }); } -async function getProcessTree(pid: number) { - return new Promise((res, rej) => { - pstree(pid, (err, children) => { - if (err) rej(err); - res(children); - }); - }); -} - async function terminate(pid: number) { - const children = await getProcessTree(pid); - // the process tree is ordered from parents -> children, - // so we'll iterate in the reverse order to terminate the children first - for (let i = children.length - 1; i >= 0; i--) { - const child = children[i]; - const pid = Number(child.PID); - kill(pid); - } - kill(pid); -} - -function kill(pid: number) { try { - process.kill(pid); + if (process.platform === 'win32') { + await exec(`taskkill /pid ${pid} /T /F`); // on windows, use taskkill to terminate the process tree + } else { + process.kill(-pid, 'SIGTERM'); // Kill the process group + } } catch { - // this can happen if a process has been automatically terminated. + try { + process.kill(pid, 'SIGTERM'); // Kill just the process + } catch { + // Process might already be terminated + } } } diff --git a/packages/cli/package.json b/packages/cli/package.json index 23e3d79a2..014c8e0f0 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -35,13 +35,11 @@ "@sveltejs/cli-core": "workspace:*", "@sveltejs/create": "workspace:*", "@types/degit": "^2.8.6", - "@types/ps-tree": "^1.1.6", "commander": "^13.1.0", "degit": "^2.8.4", "empathic": "^1.1.0", "package-manager-detector": "^0.2.11", "picocolors": "^1.1.1", - "ps-tree": "^1.2.0", "tinyexec": "^0.3.2", "valibot": "^0.41.0" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 93c9ad4f8..30594fb70 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -112,9 +112,6 @@ importers: '@types/degit': specifier: ^2.8.6 version: 2.8.6 - '@types/ps-tree': - specifier: ^1.1.6 - version: 1.1.6 commander: specifier: ^13.1.0 version: 13.1.0 @@ -130,9 +127,6 @@ importers: picocolors: specifier: ^1.1.1 version: 1.1.1 - ps-tree: - specifier: ^1.2.0 - version: 1.2.0 tinyexec: specifier: ^0.3.2 version: 0.3.2 @@ -889,9 +883,6 @@ packages: '@types/prompts@2.4.9': resolution: {integrity: sha512-qTxFi6Buiu8+50/+3DGIWLHM6QuWsEKugJnnP6iv2Mc4ncxE4A/OJkjuVOA+5X0X1S/nq5VJRa8Lu+nwcvbrKA==} - '@types/ps-tree@1.1.6': - resolution: {integrity: sha512-PtrlVaOaI44/3pl3cvnlK+GxOM3re2526TJvPvh7W+keHIXdV4TE0ylpPBAcvFQCbGitaTXwL9u+RF7qtVeazQ==} - '@types/semver@7.7.0': resolution: {integrity: sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==} @@ -1189,9 +1180,6 @@ packages: resolution: {integrity: sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==} engines: {node: '>=12'} - duplexer@0.1.2: - resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} - eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} @@ -1322,9 +1310,6 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} - event-stream@3.3.4: - resolution: {integrity: sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==} - expect-type@1.2.2: resolution: {integrity: sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==} engines: {node: '>=12.0.0'} @@ -1390,9 +1375,6 @@ packages: resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} - from@0.1.7: - resolution: {integrity: sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==} - fs-extra@7.0.1: resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} engines: {node: '>=6 <7 || >=8'} @@ -1602,9 +1584,6 @@ packages: magic-string@0.30.17: resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} - map-stream@0.1.0: - resolution: {integrity: sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==} - merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} @@ -1737,9 +1716,6 @@ packages: resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} engines: {node: '>= 14.16'} - pause-stream@0.0.11: - resolution: {integrity: sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==} - picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -1833,11 +1809,6 @@ packages: engines: {node: '>=14'} hasBin: true - ps-tree@1.2.0: - resolution: {integrity: sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==} - engines: {node: '>= 0.10'} - hasBin: true - punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -1935,9 +1906,6 @@ packages: spawndamnit@3.0.1: resolution: {integrity: sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==} - split@0.3.3: - resolution: {integrity: sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==} - sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} @@ -1947,9 +1915,6 @@ packages: std-env@3.9.0: resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} - stream-combiner@0.0.4: - resolution: {integrity: sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==} - string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -2018,9 +1983,6 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} - through@2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - tiny-glob@0.2.9: resolution: {integrity: sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==} @@ -2840,8 +2802,6 @@ snapshots: '@types/node': 18.19.112 kleur: 3.0.3 - '@types/ps-tree@1.1.6': {} - '@types/semver@7.7.0': {} '@typescript-eslint/eslint-plugin@8.34.1(@typescript-eslint/parser@8.34.1(eslint@9.29.0)(typescript@5.8.3))(eslint@9.29.0)(typescript@5.8.3)': @@ -3138,8 +3098,6 @@ snapshots: dotenv@16.5.0: {} - duplexer@0.1.2: {} - eastasianwidth@0.2.0: {} emoji-regex@8.0.0: {} @@ -3320,16 +3278,6 @@ snapshots: esutils@2.0.3: {} - event-stream@3.3.4: - dependencies: - duplexer: 0.1.2 - from: 0.1.7 - map-stream: 0.1.0 - pause-stream: 0.0.11 - split: 0.3.3 - stream-combiner: 0.0.4 - through: 2.3.8 - expect-type@1.2.2: {} extendable-error@0.1.7: {} @@ -3398,8 +3346,6 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 - from@0.1.7: {} - fs-extra@7.0.1: dependencies: graceful-fs: 4.2.11 @@ -3584,8 +3530,6 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 - map-stream@0.1.0: {} - merge2@1.4.1: {} micromatch@4.0.8: @@ -3702,10 +3646,6 @@ snapshots: pathval@2.0.1: {} - pause-stream@0.0.11: - dependencies: - through: 2.3.8 - picocolors@1.1.1: {} picomatch@2.3.1: {} @@ -3770,10 +3710,6 @@ snapshots: prettier@3.5.3: {} - ps-tree@1.2.0: - dependencies: - event-stream: 3.3.4 - punycode@2.3.1: {} quansync@0.2.10: {} @@ -3888,20 +3824,12 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 - split@0.3.3: - dependencies: - through: 2.3.8 - sprintf-js@1.0.3: {} stackback@0.0.2: {} std-env@3.9.0: {} - stream-combiner@0.0.4: - dependencies: - duplexer: 0.1.2 - string-width@4.2.3: dependencies: emoji-regex: 8.0.0 @@ -3988,8 +3916,6 @@ snapshots: dependencies: any-promise: 1.3.0 - through@2.3.8: {} - tiny-glob@0.2.9: dependencies: globalyzer: 0.1.0 From 5b4f5789574d72186191a71d0fc61970929b1660 Mon Sep 17 00:00:00 2001 From: jycouet Date: Thu, 18 Sep 2025 00:15:17 +0200 Subject: [PATCH 04/30] only kit for all addons (like before^^) --- packages/addons/_tests/all-addons/test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/addons/_tests/all-addons/test.ts b/packages/addons/_tests/all-addons/test.ts index 423332b47..9bfd85c42 100644 --- a/packages/addons/_tests/all-addons/test.ts +++ b/packages/addons/_tests/all-addons/test.ts @@ -17,7 +17,8 @@ const defaultOptions = officialAddons.reduce>((options, }, {}); const { test, flavors, prepareServer } = setupTest(addons, { - kinds: [{ type: 'default', options: defaultOptions }] + kinds: [{ type: 'default', options: defaultOptions }], + filter: (flavor) => flavor.variant.startsWith('kit') }); test.concurrent.for(flavors)('run all addons - $variant', async (flavor, { page, ...ctx }) => { From 3244ffb8a29aded193862b51dc62e27a73e91fe4 Mon Sep 17 00:00:00 2001 From: jycouet Date: Thu, 18 Sep 2025 00:28:32 +0200 Subject: [PATCH 05/30] naming --- packages/addons/_tests/vitest/test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/addons/_tests/vitest/test.ts b/packages/addons/_tests/vitest/test.ts index 404f3cf24..2dae2e0e3 100644 --- a/packages/addons/_tests/vitest/test.ts +++ b/packages/addons/_tests/vitest/test.ts @@ -7,7 +7,7 @@ const { test, flavors } = setupTest( { kinds: [{ type: 'default', options: { vitest: {} } }], browser: false } ); -test.concurrent.for(flavors)('vitest %variant', (flavor, { expect, ...ctx }) => { +test.concurrent.for(flavors)('vitest $variant', (flavor, { expect, ...ctx }) => { const cwd = ctx.run(flavor); expect(() => execSync('pnpm install', { cwd, stdio: 'pipe' })).not.toThrow(); From 237e39ae1efc16484d652ae1e990e427fe1ba56c Mon Sep 17 00:00:00 2001 From: jycouet Date: Thu, 18 Sep 2025 07:55:04 +0200 Subject: [PATCH 06/30] @tailwindcss/oxide test --- packages/addons/tailwindcss/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/addons/tailwindcss/index.ts b/packages/addons/tailwindcss/index.ts index 022d8d815..40a84bbfe 100644 --- a/packages/addons/tailwindcss/index.ts +++ b/packages/addons/tailwindcss/index.ts @@ -37,6 +37,7 @@ export default defineAddon({ sv.devDependency('tailwindcss', '^4.0.0'); sv.devDependency('@tailwindcss/vite', '^4.0.0'); + sv.pnpmBuildDependency('@tailwindcss/oxide'); if (prettierInstalled) sv.devDependency('prettier-plugin-tailwindcss', '^0.6.11'); From 46affd256af866e710c73a1af11ef512ac9ed041 Mon Sep 17 00:00:00 2001 From: jycouet Date: Thu, 18 Sep 2025 08:11:19 +0200 Subject: [PATCH 07/30] back --- packages/addons/tailwindcss/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/addons/tailwindcss/index.ts b/packages/addons/tailwindcss/index.ts index 40a84bbfe..022d8d815 100644 --- a/packages/addons/tailwindcss/index.ts +++ b/packages/addons/tailwindcss/index.ts @@ -37,7 +37,6 @@ export default defineAddon({ sv.devDependency('tailwindcss', '^4.0.0'); sv.devDependency('@tailwindcss/vite', '^4.0.0'); - sv.pnpmBuildDependency('@tailwindcss/oxide'); if (prettierInstalled) sv.devDependency('prettier-plugin-tailwindcss', '^0.6.11'); From cf15192ebc5953e5071b2dd641d24a357ee1e6cd Mon Sep 17 00:00:00 2001 From: jycouet Date: Thu, 18 Sep 2025 08:15:14 +0200 Subject: [PATCH 08/30] test & pnpm --- .changeset/lazy-windows-repeat.md | 5 +++++ packages/addons/_tests/_setup/suite.ts | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 .changeset/lazy-windows-repeat.md diff --git a/.changeset/lazy-windows-repeat.md b/.changeset/lazy-windows-repeat.md new file mode 100644 index 000000000..55c60c9a7 --- /dev/null +++ b/.changeset/lazy-windows-repeat.md @@ -0,0 +1,5 @@ +--- +'sv': patch +--- + +chore(cli): speedup internal tests v2 diff --git a/packages/addons/_tests/_setup/suite.ts b/packages/addons/_tests/_setup/suite.ts index 3ea37d9b6..c5ea21572 100644 --- a/packages/addons/_tests/_setup/suite.ts +++ b/packages/addons/_tests/_setup/suite.ts @@ -139,9 +139,9 @@ async function prepareServer( { cwd, page, - previewCommand = 'npm run preview', - buildCommand = 'npm run build', - installCommand + installCommand, + buildCommand = 'pnpm build', + previewCommand = 'pnpm preview' }: PrepareServerOptions, afterInstall?: () => Promise | any ) { From b6ecec841b1f103434443a6ff883991c8493d7b2 Mon Sep 17 00:00:00 2001 From: jycouet Date: Thu, 18 Sep 2025 08:42:08 +0200 Subject: [PATCH 09/30] naming --- packages/addons/_tests/_setup/suite.ts | 25 ++++++++++++------------- packages/addons/_tests/drizzle/test.ts | 8 ++++++-- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/packages/addons/_tests/_setup/suite.ts b/packages/addons/_tests/_setup/suite.ts index c5ea21572..eadee8f55 100644 --- a/packages/addons/_tests/_setup/suite.ts +++ b/packages/addons/_tests/_setup/suite.ts @@ -130,26 +130,25 @@ export function setupTest( type PrepareServerOptions = { cwd: string; page: Page; - previewCommand?: string; - buildCommand?: string; installCommand?: string; + beforeBuild?: () => Promise | any; + buildCommand?: string; + previewCommand?: string; }; // installs dependencies, builds the project, and spins up the preview server -async function prepareServer( - { - cwd, - page, - installCommand, - buildCommand = 'pnpm build', - previewCommand = 'pnpm preview' - }: PrepareServerOptions, - afterInstall?: () => Promise | any -) { +async function prepareServer({ + cwd, + page, + installCommand, // should happen in the beforeAll hook + beforeBuild, + buildCommand = 'pnpm build', + previewCommand = 'pnpm preview' +}: PrepareServerOptions) { // install deps if (installCommand) execSync(installCommand, { cwd, stdio: 'pipe' }); // ...do commands and any other extra stuff - await afterInstall?.(); + await beforeBuild?.(); // build project if (buildCommand) execSync(buildCommand, { cwd, stdio: 'pipe' }); diff --git a/packages/addons/_tests/drizzle/test.ts b/packages/addons/_tests/drizzle/test.ts index 3bc729ab2..e643d665d 100644 --- a/packages/addons/_tests/drizzle/test.ts +++ b/packages/addons/_tests/drizzle/test.ts @@ -68,8 +68,12 @@ test.concurrent.for(flavors)('drizzle $kind.type $variant', async (flavor, { pag const pageServerPath = path.resolve(routes, `+page.server.${ts ? 'ts' : 'js'}`); fs.writeFileSync(pageServerPath, pageServer, 'utf8'); - const { close } = await prepareServer({ cwd, page }, () => { - execSync('npm run db:push', { cwd, stdio: 'pipe' }); + const { close } = await prepareServer({ + cwd, + page, + beforeBuild: () => { + execSync('npm run db:push', { cwd, stdio: 'pipe' }); + } }); // kill server process when we're done ctx.onTestFinished(async () => await close()); From 807016d1d2e69f9a14d5c524c303a6ee3bba3322 Mon Sep 17 00:00:00 2001 From: "jyc.dev" Date: Wed, 24 Sep 2025 18:09:35 +0200 Subject: [PATCH 10/30] feat(cli): pnpm config will now be stored in pnpm-workspace.yaml (#718) * fix(tailwindcss): add `@tailwindcss/oxide` to approve-builds in `pnpm` * addd yaml utils * using yaml-workspace when possible * windows robustness * CI debug * more logs * !silent * CI & windows & I don't know * sniff * . * more and more logs * pnpm v * cleanup! * --silent * add changeset --- .changeset/nasty-towns-crash.md | 5 + .changeset/solid-dragons-trade.md | 5 + community-addon-template/tests/setup/suite.ts | 2 +- package.json | 7 +- packages/addons/_tests/_setup/suite.ts | 2 +- packages/addons/tailwindcss/index.ts | 1 + packages/cli/commands/add/index.ts | 2 +- packages/cli/commands/create.ts | 2 +- packages/cli/lib/testing.ts | 6 +- packages/cli/utils/package-manager.ts | 98 ++++++++++++------- packages/core/package.json | 1 + packages/core/tests/utils.ts | 90 ++++++++++++++++- packages/core/tooling/index.ts | 9 ++ packages/core/tooling/parsers.ts | 10 ++ pnpm-lock.yaml | 29 ++++-- pnpm-workspace.yaml | 3 + 16 files changed, 215 insertions(+), 57 deletions(-) create mode 100644 .changeset/nasty-towns-crash.md create mode 100644 .changeset/solid-dragons-trade.md diff --git a/.changeset/nasty-towns-crash.md b/.changeset/nasty-towns-crash.md new file mode 100644 index 000000000..9e9f474d2 --- /dev/null +++ b/.changeset/nasty-towns-crash.md @@ -0,0 +1,5 @@ +--- +'sv': patch +--- + +fix(tailwindcss): add `@tailwindcss/oxide` to approve-builds in `pnpm` diff --git a/.changeset/solid-dragons-trade.md b/.changeset/solid-dragons-trade.md new file mode 100644 index 000000000..481b024ed --- /dev/null +++ b/.changeset/solid-dragons-trade.md @@ -0,0 +1,5 @@ +--- +'sv': patch +--- + +feat(cli): pnpm config will now be stored in `pnpm-workspace.yaml` (e.g. `onlyBuiltDependencies`) diff --git a/community-addon-template/tests/setup/suite.ts b/community-addon-template/tests/setup/suite.ts index 3b7c04138..db7dd06d1 100644 --- a/community-addon-template/tests/setup/suite.ts +++ b/community-addon-template/tests/setup/suite.ts @@ -78,7 +78,7 @@ export function setupTest(addons: Addons) { options, packageManager: 'pnpm' }); - addPnpmBuildDependencies(cwd, 'pnpm', ['esbuild', ...pnpmBuildDependencies]); + await addPnpmBuildDependencies(cwd, 'pnpm', ['esbuild', ...pnpmBuildDependencies]); return cwd; }; diff --git a/package.json b/package.json index 82cbc963e..da6e3308b 100644 --- a/package.json +++ b/package.json @@ -40,10 +40,5 @@ "unplugin-isolated-decl": "^0.8.3", "vitest": "4.0.0-beta.6" }, - "packageManager": "pnpm@10.4.1", - "pnpm": { - "onlyBuiltDependencies": [ - "esbuild" - ] - } + "packageManager": "pnpm@10.17.0" } diff --git a/packages/addons/_tests/_setup/suite.ts b/packages/addons/_tests/_setup/suite.ts index eadee8f55..9eb500b5b 100644 --- a/packages/addons/_tests/_setup/suite.ts +++ b/packages/addons/_tests/_setup/suite.ts @@ -98,7 +98,7 @@ export function setupTest( options: kind.options, packageManager: 'pnpm' }); - addPnpmBuildDependencies(cwd, 'pnpm', ['esbuild', ...pnpmBuildDependencies]); + await addPnpmBuildDependencies(cwd, 'pnpm', ['esbuild', ...pnpmBuildDependencies]); } execSync('pnpm install', { cwd: path.resolve(cwd, testName), stdio: 'pipe' }); diff --git a/packages/addons/tailwindcss/index.ts b/packages/addons/tailwindcss/index.ts index 022d8d815..40a84bbfe 100644 --- a/packages/addons/tailwindcss/index.ts +++ b/packages/addons/tailwindcss/index.ts @@ -37,6 +37,7 @@ export default defineAddon({ sv.devDependency('tailwindcss', '^4.0.0'); sv.devDependency('@tailwindcss/vite', '^4.0.0'); + sv.pnpmBuildDependency('@tailwindcss/oxide'); if (prettierInstalled) sv.devDependency('prettier-plugin-tailwindcss', '^0.6.11'); diff --git a/packages/cli/commands/add/index.ts b/packages/cli/commands/add/index.ts index f5945575d..2223250c3 100644 --- a/packages/cli/commands/add/index.ts +++ b/packages/cli/commands/add/index.ts @@ -559,7 +559,7 @@ export async function runAddCommand( if (packageManager) { workspace.packageManager = packageManager; - addPnpmBuildDependencies(workspace.cwd, packageManager, [ + await addPnpmBuildDependencies(workspace.cwd, packageManager, [ 'esbuild', ...addonPnpmBuildDependencies ]); diff --git a/packages/cli/commands/create.ts b/packages/cli/commands/create.ts index 386c801fd..acd8112f9 100644 --- a/packages/cli/commands/create.ts +++ b/packages/cli/commands/create.ts @@ -204,7 +204,7 @@ async function createProject(cwd: ProjectPath, options: Options) { const installDeps = async (install: true | AgentName) => { packageManager = install === true ? await packageManagerPrompt(projectPath) : install; - addPnpmBuildDependencies(projectPath, packageManager, ['esbuild']); + await addPnpmBuildDependencies(projectPath, packageManager, ['esbuild']); if (packageManager) await installDependencies(packageManager, projectPath); }; diff --git a/packages/cli/lib/testing.ts b/packages/cli/lib/testing.ts index 998e95424..b4c291446 100644 --- a/packages/cli/lib/testing.ts +++ b/packages/cli/lib/testing.ts @@ -2,7 +2,7 @@ import fs from 'node:fs'; import path from 'node:path'; import process from 'node:process'; import degit from 'degit'; -import { exec } from 'tinyexec'; +import { x, exec } from 'tinyexec'; import { create } from '@sveltejs/create'; export { addPnpmBuildDependencies } from '../utils/package-manager.ts'; @@ -83,7 +83,7 @@ export function createProject({ cwd, testName, templatesDir }: CreateOptions): C type PreviewOptions = { cwd: string; command?: string }; export async function startPreview({ cwd, - command = 'npm run preview' + command = 'pnpm preview' }: PreviewOptions): Promise<{ url: string; close: () => Promise }> { const [cmd, ...args] = command.split(' '); const proc = exec(cmd, args, { @@ -124,7 +124,7 @@ export async function startPreview({ async function terminate(pid: number) { try { if (process.platform === 'win32') { - await exec(`taskkill /pid ${pid} /T /F`); // on windows, use taskkill to terminate the process tree + await x('taskkill', ['/PID', `${pid}`, '/T', '/F']); // on windows, use taskkill to terminate the process tree } else { process.kill(-pid, 'SIGTERM'); // Kill the process group } diff --git a/packages/cli/utils/package-manager.ts b/packages/cli/utils/package-manager.ts index f53e48784..2c534c59e 100644 --- a/packages/cli/utils/package-manager.ts +++ b/packages/cli/utils/package-manager.ts @@ -2,7 +2,7 @@ import fs from 'node:fs'; import path from 'node:path'; import process from 'node:process'; import * as find from 'empathic/find'; -import { exec } from 'tinyexec'; +import { x } from 'tinyexec'; import { Option } from 'commander'; import * as p from '@clack/prompts'; import { @@ -12,7 +12,8 @@ import { detect, type AgentName } from 'package-manager-detector'; -import { parseJson } from '@sveltejs/cli-core/parsers'; +import { parseJson, parseYaml } from '@sveltejs/cli-core/parsers'; +import { isVersionUnsupportedBelow } from '@sveltejs/cli-core'; export const AGENT_NAMES = AGENTS.filter((agent): agent is AgentName => !agent.includes('@')); const agentOptions: PackageManagerOptions = AGENT_NAMES.map((pm) => ({ value: pm, label: pm })); @@ -55,19 +56,16 @@ export async function installDependencies(agent: AgentName, cwd: string): Promis try { const { command, args } = constructCommand(COMMANDS[agent].install, [])!; - const proc = exec(command, args, { + + const proc = x(command, args, { nodeOptions: { cwd, stdio: 'pipe' }, throwOnError: true }); - proc.process?.stdout?.on('data', (data) => { - task.message(data.toString(), { raw: true }); - }); - proc.process?.stderr?.on('data', (data) => { - task.message(data.toString(), { raw: true }); - }); - - await proc; + for await (const line of proc) { + // line will be from stderr/stdout in the order you'd see it in a term + task.message(line, { raw: true }); + } task.success('Successfully installed dependencies'); } catch { @@ -87,35 +85,69 @@ export function getUserAgent(): AgentName | undefined { return AGENTS.includes(name) ? name : undefined; } -export function addPnpmBuildDependencies( +export async function addPnpmBuildDependencies( cwd: string, packageManager: AgentName | null | undefined, allowedPackages: string[] ) { // other package managers are currently not affected by this change - if (!packageManager || packageManager !== 'pnpm') return; + if (!packageManager || packageManager !== 'pnpm' || allowedPackages.length === 0) return; + + let confIn: 'package.json' | 'pnpm-workspace.yaml' = 'package.json'; + const pnpmVersion = await getPnpmVersion(); + if (pnpmVersion) { + confIn = isVersionUnsupportedBelow(pnpmVersion, '10.5') + ? 'package.json' + : 'pnpm-workspace.yaml'; + } // find the workspace root (if present) - const pnpmWorkspacePath = find.up('pnpm-workspace.yaml', { cwd }); - let packageDirectory; - - if (pnpmWorkspacePath) packageDirectory = path.dirname(pnpmWorkspacePath); - else packageDirectory = cwd; - - // load the package.json - const pkgPath = path.join(packageDirectory, 'package.json'); - const content = fs.readFileSync(pkgPath, 'utf-8'); - const { data, generateCode } = parseJson(content); - - // add the packages where we install scripts should be executed - data.pnpm ??= {}; - data.pnpm.onlyBuiltDependencies ??= []; - for (const allowedPackage of allowedPackages) { - if (data.pnpm.onlyBuiltDependencies.includes(allowedPackage)) continue; - data.pnpm.onlyBuiltDependencies.push(allowedPackage); + const found = find.up('pnpm-workspace.yaml', { cwd }); + const dir = found ? path.dirname(found) : cwd; + + if (confIn === 'pnpm-workspace.yaml') { + const content = found ? fs.readFileSync(found, 'utf-8') : ''; + const { data, generateCode } = parseYaml(content); + + const onlyBuiltDependencies = data.get('onlyBuiltDependencies'); + const items: Array<{ value: string } | string> = onlyBuiltDependencies?.items ?? []; + + for (const item of allowedPackages) { + if (items.includes(item)) continue; + if (items.some((y) => typeof y === 'object' && y.value === item)) continue; + items.push(item); + } + data.set('onlyBuiltDependencies', new Set(items)); + + const newContent = generateCode(); + + const pnpmWorkspacePath = found ?? path.join(cwd, 'pnpm-workspace.yaml'); + if (newContent !== content) fs.writeFileSync(pnpmWorkspacePath, newContent); + } else { + // else is package.json (fallback) + const pkgPath = path.join(dir, 'package.json'); + const content = fs.readFileSync(pkgPath, 'utf-8'); + const { data, generateCode } = parseJson(content); + + // add the packages where we install scripts should be executed + data.pnpm ??= {}; + data.pnpm.onlyBuiltDependencies ??= []; + for (const allowedPackage of allowedPackages) { + if (data.pnpm.onlyBuiltDependencies.includes(allowedPackage)) continue; + data.pnpm.onlyBuiltDependencies.push(allowedPackage); + } + + // save the updated package.json + const newContent = generateCode(); + if (newContent !== content) fs.writeFileSync(pkgPath, newContent); } +} - // save the updated package.json - const newContent = generateCode(); - fs.writeFileSync(pkgPath, newContent); +async function getPnpmVersion(): Promise { + let v: string | undefined = undefined; + try { + const proc = await x('pnpm', ['--version'], { throwOnError: true }); + v = proc.stdout.trim(); + } catch {} + return v; } diff --git a/packages/core/package.json b/packages/core/package.json index 8897e9904..4d9009beb 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -57,6 +57,7 @@ "picocolors": "^1.1.1", "postcss": "^8.5.6", "silver-fleece": "^1.2.1", + "yaml": "^2.8.1", "zimmerframe": "^1.1.2" }, "keywords": [ diff --git a/packages/core/tests/utils.ts b/packages/core/tests/utils.ts index 37979d0be..01139fbc4 100644 --- a/packages/core/tests/utils.ts +++ b/packages/core/tests/utils.ts @@ -1,11 +1,13 @@ -import { expect, test } from 'vitest'; +import { describe, expect, test } from 'vitest'; import dedent from 'dedent'; import { parseScript, serializeScript, guessIndentString, guessQuoteStyle, - type AstTypes + type AstTypes, + serializeYaml, + parseYaml } from '../tooling/index.ts'; test('guessIndentString - one tab', () => { @@ -183,3 +185,87 @@ test('integration - preserves comments', () => { let foo = 'bar';" `); }); + +describe('yaml', () => { + test('read and write', () => { + const input = dedent`foo: + - bar + - baz`; + const output = serializeYaml(parseYaml(input)); + expect(output).toMatchInlineSnapshot(` + "foo: + - bar + - baz + " + `); + }); + + test('edit object', () => { + const input = dedent`foo: + # nice comment + - bar + - baz`; + const doc = parseYaml(input); + const foo = doc.get('foo'); + if (foo) foo.add('yop'); + else doc.set('foo', ['yop']); + expect(serializeYaml(doc)).toMatchInlineSnapshot(` + "foo: + # nice comment + - bar + - baz + - yop + " + `); + }); + + test('add to array (keeping comments)', () => { + const input = dedent`foo: + - bar + # com + - baz`; + const doc = parseYaml(input); + const toAdd = ['bar', 'yop1', 'yop2', 'yop1']; + const foo = doc.get('foo'); + const items: Array<{ value: string } | string> = foo?.items ?? []; + for (const item of toAdd) { + if (items.includes(item)) continue; + if (items.some((y) => typeof y === 'object' && y.value === item)) continue; + items.push(item); + } + doc.set('foo', new Set(items)); + expect(serializeYaml(doc)).toMatchInlineSnapshot(` + "foo: + - bar + # com + - baz + - yop1 + - yop2 + " + `); + }); + + test('create object', () => { + const input = dedent`# this is my file`; + const doc = parseYaml(input); + const foo = doc.get('foo'); + if (foo) foo.add('yop'); + else doc.set('foo', ['yop']); + expect(serializeYaml(doc)).toMatchInlineSnapshot(` + "# this is my file + + foo: + - yop + " + `); + }); + + test('array of foo', () => { + const input = dedent`foo: # nice comment - bar - baz`; + const output = serializeYaml(parseYaml(input)); + expect(output).toMatchInlineSnapshot(` + "foo: # nice comment - bar - baz + " + `); + }); +}); diff --git a/packages/core/tooling/index.ts b/packages/core/tooling/index.ts index ac42aa48f..b2fbe43f2 100644 --- a/packages/core/tooling/index.ts +++ b/packages/core/tooling/index.ts @@ -16,6 +16,7 @@ import * as fleece from 'silver-fleece'; import { print as esrapPrint } from 'esrap'; import * as acorn from 'acorn'; import { tsPlugin } from '@sveltejs/acorn-typescript'; +import * as yaml from 'yaml'; export { // html @@ -238,3 +239,11 @@ export function guessQuoteStyle(ast: TsEstree.Node): 'single' | 'double' | undef return singleCount > doubleCount ? 'single' : 'double'; } + +export function parseYaml(content: string): ReturnType { + return yaml.parseDocument(content); +} + +export function serializeYaml(data: unknown): string { + return yaml.stringify(data, { singleQuote: true }); +} diff --git a/packages/core/tooling/parsers.ts b/packages/core/tooling/parsers.ts index f7764d34f..21b6b0993 100644 --- a/packages/core/tooling/parsers.ts +++ b/packages/core/tooling/parsers.ts @@ -35,6 +35,16 @@ export function parseJson(source: string): { data: any } & ParseBase { return { data, source, generateCode }; } +export function parseYaml( + source: string +): { data: ReturnType } & ParseBase { + if (!source) source = ''; + const data = utils.parseYaml(source); + const generateCode = () => utils.serializeYaml(data); + + return { data, source, generateCode }; +} + type SvelteGenerator = (code: { script?: string; module?: string; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 30594fb70..f62b6a131 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -67,7 +67,7 @@ importers: version: 0.8.3(rollup@4.46.2)(typescript@5.8.3) vitest: specifier: 4.0.0-beta.6 - version: 4.0.0-beta.6(@types/node@22.15.32)(@vitest/ui@4.0.0-beta.6) + version: 4.0.0-beta.6(@types/node@22.15.32)(@vitest/ui@4.0.0-beta.6)(yaml@2.8.1) community-addon-template: dependencies: @@ -83,7 +83,7 @@ importers: version: link:../packages/cli vitest: specifier: 4.0.0-beta.6 - version: 4.0.0-beta.6(@types/node@22.15.32)(@vitest/ui@4.0.0-beta.6) + version: 4.0.0-beta.6(@types/node@22.15.32)(@vitest/ui@4.0.0-beta.6)(yaml@2.8.1) packages/addons: dependencies: @@ -181,6 +181,9 @@ importers: silver-fleece: specifier: ^1.2.1 version: 1.2.1 + yaml: + specifier: ^2.8.1 + version: 2.8.1 zimmerframe: specifier: ^1.1.2 version: 1.1.2 @@ -2196,6 +2199,11 @@ packages: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} + yaml@2.8.1: + resolution: {integrity: sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==} + engines: {node: '>= 14.6'} + hasBin: true + yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} @@ -2904,13 +2912,13 @@ snapshots: chai: 5.2.1 tinyrainbow: 2.0.0 - '@vitest/mocker@4.0.0-beta.6(vite@7.0.6(@types/node@22.15.32))': + '@vitest/mocker@4.0.0-beta.6(vite@7.0.6(@types/node@22.15.32)(yaml@2.8.1))': dependencies: '@vitest/spy': 4.0.0-beta.6 estree-walker: 3.0.3 magic-string: 0.30.17 optionalDependencies: - vite: 7.0.6(@types/node@22.15.32) + vite: 7.0.6(@types/node@22.15.32)(yaml@2.8.1) '@vitest/pretty-format@4.0.0-beta.6': dependencies: @@ -2939,7 +2947,7 @@ snapshots: sirv: 3.0.1 tinyglobby: 0.2.14 tinyrainbow: 2.0.0 - vitest: 4.0.0-beta.6(@types/node@22.15.32)(@vitest/ui@4.0.0-beta.6) + vitest: 4.0.0-beta.6(@types/node@22.15.32)(@vitest/ui@4.0.0-beta.6)(yaml@2.8.1) '@vitest/utils@4.0.0-beta.6': dependencies: @@ -4010,7 +4018,7 @@ snapshots: optionalDependencies: typescript: 5.8.3 - vite@7.0.6(@types/node@22.15.32): + vite@7.0.6(@types/node@22.15.32)(yaml@2.8.1): dependencies: esbuild: 0.25.8 fdir: 6.4.6(picomatch@4.0.3) @@ -4021,12 +4029,13 @@ snapshots: optionalDependencies: '@types/node': 22.15.32 fsevents: 2.3.3 + yaml: 2.8.1 - vitest@4.0.0-beta.6(@types/node@22.15.32)(@vitest/ui@4.0.0-beta.6): + vitest@4.0.0-beta.6(@types/node@22.15.32)(@vitest/ui@4.0.0-beta.6)(yaml@2.8.1): dependencies: '@types/chai': 5.2.2 '@vitest/expect': 4.0.0-beta.6 - '@vitest/mocker': 4.0.0-beta.6(vite@7.0.6(@types/node@22.15.32)) + '@vitest/mocker': 4.0.0-beta.6(vite@7.0.6(@types/node@22.15.32)(yaml@2.8.1)) '@vitest/pretty-format': 4.0.0-beta.6 '@vitest/runner': 4.0.0-beta.6 '@vitest/snapshot': 4.0.0-beta.6 @@ -4045,7 +4054,7 @@ snapshots: tinyglobby: 0.2.14 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 7.0.6(@types/node@22.15.32) + vite: 7.0.6(@types/node@22.15.32)(yaml@2.8.1) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 22.15.32 @@ -4098,6 +4107,8 @@ snapshots: yaml@1.10.2: {} + yaml@2.8.1: {} + yocto-queue@0.1.0: {} zimmerframe@1.1.2: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 86c4b35e7..6e0eb8cb7 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -2,3 +2,6 @@ packages: - 'packages/*' - 'community-addon-template' - '!.test-tmp/**' + +onlyBuiltDependencies: + - esbuild From 142bde742d998117f00dceae573ff606748180f2 Mon Sep 17 00:00:00 2001 From: jycouet Date: Wed, 24 Sep 2025 23:28:56 +0200 Subject: [PATCH 11/30] . --- packages/cli/package.json | 2 ++ pnpm-lock.yaml | 74 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/packages/cli/package.json b/packages/cli/package.json index 021994137..a3effe99e 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -35,11 +35,13 @@ "@sveltejs/cli-core": "workspace:*", "@sveltejs/create": "workspace:*", "@types/degit": "^2.8.6", + "@types/ps-tree": "^1.1.6", "commander": "^13.1.0", "degit": "^2.8.4", "empathic": "^1.1.0", "package-manager-detector": "^0.2.11", "picocolors": "^1.1.1", + "ps-tree": "^1.2.0", "tinyexec": "^0.3.2", "valibot": "^0.41.0" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f62b6a131..1e49721ae 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -112,6 +112,9 @@ importers: '@types/degit': specifier: ^2.8.6 version: 2.8.6 + '@types/ps-tree': + specifier: ^1.1.6 + version: 1.1.6 commander: specifier: ^13.1.0 version: 13.1.0 @@ -127,6 +130,9 @@ importers: picocolors: specifier: ^1.1.1 version: 1.1.1 + ps-tree: + specifier: ^1.2.0 + version: 1.2.0 tinyexec: specifier: ^0.3.2 version: 0.3.2 @@ -886,6 +892,9 @@ packages: '@types/prompts@2.4.9': resolution: {integrity: sha512-qTxFi6Buiu8+50/+3DGIWLHM6QuWsEKugJnnP6iv2Mc4ncxE4A/OJkjuVOA+5X0X1S/nq5VJRa8Lu+nwcvbrKA==} + '@types/ps-tree@1.1.6': + resolution: {integrity: sha512-PtrlVaOaI44/3pl3cvnlK+GxOM3re2526TJvPvh7W+keHIXdV4TE0ylpPBAcvFQCbGitaTXwL9u+RF7qtVeazQ==} + '@types/semver@7.7.0': resolution: {integrity: sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==} @@ -1183,6 +1192,9 @@ packages: resolution: {integrity: sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==} engines: {node: '>=12'} + duplexer@0.1.2: + resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} @@ -1313,6 +1325,9 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} + event-stream@3.3.4: + resolution: {integrity: sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==} + expect-type@1.2.2: resolution: {integrity: sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==} engines: {node: '>=12.0.0'} @@ -1378,6 +1393,9 @@ packages: resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} + from@0.1.7: + resolution: {integrity: sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==} + fs-extra@7.0.1: resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} engines: {node: '>=6 <7 || >=8'} @@ -1587,6 +1605,9 @@ packages: magic-string@0.30.17: resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + map-stream@0.1.0: + resolution: {integrity: sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==} + merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} @@ -1719,6 +1740,9 @@ packages: resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} engines: {node: '>= 14.16'} + pause-stream@0.0.11: + resolution: {integrity: sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==} + picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -1812,6 +1836,11 @@ packages: engines: {node: '>=14'} hasBin: true + ps-tree@1.2.0: + resolution: {integrity: sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==} + engines: {node: '>= 0.10'} + hasBin: true + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -1909,6 +1938,9 @@ packages: spawndamnit@3.0.1: resolution: {integrity: sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==} + split@0.3.3: + resolution: {integrity: sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==} + sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} @@ -1918,6 +1950,9 @@ packages: std-env@3.9.0: resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} + stream-combiner@0.0.4: + resolution: {integrity: sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==} + string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -1986,6 +2021,9 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + tiny-glob@0.2.9: resolution: {integrity: sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==} @@ -2810,6 +2848,8 @@ snapshots: '@types/node': 18.19.112 kleur: 3.0.3 + '@types/ps-tree@1.1.6': {} + '@types/semver@7.7.0': {} '@typescript-eslint/eslint-plugin@8.34.1(@typescript-eslint/parser@8.34.1(eslint@9.29.0)(typescript@5.8.3))(eslint@9.29.0)(typescript@5.8.3)': @@ -3106,6 +3146,8 @@ snapshots: dotenv@16.5.0: {} + duplexer@0.1.2: {} + eastasianwidth@0.2.0: {} emoji-regex@8.0.0: {} @@ -3286,6 +3328,16 @@ snapshots: esutils@2.0.3: {} + event-stream@3.3.4: + dependencies: + duplexer: 0.1.2 + from: 0.1.7 + map-stream: 0.1.0 + pause-stream: 0.0.11 + split: 0.3.3 + stream-combiner: 0.0.4 + through: 2.3.8 + expect-type@1.2.2: {} extendable-error@0.1.7: {} @@ -3354,6 +3406,8 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 + from@0.1.7: {} + fs-extra@7.0.1: dependencies: graceful-fs: 4.2.11 @@ -3538,6 +3592,8 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 + map-stream@0.1.0: {} + merge2@1.4.1: {} micromatch@4.0.8: @@ -3654,6 +3710,10 @@ snapshots: pathval@2.0.1: {} + pause-stream@0.0.11: + dependencies: + through: 2.3.8 + picocolors@1.1.1: {} picomatch@2.3.1: {} @@ -3718,6 +3778,10 @@ snapshots: prettier@3.5.3: {} + ps-tree@1.2.0: + dependencies: + event-stream: 3.3.4 + punycode@2.3.1: {} quansync@0.2.10: {} @@ -3832,12 +3896,20 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 + split@0.3.3: + dependencies: + through: 2.3.8 + sprintf-js@1.0.3: {} stackback@0.0.2: {} std-env@3.9.0: {} + stream-combiner@0.0.4: + dependencies: + duplexer: 0.1.2 + string-width@4.2.3: dependencies: emoji-regex: 8.0.0 @@ -3924,6 +3996,8 @@ snapshots: dependencies: any-promise: 1.3.0 + through@2.3.8: {} + tiny-glob@0.2.9: dependencies: globalyzer: 0.1.0 From 0535e992b16ba1a74ad3ee7cb24518bdb93496af Mon Sep 17 00:00:00 2001 From: jycouet Date: Wed, 24 Sep 2025 23:33:36 +0200 Subject: [PATCH 12/30] tsc --- packages/addons/_tests/vitest/test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/addons/_tests/vitest/test.ts b/packages/addons/_tests/vitest/test.ts index da85ba9ad..b8e47626c 100644 --- a/packages/addons/_tests/vitest/test.ts +++ b/packages/addons/_tests/vitest/test.ts @@ -18,7 +18,7 @@ test.concurrent.for(flavors)('vitest $variant', (flavor, { expect, ...ctx }) => expect(() => execSync('pnpm test', { cwd, stdio: 'pipe' })).not.toThrow(); - const ext = variant.includes('ts') ? 'ts' : 'js'; + const ext = flavor.variant.includes('ts') ? 'ts' : 'js'; const viteFile = path.resolve(cwd, `vite.config.${ext}`); const viteContent = fs.readFileSync(viteFile, 'utf8'); From cf71e3f43dec3da71b367fd92f3545851aa9a5b7 Mon Sep 17 00:00:00 2001 From: jycouet Date: Fri, 26 Sep 2025 20:33:22 +0200 Subject: [PATCH 13/30] it's internal stuff --- .changeset/lazy-windows-repeat.md | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 .changeset/lazy-windows-repeat.md diff --git a/.changeset/lazy-windows-repeat.md b/.changeset/lazy-windows-repeat.md deleted file mode 100644 index 55c60c9a7..000000000 --- a/.changeset/lazy-windows-repeat.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'sv': patch ---- - -chore(cli): speedup internal tests v2 From 32dceed0f834afb22a5d2ea42721278323edfb6e Mon Sep 17 00:00:00 2001 From: jycouet Date: Mon, 29 Sep 2025 20:15:33 +0200 Subject: [PATCH 14/30] using same strategy for community-addon-template --- community-addon-template/src/index.js | 2 +- .../tests/custom-addon.test.ts | 11 +- .../tests/setup/global.ts | 2 +- community-addon-template/tests/setup/suite.ts | 141 ++++++++++++------ 4 files changed, 108 insertions(+), 48 deletions(-) diff --git a/community-addon-template/src/index.js b/community-addon-template/src/index.js index 61dc312ea..f284ab7df 100644 --- a/community-addon-template/src/index.js +++ b/community-addon-template/src/index.js @@ -13,7 +13,7 @@ export const options = defineAddonOptions() export default defineAddon({ id: 'community-addon', options, - setup: ({ kit, unsupported }) => { + setup: ({ kit, unsupported }) => { if (!kit) unsupported('Requires SvelteKit'); }, run: ({ sv, options, typescript }) => { diff --git a/community-addon-template/tests/custom-addon.test.ts b/community-addon-template/tests/custom-addon.test.ts index 6fa77191b..6f7800b2d 100644 --- a/community-addon-template/tests/custom-addon.test.ts +++ b/community-addon-template/tests/custom-addon.test.ts @@ -4,13 +4,16 @@ import { fixture, setupTest } from './setup/suite.js'; import addon from '../src/index.js'; const id = addon.id; -const { test, variants, prepareServer } = setupTest({ [id]: addon }); +const { test, flavors, prepareServer } = setupTest( + { [id]: addon }, + { kinds: [{ type: 'default', options: { [id]: { demo: true } } }] } +); -test.concurrent.for(variants)('demo - %s', async (variant, { page, ...ctx }) => { - const cwd = await ctx.run(variant, { [id]: { demo: true } }); +test.concurrent.for(flavors)('community-addon $variant', async (flavor, { page, ...ctx }) => { + const cwd = ctx.run(flavor); // ...add files - if (variant.startsWith('kit')) { + if (flavor.variant.startsWith('kit')) { const target = path.resolve(cwd, 'src', 'routes', '+page.svelte'); fixture({ name: '+page.svelte', target }); } else { diff --git a/community-addon-template/tests/setup/global.ts b/community-addon-template/tests/setup/global.ts index 31b2ed100..a9cbb495c 100644 --- a/community-addon-template/tests/setup/global.ts +++ b/community-addon-template/tests/setup/global.ts @@ -2,8 +2,8 @@ import { fileURLToPath } from 'node:url'; import { setup, type ProjectVariant } from 'sv/testing'; import type { TestProject } from 'vitest/node'; -const variants: ProjectVariant[] = ['kit-js', 'kit-ts', 'vite-js', 'vite-ts']; const TEST_DIR = fileURLToPath(new URL('../../.test-output/', import.meta.url)); +const variants: ProjectVariant[] = ['kit-js', 'kit-ts', 'vite-js', 'vite-ts']; export default async function ({ provide }: TestProject) { // global setup (e.g. spin up docker containers) diff --git a/community-addon-template/tests/setup/suite.ts b/community-addon-template/tests/setup/suite.ts index db7dd06d1..83006eae7 100644 --- a/community-addon-template/tests/setup/suite.ts +++ b/community-addon-template/tests/setup/suite.ts @@ -1,44 +1,73 @@ import fs from 'node:fs'; import path from 'node:path'; -import { execSync } from 'node:child_process'; +import { promisify } from 'node:util'; +import { exec, execSync } from 'node:child_process'; import * as vitest from 'vitest'; import { installAddon, type AddonMap, type OptionMap } from 'sv'; import { - addPnpmBuildDependencies, createProject, startPreview, + addPnpmBuildDependencies, type CreateProject, type ProjectVariant } from 'sv/testing'; -import { chromium, type Browser, type Page } from '@playwright/test'; +import { chromium, type Browser, type BrowserContext, type Page } from '@playwright/test'; import { fileURLToPath } from 'node:url'; const cwd = vitest.inject('testDir'); const templatesDir = vitest.inject('templatesDir'); const variants = vitest.inject('variants'); +export const execAsync = promisify(exec); + const SETUP_DIR = fileURLToPath(new URL('.', import.meta.url)); type Fixtures = { page: Page; - run(variant: ProjectVariant, options: OptionMap): Promise; + run(flavor: Flavor): string; }; -export function setupTest(addons: Addons) { - let create: CreateProject; - let browser: Browser; +type Flavor = { + variant: ProjectVariant; + kind: { type: string; options: OptionMap }; +}; +export function setupTest( + addons: Addons, + options?: { + kinds: Array['kind']>; + filter?: (flavor: Flavor) => boolean; + browser?: boolean; + } +) { const test = vitest.test.extend>({} as any); - vitest.beforeAll(async () => { - browser = await chromium.launch(); - return async () => { - await browser.close(); - }; - }); + const withBrowser = options?.browser ?? true; - vitest.beforeAll(({ name }) => { - const testName = path.parse(name).name.replace('.test', ''); + let create: CreateProject; + let browser: Browser; + + if (withBrowser) { + vitest.beforeAll(async () => { + browser = await chromium.launch(); + return async () => { + await browser.close(); + }; + }); + } + + const flavors: Array> = []; + for (const kind of options?.kinds ?? []) { + for (const variant of variants) { + const flavor = { variant, kind }; + if (!options?.filter || options?.filter?.(flavor)) { + flavors.push(flavor); + } + } + } + let testName: string; + vitest.beforeAll(async ({ name }) => { + testName = path.dirname(name).split('/').at(-1)!; // constructs a builder for create test projects create = createProject({ cwd, templatesDir, testName }); @@ -58,61 +87,89 @@ export function setupTest(addons: Addons) { private: true }) ); - }); - // runs before each test case - vitest.beforeEach>(async (ctx) => { - const browserCtx = await browser.newContext(); - ctx.page = await browserCtx.newPage(); - ctx.run = async (variant, options) => { - const cwd = create({ testId: ctx.task.id, variant }); + for (const { variant, kind } of flavors) { + const cwd = create({ testId: `${kind.type}-${variant}`, variant }); // test metadata const metaPath = path.resolve(cwd, 'meta.json'); - fs.writeFileSync(metaPath, JSON.stringify({ variant, options }, null, '\t'), 'utf8'); + fs.writeFileSync(metaPath, JSON.stringify({ variant, kind }, null, '\t'), 'utf8'); - // run addon const { pnpmBuildDependencies } = await installAddon({ cwd, addons, - options, + options: kind.options, packageManager: 'pnpm' }); await addPnpmBuildDependencies(cwd, 'pnpm', ['esbuild', ...pnpmBuildDependencies]); + } - return cwd; + execSync('pnpm install', { cwd: path.resolve(cwd, testName), stdio: 'pipe' }); + }); + + // runs before each test case + vitest.beforeEach>(async (ctx) => { + let browserCtx: BrowserContext; + if (withBrowser) { + browserCtx = await browser.newContext(); + ctx.page = await browserCtx.newPage(); + } + + ctx.run = (flavor) => { + return path.join(cwd, testName, `${flavor.kind.type}-${flavor.variant}`); }; return async () => { - await browserCtx.close(); + if (withBrowser) { + await browserCtx.close(); + } // ...other tear downs }; }); - return { - test, - variants, - prepareServer - }; + return { test, flavors, prepareServer }; } -/** - * Installs dependencies, builds the project, and spins up the preview server - */ -async function prepareServer({ cwd, page }: { cwd: string; page: Page }) { +type PrepareServerOptions = { + cwd: string; + page: Page; + installCommand?: string; + beforeBuild?: () => Promise | any; + buildCommand?: string; + previewCommand?: string; +}; +// installs dependencies, builds the project, and spins up the preview server +async function prepareServer({ + cwd, + page, + installCommand, // should happen in the beforeAll hook + beforeBuild, + buildCommand = 'pnpm build', + previewCommand = 'pnpm preview' +}: PrepareServerOptions) { // install deps - execSync('pnpm install --no-frozen-lockfile', { cwd, stdio: 'pipe' }); + if (installCommand) execSync(installCommand, { cwd, stdio: 'pipe' }); // ...do commands and any other extra stuff + await beforeBuild?.(); // build project - execSync('npm run build', { cwd, stdio: 'pipe' }); + if (buildCommand) execSync(buildCommand, { cwd, stdio: 'pipe' }); + + // start preview server + const { url, close } = await startPreview({ cwd, command: previewCommand }); - // start preview server `vite preview` - const { url, close } = await startPreview({ cwd }); + // increases timeout as 30s is not always enough when running the full suite + page.setDefaultNavigationTimeout(60_000); - // navigate to the page - await page.goto(url); + try { + // navigate to the page + await page.goto(url); + } catch (e) { + // cleanup in the instance of a timeout + await close(); + throw e; + } return { url, close }; } From 1509341e699df9910539817fb6f70d8dbdbca4dc Mon Sep 17 00:00:00 2001 From: jycouet Date: Mon, 29 Sep 2025 20:48:54 +0200 Subject: [PATCH 15/30] linting power --- packages/cli/utils/package-manager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/utils/package-manager.ts b/packages/cli/utils/package-manager.ts index 4e7204c0f..d53ffd68e 100644 --- a/packages/cli/utils/package-manager.ts +++ b/packages/cli/utils/package-manager.ts @@ -91,7 +91,7 @@ export async function addPnpmBuildDependencies( cwd: string, packageManager: AgentName | null | undefined, allowedPackages: string[] -): void { +): Promise { // other package managers are currently not affected by this change if (!packageManager || packageManager !== 'pnpm' || allowedPackages.length === 0) return; From a96c339a2ba2cf9d5240b7a3feafd4e015187799 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Thu, 2 Oct 2025 19:49:51 -0400 Subject: [PATCH 16/30] remove unused --- community-addon-template/src/index.js | 2 +- community-addon-template/tests/setup/suite.ts | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/community-addon-template/src/index.js b/community-addon-template/src/index.js index f284ab7df..61dc312ea 100644 --- a/community-addon-template/src/index.js +++ b/community-addon-template/src/index.js @@ -13,7 +13,7 @@ export const options = defineAddonOptions() export default defineAddon({ id: 'community-addon', options, - setup: ({ kit, unsupported }) => { + setup: ({ kit, unsupported }) => { if (!kit) unsupported('Requires SvelteKit'); }, run: ({ sv, options, typescript }) => { diff --git a/community-addon-template/tests/setup/suite.ts b/community-addon-template/tests/setup/suite.ts index 83006eae7..0eabd6530 100644 --- a/community-addon-template/tests/setup/suite.ts +++ b/community-addon-template/tests/setup/suite.ts @@ -1,7 +1,6 @@ import fs from 'node:fs'; import path from 'node:path'; -import { promisify } from 'node:util'; -import { exec, execSync } from 'node:child_process'; +import { execSync } from 'node:child_process'; import * as vitest from 'vitest'; import { installAddon, type AddonMap, type OptionMap } from 'sv'; import { @@ -18,8 +17,6 @@ const cwd = vitest.inject('testDir'); const templatesDir = vitest.inject('templatesDir'); const variants = vitest.inject('variants'); -export const execAsync = promisify(exec); - const SETUP_DIR = fileURLToPath(new URL('.', import.meta.url)); type Fixtures = { From 95b1826f01ff24508db938ae28c3ee49b2021496 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Thu, 2 Oct 2025 20:10:06 -0400 Subject: [PATCH 17/30] dedupe --- pnpm-lock.yaml | 289 +++++++++++++++++-------------------------------- 1 file changed, 102 insertions(+), 187 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 38000926f..9bc730637 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -37,7 +37,7 @@ importers: version: 3.9.2(eslint@9.29.0(jiti@2.6.0))(svelte@5.34.7) magic-string: specifier: ^0.30.17 - version: 0.30.17 + version: 0.30.19 prettier: specifier: ^3.5.3 version: 3.5.3 @@ -174,7 +174,7 @@ importers: version: 9.1.0 magic-string: specifier: ^0.30.17 - version: 0.30.17 + version: 0.30.19 picocolors: specifier: ^1.1.1 version: 1.1.1 @@ -219,7 +219,7 @@ importers: version: 4.1.0 magic-string: specifier: ^0.30.17 - version: 0.30.17 + version: 0.30.19 package-manager-detector: specifier: ^0.2.11 version: 0.2.11 @@ -584,27 +584,13 @@ packages: '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} - '@jridgewell/gen-mapping@0.3.8': - resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} - engines: {node: '>=6.0.0'} - '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} - '@jridgewell/set-array@1.2.1': - resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} - engines: {node: '>=6.0.0'} - - '@jridgewell/sourcemap-codec@1.5.0': - resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} - '@jridgewell/sourcemap-codec@1.5.5': resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - '@jridgewell/trace-mapping@0.3.25': - resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} - '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} @@ -629,8 +615,8 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@oxc-project/types@0.92.0': - resolution: {integrity: sha512-PDLfCbwgXjGdTBxzcuDOUxJYNBl6P8dOp3eDKWw54dYvqONan9rwGDRQU0zrkdEMiItfXQQUOI17uOcMX5Zm7A==} + '@oxc-project/types@0.93.0': + resolution: {integrity: sha512-yNtwmWZIBtJsMr5TEfoZFDxIWV6OdScOpza/f5YxbqUMJk+j6QX3Cf3jgZShGEFYWQJ5j9mJ6jM0tZHu2J9Yrg==} '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} @@ -651,91 +637,91 @@ packages: '@quansync/fs@0.1.5': resolution: {integrity: sha512-lNS9hL2aS2NZgNW7BBj+6EBl4rOf8l+tQ0eRY6JWCI8jI2kc53gSoqbjojU0OnAWhzoXiOjFyGsHcDGePB3lhA==} - '@rolldown/binding-android-arm64@1.0.0-beta.40': - resolution: {integrity: sha512-9Ii9phC7QU6Lb+ncMfG1Xlosq0NBB1N/4sw+EGZ3y0BBWGy02TOb5ghWZalphAKv9rn1goqo5WkBjyd2YvsLmA==} + '@rolldown/binding-android-arm64@1.0.0-beta.41': + resolution: {integrity: sha512-Edflndd9lU7JVhVIvJlZhdCj5DkhYDJPIRn4Dx0RUdfc8asP9xHOI5gMd8MesDDx+BJpdIT/uAmVTearteU/mQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@rolldown/binding-darwin-arm64@1.0.0-beta.40': - resolution: {integrity: sha512-5O6d0y2tBQTL+ecQY3qXIwSnF1/Zik8q7LZMKeyF+VJ9l194d0IdMhl2zUF0cqWbYHuF4Pnxplk4OhurPQ/Z9Q==} + '@rolldown/binding-darwin-arm64@1.0.0-beta.41': + resolution: {integrity: sha512-XGCzqfjdk7550PlyZRTBKbypXrB7ATtXhw/+bjtxnklLQs0mKP/XkQVOKyn9qGKSlvH8I56JLYryVxl0PCvSNw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-x64@1.0.0-beta.40': - resolution: {integrity: sha512-izB9jygt3miPQbOTZfSu5K51isUplqa8ysByOKQqcJHgrBWmbTU8TM9eouv6tRmBR0kjcEcID9xhmA1CeZ1VIg==} + '@rolldown/binding-darwin-x64@1.0.0-beta.41': + resolution: {integrity: sha512-Ho6lIwGJed98zub7n0xcRKuEtnZgbxevAmO4x3zn3C3N4GVXZD5xvCvTVxSMoeBJwTcIYzkVDRTIhylQNsTgLQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@rolldown/binding-freebsd-x64@1.0.0-beta.40': - resolution: {integrity: sha512-2fdpEpKT+wwP0vig9dqxu+toTeWmVSjo3psJQVDeLJ51rO+GXcCJ1IkCXjhMKVEevNtZS7B8T8Z2vvmRV9MAdA==} + '@rolldown/binding-freebsd-x64@1.0.0-beta.41': + resolution: {integrity: sha512-ijAZETywvL+gACjbT4zBnCp5ez1JhTRs6OxRN4J+D6AzDRbU2zb01Esl51RP5/8ZOlvB37xxsRQ3X4YRVyYb3g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.40': - resolution: {integrity: sha512-HP2lo78OWULN+8TewpLbS9PS00jh0CaF04tA2u8z2I+6QgVgrYOYKvX+T0hlO5smgso4+qb3YchzumWJl3yCPQ==} + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.41': + resolution: {integrity: sha512-EgIOZt7UildXKFEFvaiLNBXm+4ggQyGe3E5Z1QP9uRcJJs9omihOnm897FwOBQdCuMvI49iBgjFrkhH+wMJ2MA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.40': - resolution: {integrity: sha512-ng00gfr9BhA2NPAOU5RWAlTiL+JcwAD+L+4yUD1sbBy6tgHdLiNBOvKtHISIF9RM9/eQeS0tAiWOYZGIH9JMew==} + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.41': + resolution: {integrity: sha512-F8bUwJq8v/JAU8HSwgF4dztoqJ+FjdyjuvX4//3+Fbe2we9UktFeZ27U4lRMXF1vxWtdV4ey6oCSqI7yUrSEeg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - '@rolldown/binding-linux-arm64-musl@1.0.0-beta.40': - resolution: {integrity: sha512-mF0R1l9kLcaag/9cLEiYYdNZ4v1uuX4jklSDZ1s6vJE4RB3LirUney0FavdVRwCJ5sDvfvsPgXgtBXWYr2M2tQ==} + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.41': + resolution: {integrity: sha512-MioXcCIX/wB1pBnBoJx8q4OGucUAfC1+/X1ilKFsjDK05VwbLZGRgOVD5OJJpUQPK86DhQciNBrfOKDiatxNmg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - '@rolldown/binding-linux-x64-gnu@1.0.0-beta.40': - resolution: {integrity: sha512-+wi08S7wT5iLPHRZb0USrS6n+T6m+yY++dePYedE5uvKIpWCJJioFTaRtWjpm0V6dVNLcq2OukrvfdlGtH9Wgg==} + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.41': + resolution: {integrity: sha512-m66M61fizvRCwt5pOEiZQMiwBL9/y0bwU/+Kc4Ce/Pef6YfoEkR28y+DzN9rMdjo8Z28NXjsDPq9nH4mXnAP0g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - '@rolldown/binding-linux-x64-musl@1.0.0-beta.40': - resolution: {integrity: sha512-W5qBGAemUocIBKCcOsDjlV9GUt28qhl/+M6etWBeLS5gQK0J6XDg0YVzfOQdvq57ZGjYNP0NvhYzqhOOnEx+4g==} + '@rolldown/binding-linux-x64-musl@1.0.0-beta.41': + resolution: {integrity: sha512-yRxlSfBvWnnfrdtJfvi9lg8xfG5mPuyoSHm0X01oiE8ArmLRvoJGHUTJydCYz+wbK2esbq5J4B4Tq9WAsOlP1Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - '@rolldown/binding-openharmony-arm64@1.0.0-beta.40': - resolution: {integrity: sha512-vJwoDehtt+yqj2zacq1AqNc2uE/oh7mnRGqAUbuldV6pgvU01OSQUJ7Zu+35hTopnjFoDNN6mIezkYlGAv5RFA==} + '@rolldown/binding-openharmony-arm64@1.0.0-beta.41': + resolution: {integrity: sha512-PHVxYhBpi8UViS3/hcvQQb9RFqCtvFmFU1PvUoTRiUdBtgHA6fONNHU4x796lgzNlVSD3DO/MZNk1s5/ozSMQg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@rolldown/binding-wasm32-wasi@1.0.0-beta.40': - resolution: {integrity: sha512-Oj3YyqVUPurr1FlMpEE/bJmMC+VWAWPM/SGUfklO5KUX97bk5Q/733nPg4RykK8q8/TluJoQYvRc05vL/B74dw==} + '@rolldown/binding-wasm32-wasi@1.0.0-beta.41': + resolution: {integrity: sha512-OAfcO37ME6GGWmj9qTaDT7jY4rM0T2z0/8ujdQIJQ2x2nl+ztO32EIwURfmXOK0U1tzkyuaKYvE34Pug/ucXlQ==} engines: {node: '>=14.0.0'} cpu: [wasm32] - '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.40': - resolution: {integrity: sha512-0ZtO6yN8XjVoFfN4HDWQj4nDu3ndMybr7jIM00DJqOmc+yFhly7rdOy7fNR9Sky3leCpBtsXfepVqRmVpYKPVA==} + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.41': + resolution: {integrity: sha512-NIYGuCcuXaq5BC4Q3upbiMBvmZsTsEPG9k/8QKQdmrch+ocSy5Jv9tdpdmXJyighKqm182nh/zBt+tSJkYoNlg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.40': - resolution: {integrity: sha512-BPl1inoJXPpIe38Ja46E4y11vXlJyuleo+9Rmu//pYL5fIDYJkXUj/oAXqjSuwLcssrcwnuPgzvzvlz9++cr3w==} + '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.41': + resolution: {integrity: sha512-kANdsDbE5FkEOb5NrCGBJBCaZ2Sabp3D7d4PRqMYJqyLljwh9mDyYyYSv5+QNvdAmifj+f3lviNEUUuUZPEFPw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.0.0-beta.40': - resolution: {integrity: sha512-UguA4ltbAk+nbwHRxqaUP/etpTbR0HjyNlsu4Zjbh/ytNbFsbw8CA4tEBkwDyjgI5NIPea6xY11zpl7R2/ddVA==} + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.41': + resolution: {integrity: sha512-UlpxKmFdik0Y2VjZrgUCgoYArZJiZllXgIipdBRV1hw6uK45UbQabSTW6Kp6enuOu7vouYWftwhuxfpE8J2JAg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] - '@rolldown/pluginutils@1.0.0-beta.40': - resolution: {integrity: sha512-s3GeJKSQOwBlzdUrj4ISjJj5SfSh+aqn0wjOar4Bx95iV1ETI7F6S/5hLcfAxZ9kXDcyrAkxPlqmd1ZITttf+w==} + '@rolldown/pluginutils@1.0.0-beta.41': + resolution: {integrity: sha512-ycMEPrS3StOIeb87BT3/+bu+blEtyvwQ4zmo2IcJQy0Rd1DAAhKksA0iUZ3MYSpJtjlPhg0Eo6mvVS6ggPhRbw==} '@rollup/rollup-android-arm-eabi@4.46.2': resolution: {integrity: sha512-Zj3Hl6sN34xJtMv7Anwb5Gu01yujyE/cLBDB2gnHTAHaWS1Z38L7kuSG+oAh0giZMqG060f/YBStXtMH6FvPMA==} @@ -1152,15 +1138,6 @@ packages: dataloader@1.4.0: resolution: {integrity: sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==} - debug@4.4.1: - resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - debug@4.4.3: resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} @@ -1407,14 +1384,6 @@ packages: fastq@1.19.1: resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} - fdir@6.4.6: - resolution: {integrity: sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==} - peerDependencies: - picomatch: ^3 || ^4 - peerDependenciesMeta: - picomatch: - optional: true - fdir@6.5.0: resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} engines: {node: '>=12.0.0'} @@ -1675,9 +1644,6 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - magic-string@0.30.17: - resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} - magic-string@0.30.19: resolution: {integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==} @@ -1823,10 +1789,6 @@ packages: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} - picomatch@4.0.2: - resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} - engines: {node: '>=12'} - picomatch@4.0.3: resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} @@ -1918,9 +1880,6 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - quansync@0.2.10: - resolution: {integrity: sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==} - quansync@0.2.11: resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} @@ -1969,8 +1928,8 @@ packages: vue-tsc: optional: true - rolldown@1.0.0-beta.40: - resolution: {integrity: sha512-VqEHbKpOgTPmQrZ4fVn4eshDQS/6g/fRpNE7cFSJY+eQLDZn4B9X61J6L+hnlt1u2uRI+pF7r1USs6S5fuWCvw==} + rolldown@1.0.0-beta.41: + resolution: {integrity: sha512-U+NPR0Bkg3wm61dteD2L4nAM1U9dtaqVrpDXwC36IKRHpEO/Ubpid4Nijpa2imPchcVNHfxVFwSSMJdwdGFUbg==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true @@ -2131,10 +2090,6 @@ packages: tinyexec@1.0.1: resolution: {integrity: sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==} - tinyglobby@0.2.14: - resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} - engines: {node: '>=12.0.0'} - tinyglobby@0.2.15: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} @@ -2362,8 +2317,8 @@ snapshots: '@ampproject/remapping@2.3.0': dependencies: - '@jridgewell/gen-mapping': 0.3.8 - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 '@babel/generator@7.28.3': dependencies: @@ -2652,7 +2607,7 @@ snapshots: '@eslint/config-array@0.20.1': dependencies: '@eslint/object-schema': 2.1.6 - debug: 4.4.1 + debug: 4.4.3 minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -2670,7 +2625,7 @@ snapshots: '@eslint/eslintrc@3.3.1': dependencies: ajv: 6.12.6 - debug: 4.4.1 + debug: 4.4.3 espree: 10.4.0 globals: 14.0.0 ignore: 5.3.2 @@ -2714,32 +2669,17 @@ snapshots: '@jridgewell/gen-mapping@0.3.13': dependencies: - '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/sourcemap-codec': 1.5.5 '@jridgewell/trace-mapping': 0.3.31 - '@jridgewell/gen-mapping@0.3.8': - dependencies: - '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.5.0 - '@jridgewell/trace-mapping': 0.3.25 - '@jridgewell/resolve-uri@3.1.2': {} - '@jridgewell/set-array@1.2.1': {} - - '@jridgewell/sourcemap-codec@1.5.0': {} - '@jridgewell/sourcemap-codec@1.5.5': {} - '@jridgewell/trace-mapping@0.3.25': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.0 - '@jridgewell/trace-mapping@0.3.31': dependencies: '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/sourcemap-codec': 1.5.5 '@manypkg/find-root@1.1.0': dependencies: @@ -2776,7 +2716,7 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.19.1 - '@oxc-project/types@0.92.0': {} + '@oxc-project/types@0.93.0': {} '@pkgjs/parseargs@0.11.0': optional: true @@ -2793,51 +2733,51 @@ snapshots: dependencies: quansync: 0.2.11 - '@rolldown/binding-android-arm64@1.0.0-beta.40': + '@rolldown/binding-android-arm64@1.0.0-beta.41': optional: true - '@rolldown/binding-darwin-arm64@1.0.0-beta.40': + '@rolldown/binding-darwin-arm64@1.0.0-beta.41': optional: true - '@rolldown/binding-darwin-x64@1.0.0-beta.40': + '@rolldown/binding-darwin-x64@1.0.0-beta.41': optional: true - '@rolldown/binding-freebsd-x64@1.0.0-beta.40': + '@rolldown/binding-freebsd-x64@1.0.0-beta.41': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.40': + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.41': optional: true - '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.40': + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.41': optional: true - '@rolldown/binding-linux-arm64-musl@1.0.0-beta.40': + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.41': optional: true - '@rolldown/binding-linux-x64-gnu@1.0.0-beta.40': + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.41': optional: true - '@rolldown/binding-linux-x64-musl@1.0.0-beta.40': + '@rolldown/binding-linux-x64-musl@1.0.0-beta.41': optional: true - '@rolldown/binding-openharmony-arm64@1.0.0-beta.40': + '@rolldown/binding-openharmony-arm64@1.0.0-beta.41': optional: true - '@rolldown/binding-wasm32-wasi@1.0.0-beta.40': + '@rolldown/binding-wasm32-wasi@1.0.0-beta.41': dependencies: '@napi-rs/wasm-runtime': 1.0.5 optional: true - '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.40': + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.41': optional: true - '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.40': + '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.41': optional: true - '@rolldown/binding-win32-x64-msvc@1.0.0-beta.40': + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.41': optional: true - '@rolldown/pluginutils@1.0.0-beta.40': {} + '@rolldown/pluginutils@1.0.0-beta.41': {} '@rollup/rollup-android-arm-eabi@4.46.2': optional: true @@ -2931,7 +2871,7 @@ snapshots: dependencies: minimatch: 9.0.5 path-browserify: 1.0.1 - tinyglobby: 0.2.14 + tinyglobby: 0.2.15 '@tybys/wasm-util@0.10.1': dependencies: @@ -2964,7 +2904,7 @@ snapshots: '@types/prompts@2.4.9': dependencies: - '@types/node': 18.19.112 + '@types/node': 22.15.32 kleur: 3.0.3 '@types/ps-tree@1.1.6': {} @@ -2994,7 +2934,7 @@ snapshots: '@typescript-eslint/types': 8.34.1 '@typescript-eslint/typescript-estree': 8.34.1(typescript@5.8.3) '@typescript-eslint/visitor-keys': 8.34.1 - debug: 4.4.1 + debug: 4.4.3 eslint: 9.29.0(jiti@2.6.0) typescript: 5.8.3 transitivePeerDependencies: @@ -3004,7 +2944,7 @@ snapshots: dependencies: '@typescript-eslint/tsconfig-utils': 8.34.1(typescript@5.8.3) '@typescript-eslint/types': 8.34.1 - debug: 4.4.1 + debug: 4.4.3 typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -3022,7 +2962,7 @@ snapshots: dependencies: '@typescript-eslint/typescript-estree': 8.34.1(typescript@5.8.3) '@typescript-eslint/utils': 8.34.1(eslint@9.29.0(jiti@2.6.0))(typescript@5.8.3) - debug: 4.4.1 + debug: 4.4.3 eslint: 9.29.0(jiti@2.6.0) ts-api-utils: 2.1.0(typescript@5.8.3) typescript: 5.8.3 @@ -3037,7 +2977,7 @@ snapshots: '@typescript-eslint/tsconfig-utils': 8.34.1(typescript@5.8.3) '@typescript-eslint/types': 8.34.1 '@typescript-eslint/visitor-keys': 8.34.1 - debug: 4.4.1 + debug: 4.4.3 fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 @@ -3075,7 +3015,7 @@ snapshots: dependencies: '@vitest/spy': 4.0.0-beta.6 estree-walker: 3.0.3 - magic-string: 0.30.17 + magic-string: 0.30.19 optionalDependencies: vite: 7.0.6(@types/node@22.15.32)(jiti@2.6.0)(yaml@2.8.1) @@ -3092,7 +3032,7 @@ snapshots: '@vitest/snapshot@4.0.0-beta.6': dependencies: '@vitest/pretty-format': 4.0.0-beta.6 - magic-string: 0.30.17 + magic-string: 0.30.19 pathe: 2.0.3 '@vitest/spy@4.0.0-beta.6': {} @@ -3104,7 +3044,7 @@ snapshots: flatted: 3.3.3 pathe: 2.0.3 sirv: 3.0.1 - tinyglobby: 0.2.14 + tinyglobby: 0.2.15 tinyrainbow: 2.0.0 vitest: 4.0.0-beta.6(@types/node@22.15.32)(@vitest/ui@4.0.0-beta.6)(jiti@2.6.0)(yaml@2.8.1) @@ -3236,10 +3176,6 @@ snapshots: dataloader@1.4.0: {} - debug@4.4.1: - dependencies: - ms: 2.1.3 - debug@4.4.3: dependencies: ms: 2.1.3 @@ -3378,7 +3314,7 @@ snapshots: eslint-plugin-svelte@3.9.2(eslint@9.29.0(jiti@2.6.0))(svelte@5.34.7): dependencies: '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@2.6.0)) - '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/sourcemap-codec': 1.5.5 eslint: 9.29.0(jiti@2.6.0) esutils: 2.0.3 globals: 16.2.0 @@ -3420,7 +3356,7 @@ snapshots: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.1 + debug: 4.4.3 escape-string-regexp: 4.0.0 eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 @@ -3460,7 +3396,7 @@ snapshots: esrap@1.4.9: dependencies: - '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/sourcemap-codec': 1.5.5 esrecurse@4.3.0: dependencies: @@ -3512,14 +3448,6 @@ snapshots: dependencies: reusify: 1.1.0 - fdir@6.4.6(picomatch@4.0.2): - optionalDependencies: - picomatch: 4.0.2 - - fdir@6.4.6(picomatch@4.0.3): - optionalDependencies: - picomatch: 4.0.3 - fdir@6.5.0(picomatch@4.0.3): optionalDependencies: picomatch: 4.0.3 @@ -3744,10 +3672,6 @@ snapshots: lru-cache@10.4.3: {} - magic-string@0.30.17: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.0 - magic-string@0.30.19: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -3834,7 +3758,7 @@ snapshots: package-manager-detector@0.2.11: dependencies: - quansync: 0.2.10 + quansync: 0.2.11 parent-module@1.0.1: dependencies: @@ -3865,8 +3789,6 @@ snapshots: picomatch@2.3.1: {} - picomatch@4.0.2: {} - picomatch@4.0.3: {} pify@4.0.1: {} @@ -3931,8 +3853,6 @@ snapshots: punycode@2.3.1: {} - quansync@0.2.10: {} - quansync@0.2.11: {} queue-microtask@1.2.3: {} @@ -3954,7 +3874,7 @@ snapshots: reusify@1.1.0: {} - rolldown-plugin-dts@0.16.9(rolldown@1.0.0-beta.40)(typescript@5.8.3): + rolldown-plugin-dts@0.16.9(rolldown@1.0.0-beta.41)(typescript@5.8.3): dependencies: '@babel/generator': 7.28.3 '@babel/parser': 7.28.4 @@ -3965,33 +3885,33 @@ snapshots: dts-resolver: 2.1.2 get-tsconfig: 4.10.1 magic-string: 0.30.19 - rolldown: 1.0.0-beta.40 + rolldown: 1.0.0-beta.41 optionalDependencies: typescript: 5.8.3 transitivePeerDependencies: - oxc-resolver - supports-color - rolldown@1.0.0-beta.40: + rolldown@1.0.0-beta.41: dependencies: - '@oxc-project/types': 0.92.0 - '@rolldown/pluginutils': 1.0.0-beta.40 + '@oxc-project/types': 0.93.0 + '@rolldown/pluginutils': 1.0.0-beta.41 ansis: 4.2.0 optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.0-beta.40 - '@rolldown/binding-darwin-arm64': 1.0.0-beta.40 - '@rolldown/binding-darwin-x64': 1.0.0-beta.40 - '@rolldown/binding-freebsd-x64': 1.0.0-beta.40 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.40 - '@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.40 - '@rolldown/binding-linux-arm64-musl': 1.0.0-beta.40 - '@rolldown/binding-linux-x64-gnu': 1.0.0-beta.40 - '@rolldown/binding-linux-x64-musl': 1.0.0-beta.40 - '@rolldown/binding-openharmony-arm64': 1.0.0-beta.40 - '@rolldown/binding-wasm32-wasi': 1.0.0-beta.40 - '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.40 - '@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.40 - '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.40 + '@rolldown/binding-android-arm64': 1.0.0-beta.41 + '@rolldown/binding-darwin-arm64': 1.0.0-beta.41 + '@rolldown/binding-darwin-x64': 1.0.0-beta.41 + '@rolldown/binding-freebsd-x64': 1.0.0-beta.41 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.41 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.41 + '@rolldown/binding-linux-arm64-musl': 1.0.0-beta.41 + '@rolldown/binding-linux-x64-gnu': 1.0.0-beta.41 + '@rolldown/binding-linux-x64-musl': 1.0.0-beta.41 + '@rolldown/binding-openharmony-arm64': 1.0.0-beta.41 + '@rolldown/binding-wasm32-wasi': 1.0.0-beta.41 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.41 + '@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.41 + '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.41 rollup@4.46.2: dependencies: @@ -4059,7 +3979,7 @@ snapshots: is-plain-obj: 4.1.0 semver: 7.7.2 sort-object-keys: 1.1.3 - tinyglobby: 0.2.14 + tinyglobby: 0.2.15 source-map-js@1.2.1: {} @@ -4112,7 +4032,7 @@ snapshots: sucrase@3.35.0: dependencies: - '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/gen-mapping': 0.3.13 commander: 4.1.1 glob: 10.4.5 lines-and-columns: 1.2.4 @@ -4138,7 +4058,7 @@ snapshots: svelte@5.34.7: dependencies: '@ampproject/remapping': 2.3.0 - '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/sourcemap-codec': 1.5.5 '@sveltejs/acorn-typescript': 1.0.5(acorn@8.15.0) '@types/estree': 1.0.8 acorn: 8.15.0 @@ -4149,7 +4069,7 @@ snapshots: esrap: 1.4.9 is-reference: 3.0.3 locate-character: 3.0.0 - magic-string: 0.30.17 + magic-string: 0.30.19 zimmerframe: 1.1.2 synckit@0.11.8: @@ -4181,11 +4101,6 @@ snapshots: tinyexec@1.0.1: {} - tinyglobby@0.2.14: - dependencies: - fdir: 6.4.6(picomatch@4.0.2) - picomatch: 4.0.2 - tinyglobby@0.2.15: dependencies: fdir: 6.5.0(picomatch@4.0.3) @@ -4229,8 +4144,8 @@ snapshots: diff: 8.0.2 empathic: 2.0.0 hookable: 5.5.3 - rolldown: 1.0.0-beta.40 - rolldown-plugin-dts: 0.16.9(rolldown@1.0.0-beta.40)(typescript@5.8.3) + rolldown: 1.0.0-beta.41 + rolldown-plugin-dts: 0.16.9(rolldown@1.0.0-beta.41)(typescript@5.8.3) semver: 7.7.2 tinyexec: 1.0.1 tinyglobby: 0.2.15 @@ -4290,11 +4205,11 @@ snapshots: vite@7.0.6(@types/node@22.15.32)(jiti@2.6.0)(yaml@2.8.1): dependencies: esbuild: 0.25.8 - fdir: 6.4.6(picomatch@4.0.3) + fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 rollup: 4.46.2 - tinyglobby: 0.2.14 + tinyglobby: 0.2.15 optionalDependencies: '@types/node': 22.15.32 fsevents: 2.3.3 @@ -4312,16 +4227,16 @@ snapshots: '@vitest/spy': 4.0.0-beta.6 '@vitest/utils': 4.0.0-beta.6 chai: 5.2.1 - debug: 4.4.1 + debug: 4.4.3 es-module-lexer: 1.7.0 expect-type: 1.2.2 - magic-string: 0.30.17 + magic-string: 0.30.19 pathe: 2.0.3 picomatch: 4.0.3 std-env: 3.9.0 tinybench: 2.9.0 tinyexec: 0.3.2 - tinyglobby: 0.2.14 + tinyglobby: 0.2.15 tinypool: 1.1.1 tinyrainbow: 2.0.0 vite: 7.0.6(@types/node@22.15.32)(jiti@2.6.0)(yaml@2.8.1) From fe7f49c02e52e849b448e363ba6c7e70286e1c85 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Fri, 3 Oct 2025 01:24:49 -0400 Subject: [PATCH 18/30] tweak --- packages/cli/utils/package-manager.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/cli/utils/package-manager.ts b/packages/cli/utils/package-manager.ts index d53ffd68e..82fa83c8b 100644 --- a/packages/cli/utils/package-manager.ts +++ b/packages/cli/utils/package-manager.ts @@ -105,7 +105,7 @@ export async function addPnpmBuildDependencies( // find the workspace root (if present) const found = find.up('pnpm-workspace.yaml', { cwd }); - const dir = found ? path.dirname(found) : cwd; + const rootDir = found ? path.dirname(found) : cwd; if (confIn === 'pnpm-workspace.yaml') { const content = found ? fs.readFileSync(found, 'utf-8') : ''; @@ -119,7 +119,7 @@ export async function addPnpmBuildDependencies( if (items.some((y) => typeof y === 'object' && y.value === item)) continue; items.push(item); } - data.set('onlyBuiltDependencies', new Set(items)); + data.set('onlyBuiltDependencies', items); const newContent = generateCode(); @@ -127,7 +127,7 @@ export async function addPnpmBuildDependencies( if (newContent !== content) fs.writeFileSync(pnpmWorkspacePath, newContent); } else { // else is package.json (fallback) - const pkgPath = path.join(dir, 'package.json'); + const pkgPath = path.join(rootDir, 'package.json'); const content = fs.readFileSync(pkgPath, 'utf-8'); const { data, generateCode } = parseJson(content); From 64304e3ec7afcc9d5794c78817a5c4ee0e3e1199 Mon Sep 17 00:00:00 2001 From: "jyc.dev" Date: Fri, 3 Oct 2025 08:19:37 +0200 Subject: [PATCH 19/30] keep npm where it's needed Co-authored-by: CokaKoala <31664583+AdrianGonz97@users.noreply.github.com> --- packages/cli/lib/testing.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/lib/testing.ts b/packages/cli/lib/testing.ts index 6f95015b3..66e889c89 100644 --- a/packages/cli/lib/testing.ts +++ b/packages/cli/lib/testing.ts @@ -84,7 +84,7 @@ export function createProject({ cwd, testName, templatesDir }: CreateOptions): C type PreviewOptions = { cwd: string; command?: string }; export async function startPreview({ cwd, - command = 'pnpm preview' + command = 'npm run preview' }: PreviewOptions): Promise<{ url: string; close: () => Promise }> { const [cmd, ...args] = command.split(' '); const proc = exec(cmd, args, { From fefee20d2229e8315d0d307c2db5375debc201b6 Mon Sep 17 00:00:00 2001 From: jycouet Date: Fri, 3 Oct 2025 08:22:00 +0200 Subject: [PATCH 20/30] tinyexec: x to exec --- packages/cli/utils/package-manager.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/cli/utils/package-manager.ts b/packages/cli/utils/package-manager.ts index 82fa83c8b..4341a1023 100644 --- a/packages/cli/utils/package-manager.ts +++ b/packages/cli/utils/package-manager.ts @@ -2,7 +2,7 @@ import fs from 'node:fs'; import path from 'node:path'; import process from 'node:process'; import * as find from 'empathic/find'; -import { x } from 'tinyexec'; +import { exec } from 'tinyexec'; import { Option } from 'commander'; import * as p from '@clack/prompts'; import { @@ -59,7 +59,7 @@ export async function installDependencies(agent: AgentName, cwd: string): Promis try { const { command, args } = constructCommand(COMMANDS[agent].install, [])!; - const proc = x(command, args, { + const proc = exec(command, args, { nodeOptions: { cwd, stdio: 'pipe' }, throwOnError: true }); @@ -148,7 +148,7 @@ export async function addPnpmBuildDependencies( async function getPnpmVersion(): Promise { let v: string | undefined = undefined; try { - const proc = await x('pnpm', ['--version'], { throwOnError: true }); + const proc = await exec('pnpm', ['--version'], { throwOnError: true }); v = proc.stdout.trim(); } catch {} return v; From 0b83c1b59c417de28dd7e81e353a9eac00fc0891 Mon Sep 17 00:00:00 2001 From: jycouet Date: Fri, 3 Oct 2025 08:34:33 +0200 Subject: [PATCH 21/30] Flavor to AddonTestCase --- .../tests/custom-addon.test.ts | 39 +++++++------- community-addon-template/tests/setup/suite.ts | 20 +++---- packages/addons/_tests/_setup/suite.ts | 24 ++++----- packages/addons/_tests/all-addons/test.ts | 21 ++++---- packages/addons/_tests/devtools-json/test.ts | 8 +-- packages/addons/_tests/drizzle/test.ts | 53 ++++++++++--------- packages/addons/_tests/eslint/test.ts | 6 +-- packages/addons/_tests/lucia/test.ts | 10 ++-- packages/addons/_tests/mdsvex/test.ts | 8 +-- packages/addons/_tests/paraglide/test.ts | 27 +++++----- packages/addons/_tests/playwright/test.ts | 8 +-- packages/addons/_tests/prettier/test.ts | 6 +-- packages/addons/_tests/storybook/test.ts | 32 ++++++----- .../addons/_tests/sveltekit-adapter/test.ts | 39 +++++++------- packages/addons/_tests/tailwindcss/test.ts | 14 ++--- packages/addons/_tests/vitest/test.ts | 8 +-- 16 files changed, 171 insertions(+), 152 deletions(-) diff --git a/community-addon-template/tests/custom-addon.test.ts b/community-addon-template/tests/custom-addon.test.ts index 6f7800b2d..2b6f07f3b 100644 --- a/community-addon-template/tests/custom-addon.test.ts +++ b/community-addon-template/tests/custom-addon.test.ts @@ -4,28 +4,31 @@ import { fixture, setupTest } from './setup/suite.js'; import addon from '../src/index.js'; const id = addon.id; -const { test, flavors, prepareServer } = setupTest( +const { test, addonTestCases, prepareServer } = setupTest( { [id]: addon }, { kinds: [{ type: 'default', options: { [id]: { demo: true } } }] } ); -test.concurrent.for(flavors)('community-addon $variant', async (flavor, { page, ...ctx }) => { - const cwd = ctx.run(flavor); +test.concurrent.for(addonTestCases)( + 'community-addon $variant', + async (addonTestCase, { page, ...ctx }) => { + const cwd = ctx.run(addonTestCase); - // ...add files - if (flavor.variant.startsWith('kit')) { - const target = path.resolve(cwd, 'src', 'routes', '+page.svelte'); - fixture({ name: '+page.svelte', target }); - } else { - const target = path.resolve(cwd, 'src', 'App.svelte'); - fixture({ name: 'App.svelte', target }); - } + // ...add files + if (addonTestCase.variant.startsWith('kit')) { + const target = path.resolve(cwd, 'src', 'routes', '+page.svelte'); + fixture({ name: '+page.svelte', target }); + } else { + const target = path.resolve(cwd, 'src', 'App.svelte'); + fixture({ name: 'App.svelte', target }); + } - const { close } = await prepareServer({ cwd, page }); - // kill server process when we're done - ctx.onTestFinished(async () => await close()); + const { close } = await prepareServer({ cwd, page }); + // kill server process when we're done + ctx.onTestFinished(async () => await close()); - // expectations - const textContent = await page.getByTestId('demo').textContent(); - expect(textContent).toContain('This is a text file made by the Community Addon Template demo!'); -}); + // expectations + const textContent = await page.getByTestId('demo').textContent(); + expect(textContent).toContain('This is a text file made by the Community Addon Template demo!'); + } +); diff --git a/community-addon-template/tests/setup/suite.ts b/community-addon-template/tests/setup/suite.ts index 0eabd6530..66b382ac8 100644 --- a/community-addon-template/tests/setup/suite.ts +++ b/community-addon-template/tests/setup/suite.ts @@ -21,7 +21,7 @@ const SETUP_DIR = fileURLToPath(new URL('.', import.meta.url)); type Fixtures = { page: Page; - run(flavor: Flavor): string; + run(addonTestCase: Flavor): string; }; type Flavor = { @@ -33,7 +33,7 @@ export function setupTest( addons: Addons, options?: { kinds: Array['kind']>; - filter?: (flavor: Flavor) => boolean; + filter?: (addonTestCase: Flavor) => boolean; browser?: boolean; } ) { @@ -53,12 +53,12 @@ export function setupTest( }); } - const flavors: Array> = []; + const addonTestCases: Array> = []; for (const kind of options?.kinds ?? []) { for (const variant of variants) { - const flavor = { variant, kind }; - if (!options?.filter || options?.filter?.(flavor)) { - flavors.push(flavor); + const addonTestCase = { variant, kind }; + if (!options?.filter || options?.filter?.(addonTestCase)) { + addonTestCases.push(addonTestCase); } } } @@ -85,7 +85,7 @@ export function setupTest( }) ); - for (const { variant, kind } of flavors) { + for (const { variant, kind } of addonTestCases) { const cwd = create({ testId: `${kind.type}-${variant}`, variant }); // test metadata @@ -112,8 +112,8 @@ export function setupTest( ctx.page = await browserCtx.newPage(); } - ctx.run = (flavor) => { - return path.join(cwd, testName, `${flavor.kind.type}-${flavor.variant}`); + ctx.run = (addonTestCase) => { + return path.join(cwd, testName, `${addonTestCase.kind.type}-${addonTestCase.variant}`); }; return async () => { @@ -124,7 +124,7 @@ export function setupTest( }; }); - return { test, flavors, prepareServer }; + return { test, addonTestCases, prepareServer }; } type PrepareServerOptions = { diff --git a/packages/addons/_tests/_setup/suite.ts b/packages/addons/_tests/_setup/suite.ts index 9eb500b5b..a1d5f3e5b 100644 --- a/packages/addons/_tests/_setup/suite.ts +++ b/packages/addons/_tests/_setup/suite.ts @@ -21,10 +21,10 @@ export const execAsync = promisify(exec); type Fixtures = { page: Page; - run(flavor: Flavor): string; + run(addonTestCase: AddonTestCase): string; }; -type Flavor = { +type AddonTestCase = { variant: ProjectVariant; kind: { type: string; options: OptionMap }; }; @@ -32,8 +32,8 @@ type Flavor = { export function setupTest( addons: Addons, options?: { - kinds: Array['kind']>; - filter?: (flavor: Flavor) => boolean; + kinds: Array['kind']>; + filter?: (addonTestCase: AddonTestCase) => boolean; browser?: boolean; } ) { @@ -53,12 +53,12 @@ export function setupTest( }); } - const flavors: Array> = []; + const addonTestCases: Array> = []; for (const kind of options?.kinds ?? []) { for (const variant of variants) { - const flavor = { variant, kind }; - if (!options?.filter || options?.filter?.(flavor)) { - flavors.push(flavor); + const addonTestCase = { variant, kind }; + if (!options?.filter || options?.filter?.(addonTestCase)) { + addonTestCases.push(addonTestCase); } } } @@ -85,7 +85,7 @@ export function setupTest( }) ); - for (const { variant, kind } of flavors) { + for (const { variant, kind } of addonTestCases) { const cwd = create({ testId: `${kind.type}-${variant}`, variant }); // test metadata @@ -112,8 +112,8 @@ export function setupTest( ctx.page = await browserCtx.newPage(); } - ctx.run = (flavor) => { - return path.join(cwd, testName, `${flavor.kind.type}-${flavor.variant}`); + ctx.run = (addonTestCase) => { + return path.join(cwd, testName, `${addonTestCase.kind.type}-${addonTestCase.variant}`); }; return async () => { @@ -124,7 +124,7 @@ export function setupTest( }; }); - return { test, flavors, prepareServer }; + return { test, addonTestCases, prepareServer }; } type PrepareServerOptions = { diff --git a/packages/addons/_tests/all-addons/test.ts b/packages/addons/_tests/all-addons/test.ts index 3b40376c9..f547c9470 100644 --- a/packages/addons/_tests/all-addons/test.ts +++ b/packages/addons/_tests/all-addons/test.ts @@ -19,17 +19,20 @@ const defaultOptions = Object.values(officialAddons).reduce flavor.variant.startsWith('kit') + filter: (addonTestCase) => addonTestCase.variant.startsWith('kit') }); -test.concurrent.for(flavors)('run all addons - $variant', async (flavor, { page, ...ctx }) => { - const cwd = ctx.run(flavor); +test.concurrent.for(addonTestCases)( + 'run all addons - $variant', + async (addonTestCase, { page, ...ctx }) => { + const cwd = ctx.run(addonTestCase); - const { close } = await prepareServer({ cwd, page }); - // kill server process when we're done - ctx.onTestFinished(async () => await close()); + const { close } = await prepareServer({ cwd, page }); + // kill server process when we're done + ctx.onTestFinished(async () => await close()); - expect(true).toBe(true); -}); + expect(true).toBe(true); + } +); diff --git a/packages/addons/_tests/devtools-json/test.ts b/packages/addons/_tests/devtools-json/test.ts index 59dbb10b2..3c47d99a9 100644 --- a/packages/addons/_tests/devtools-json/test.ts +++ b/packages/addons/_tests/devtools-json/test.ts @@ -4,15 +4,15 @@ import devtoolsJson from '../../devtools-json/index.ts'; import fs from 'node:fs'; import path from 'node:path'; -const { test, flavors } = setupTest( +const { test, addonTestCases } = setupTest( { devtoolsJson }, { kinds: [{ type: 'default', options: { devtoolsJson: {} } }], browser: false } ); -test.concurrent.for(flavors)('devtools-json $variant', (flavor, ctx) => { - const cwd = ctx.run(flavor); +test.concurrent.for(addonTestCases)('devtools-json $variant', (addonTestCase, ctx) => { + const cwd = ctx.run(addonTestCase); - const ext = flavor.variant.includes('ts') ? 'ts' : 'js'; + const ext = addonTestCase.variant.includes('ts') ? 'ts' : 'js'; const viteFile = path.resolve(cwd, `vite.config.${ext}`); const viteContent = fs.readFileSync(viteFile, 'utf8'); diff --git a/packages/addons/_tests/drizzle/test.ts b/packages/addons/_tests/drizzle/test.ts index e643d665d..d5e7e0900 100644 --- a/packages/addons/_tests/drizzle/test.ts +++ b/packages/addons/_tests/drizzle/test.ts @@ -12,7 +12,7 @@ import { pageServer, pageComp } from './fixtures.ts'; // only linux is supported for running docker containers in github runners const noDocker = process.env.CI && process.platform !== 'linux'; -const { test, flavors, prepareServer } = setupTest( +const { test, addonTestCases, prepareServer } = setupTest( { drizzle }, { kinds: [ @@ -33,7 +33,7 @@ const { test, flavors, prepareServer } = setupTest( options: { drizzle: { database: 'postgresql', postgresql: 'postgres.js', docker: true } } } ], - filter: (flavor) => flavor.variant.includes('kit') + filter: (addonTestCase) => addonTestCase.variant.includes('kit') } ); @@ -52,31 +52,34 @@ beforeAll(() => { }; }); -test.concurrent.for(flavors)('drizzle $kind.type $variant', async (flavor, { page, ...ctx }) => { - if (flavor.kind.options.drizzle.docker && noDocker) ctx.skip(); - const cwd = ctx.run(flavor); +test.concurrent.for(addonTestCases)( + 'drizzle $kind.type $variant', + async (addonTestCase, { page, ...ctx }) => { + if (addonTestCase.kind.options.drizzle.docker && noDocker) ctx.skip(); + const cwd = ctx.run(addonTestCase); - const ts = flavor.variant === 'kit-ts'; - const drizzleConfig = path.resolve(cwd, `drizzle.config.${ts ? 'ts' : 'js'}`); - const content = fs.readFileSync(drizzleConfig, 'utf8').replace(/strict: true[,\s]/, ''); - fs.writeFileSync(drizzleConfig, content, 'utf8'); + const ts = addonTestCase.variant === 'kit-ts'; + const drizzleConfig = path.resolve(cwd, `drizzle.config.${ts ? 'ts' : 'js'}`); + const content = fs.readFileSync(drizzleConfig, 'utf8').replace(/strict: true[,\s]/, ''); + fs.writeFileSync(drizzleConfig, content, 'utf8'); - const routes = path.resolve(cwd, 'src', 'routes'); - const pagePath = path.resolve(routes, '+page.svelte'); - fs.writeFileSync(pagePath, pageComp, 'utf8'); + const routes = path.resolve(cwd, 'src', 'routes'); + const pagePath = path.resolve(routes, '+page.svelte'); + fs.writeFileSync(pagePath, pageComp, 'utf8'); - const pageServerPath = path.resolve(routes, `+page.server.${ts ? 'ts' : 'js'}`); - fs.writeFileSync(pageServerPath, pageServer, 'utf8'); + const pageServerPath = path.resolve(routes, `+page.server.${ts ? 'ts' : 'js'}`); + fs.writeFileSync(pageServerPath, pageServer, 'utf8'); - const { close } = await prepareServer({ - cwd, - page, - beforeBuild: () => { - execSync('npm run db:push', { cwd, stdio: 'pipe' }); - } - }); - // kill server process when we're done - ctx.onTestFinished(async () => await close()); + const { close } = await prepareServer({ + cwd, + page, + beforeBuild: () => { + execSync('npm run db:push', { cwd, stdio: 'pipe' }); + } + }); + // kill server process when we're done + ctx.onTestFinished(async () => await close()); - expect(page.locator('[data-testid]')).toBeTruthy(); -}); + expect(page.locator('[data-testid]')).toBeTruthy(); + } +); diff --git a/packages/addons/_tests/eslint/test.ts b/packages/addons/_tests/eslint/test.ts index 3567d93de..5d6f8d30f 100644 --- a/packages/addons/_tests/eslint/test.ts +++ b/packages/addons/_tests/eslint/test.ts @@ -4,13 +4,13 @@ import { execSync } from 'node:child_process'; import { setupTest } from '../_setup/suite.ts'; import eslint from '../../eslint/index.ts'; -const { test, flavors } = setupTest( +const { test, addonTestCases } = setupTest( { eslint }, { kinds: [{ type: 'default', options: { eslint: {} } }], browser: false } ); -test.concurrent.for(flavors)('eslint $variant', (flavor, { expect, ...ctx }) => { - const cwd = ctx.run(flavor); +test.concurrent.for(addonTestCases)('eslint $variant', (addonTestCase, { expect, ...ctx }) => { + const cwd = ctx.run(addonTestCase); const unlintedFile = 'let foo = "";\nif (Boolean(foo)) {\n//\n}'; fs.writeFileSync(path.resolve(cwd, 'src/lib/foo.js'), unlintedFile, 'utf8'); diff --git a/packages/addons/_tests/lucia/test.ts b/packages/addons/_tests/lucia/test.ts index a1147df76..b3668faaa 100644 --- a/packages/addons/_tests/lucia/test.ts +++ b/packages/addons/_tests/lucia/test.ts @@ -5,7 +5,7 @@ import drizzle from '../../drizzle/index.ts'; import path from 'node:path'; import fs from 'node:fs'; -const { test, flavors, prepareServer } = setupTest( +const { test, addonTestCases, prepareServer } = setupTest( { drizzle, lucia }, { kinds: [ @@ -14,18 +14,18 @@ const { test, flavors, prepareServer } = setupTest( options: { drizzle: { database: 'sqlite', sqlite: 'libsql' }, lucia: { demo: true } } } ], - filter: (flavor) => flavor.variant.includes('kit') + filter: (addonTestCase) => addonTestCase.variant.includes('kit') } ); -test.concurrent.for(flavors)('lucia $variant', async (flavor, { page, ...ctx }) => { - const cwd = ctx.run(flavor); +test.concurrent.for(addonTestCases)('lucia $variant', async (addonTestCase, { page, ...ctx }) => { + const cwd = ctx.run(addonTestCase); const { close } = await prepareServer({ cwd, page }); // kill server process when we're done ctx.onTestFinished(async () => await close()); - const ext = flavor.variant.includes('ts') ? 'ts' : 'js'; + const ext = addonTestCase.variant.includes('ts') ? 'ts' : 'js'; const filePath = path.resolve(cwd, `src/routes/demo/lucia/+page.server.${ext}`); const fileContent = fs.readFileSync(filePath, 'utf8'); expect(fileContent).toContain(`export const actions`); diff --git a/packages/addons/_tests/mdsvex/test.ts b/packages/addons/_tests/mdsvex/test.ts index e6a5c9ece..42e344baa 100644 --- a/packages/addons/_tests/mdsvex/test.ts +++ b/packages/addons/_tests/mdsvex/test.ts @@ -8,16 +8,16 @@ import { setupTest } from '../_setup/suite.ts'; import { svxFile } from './fixtures.ts'; import mdsvex from '../../mdsvex/index.ts'; -const { test, flavors, prepareServer } = setupTest( +const { test, addonTestCases, prepareServer } = setupTest( { mdsvex }, { kinds: [{ type: 'default', options: { mdsvex: {} } }] } ); -test.concurrent.for(flavors)('mdsvex $variant', async (flavor, { page, ...ctx }) => { - const cwd = ctx.run(flavor); +test.concurrent.for(addonTestCases)('mdsvex $variant', async (addonTestCase, { page, ...ctx }) => { + const cwd = ctx.run(addonTestCase); // ...add test files - addFixture(cwd, flavor.variant); + addFixture(cwd, addonTestCase.variant); const { close } = await prepareServer({ cwd, page }); // kill server process when we're done diff --git a/packages/addons/_tests/paraglide/test.ts b/packages/addons/_tests/paraglide/test.ts index 64746ebcb..59b6747fd 100644 --- a/packages/addons/_tests/paraglide/test.ts +++ b/packages/addons/_tests/paraglide/test.ts @@ -6,26 +6,29 @@ import path from 'node:path'; const langs = ['en', 'fr', 'hu']; -const { test, flavors, prepareServer } = setupTest( +const { test, addonTestCases, prepareServer } = setupTest( { paraglide }, { kinds: [ { type: 'default', options: { paraglide: { demo: true, languageTags: langs.join(',') } } } ], - filter: (flavor) => flavor.variant.includes('kit') + filter: (addonTestCase) => addonTestCase.variant.includes('kit') } ); -test.concurrent.for(flavors)('paraglide $variant', async (flavor, { page, ...ctx }) => { - const cwd = ctx.run(flavor); +test.concurrent.for(addonTestCases)( + 'paraglide $variant', + async (addonTestCase, { page, ...ctx }) => { + const cwd = ctx.run(addonTestCase); - const { close } = await prepareServer({ cwd, page }); - // kill server process when we're done - ctx.onTestFinished(async () => await close()); + const { close } = await prepareServer({ cwd, page }); + // kill server process when we're done + ctx.onTestFinished(async () => await close()); - for (const lang of langs) { - const filePath = path.resolve(cwd, `src/lib/paraglide/messages/${lang}.js`); - const fileContent = fs.readFileSync(filePath, 'utf8'); - expect(fileContent).toContain(`hello_world`); + for (const lang of langs) { + const filePath = path.resolve(cwd, `src/lib/paraglide/messages/${lang}.js`); + const fileContent = fs.readFileSync(filePath, 'utf8'); + expect(fileContent).toContain(`hello_world`); + } } -}); +); diff --git a/packages/addons/_tests/playwright/test.ts b/packages/addons/_tests/playwright/test.ts index cc0fe8155..532c89446 100644 --- a/packages/addons/_tests/playwright/test.ts +++ b/packages/addons/_tests/playwright/test.ts @@ -3,15 +3,15 @@ import path from 'node:path'; import { setupTest } from '../_setup/suite.ts'; import playwright from '../../playwright/index.ts'; -const { test, flavors } = setupTest( +const { test, addonTestCases } = setupTest( { playwright }, { kinds: [{ type: 'default', options: { playwright: {} } }], browser: false } ); -test.concurrent.for(flavors)('playwright $variant', (flavor, { expect, ...ctx }) => { - const cwd = ctx.run(flavor); +test.concurrent.for(addonTestCases)('playwright $variant', (addonTestCase, { expect, ...ctx }) => { + const cwd = ctx.run(addonTestCase); - const ext = flavor.variant.includes('ts') ? 'ts' : 'js'; + const ext = addonTestCase.variant.includes('ts') ? 'ts' : 'js'; const playwrightConfig = path.resolve(cwd, `playwright.config.${ext}`); const configContent = fs.readFileSync(playwrightConfig, 'utf8'); diff --git a/packages/addons/_tests/prettier/test.ts b/packages/addons/_tests/prettier/test.ts index ff2b74d8b..d32e2f522 100644 --- a/packages/addons/_tests/prettier/test.ts +++ b/packages/addons/_tests/prettier/test.ts @@ -4,13 +4,13 @@ import { execSync } from 'node:child_process'; import { setupTest } from '../_setup/suite.ts'; import prettier from '../../prettier/index.ts'; -const { test, flavors } = setupTest( +const { test, addonTestCases } = setupTest( { prettier }, { kinds: [{ type: 'default', options: { prettier: {} } }], browser: false } ); -test.concurrent.for(flavors)('prettier $variant', (flavor, { expect, ...ctx }) => { - const cwd = ctx.run(flavor); +test.concurrent.for(addonTestCases)('prettier $variant', (addonTestCase, { expect, ...ctx }) => { + const cwd = ctx.run(addonTestCase); const unformattedFile = 'const foo = "bar"'; fs.writeFileSync(path.resolve(cwd, 'src/lib/foo.js'), unformattedFile, 'utf8'); diff --git a/packages/addons/_tests/storybook/test.ts b/packages/addons/_tests/storybook/test.ts index 6dfa714c8..01ef63943 100644 --- a/packages/addons/_tests/storybook/test.ts +++ b/packages/addons/_tests/storybook/test.ts @@ -7,7 +7,7 @@ import storybook from '../../storybook/index.ts'; import eslint from '../../eslint/index.ts'; // we're including the `eslint` add-on to prevent `storybook` from modifying this repo's `eslint.config.js` -const { test, flavors, prepareServer } = setupTest( +const { test, addonTestCases, prepareServer } = setupTest( { storybook, eslint }, { kinds: [{ type: 'default', options: { storybook: {}, eslint: {} } }] } ); @@ -22,18 +22,22 @@ beforeAll(() => { } }); -test.for(flavors)('storybook $variant', { concurrent: !CI }, async (flavor, { page, ...ctx }) => { - const cwd = ctx.run(flavor); +test.for(addonTestCases)( + 'storybook $variant', + { concurrent: !CI }, + async (addonTestCase, { page, ...ctx }) => { + const cwd = ctx.run(addonTestCase); - const { close } = await prepareServer({ - cwd, - page, - previewCommand: `pnpm storybook -p ${++port} --ci`, - buildCommand: '' - }); - // kill server process when we're done - ctx.onTestFinished(async () => await close()); + const { close } = await prepareServer({ + cwd, + page, + previewCommand: `pnpm storybook -p ${++port} --ci`, + buildCommand: '' + }); + // kill server process when we're done + ctx.onTestFinished(async () => await close()); - expect(page.locator('main .sb-bar')).toBeTruthy(); - expect(page.locator('#storybook-preview-wrapper')).toBeTruthy(); -}); + expect(page.locator('main .sb-bar')).toBeTruthy(); + expect(page.locator('#storybook-preview-wrapper')).toBeTruthy(); + } +); diff --git a/packages/addons/_tests/sveltekit-adapter/test.ts b/packages/addons/_tests/sveltekit-adapter/test.ts index d8c18b914..24cbfb237 100644 --- a/packages/addons/_tests/sveltekit-adapter/test.ts +++ b/packages/addons/_tests/sveltekit-adapter/test.ts @@ -5,33 +5,36 @@ import sveltekitAdapter from '../../sveltekit-adapter/index.ts'; import { setupTest } from '../_setup/suite.ts'; const addonId = sveltekitAdapter.id; -const { test, flavors, prepareServer } = setupTest( +const { test, addonTestCases, prepareServer } = setupTest( { [addonId]: sveltekitAdapter }, { kinds: [ { type: 'node', options: { [addonId]: { adapter: 'node' } } }, { type: 'auto', options: { [addonId]: { adapter: 'auto' } } } ], - filter: (flavor) => flavor.variant.includes('kit') + filter: (addonTestCase) => addonTestCase.variant.includes('kit') } ); -test.concurrent.for(flavors)('adapter $kind.type $variant', async (flavor, { page, ...ctx }) => { - const cwd = ctx.run(flavor); +test.concurrent.for(addonTestCases)( + 'adapter $kind.type $variant', + async (addonTestCase, { page, ...ctx }) => { + const cwd = ctx.run(addonTestCase); - const { close } = await prepareServer({ cwd, page }); - // kill server process when we're done - ctx.onTestFinished(async () => await close()); + const { close } = await prepareServer({ cwd, page }); + // kill server process when we're done + ctx.onTestFinished(async () => await close()); - if (flavor.kind.type === 'node') { - expect(await readFile(join(cwd, 'svelte.config.js'), 'utf8')).not.toMatch('adapter-auto'); - expect(await readFile(join(cwd, 'svelte.config.js'), 'utf8')).not.toMatch( - 'adapter-auto only supports some environments' - ); - } else if (flavor.kind.type === 'auto') { - expect(await readFile(join(cwd, 'svelte.config.js'), 'utf8')).toMatch('adapter-auto'); - expect(await readFile(join(cwd, 'svelte.config.js'), 'utf8')).toMatch( - 'adapter-auto only supports some environments' - ); + if (addonTestCase.kind.type === 'node') { + expect(await readFile(join(cwd, 'svelte.config.js'), 'utf8')).not.toMatch('adapter-auto'); + expect(await readFile(join(cwd, 'svelte.config.js'), 'utf8')).not.toMatch( + 'adapter-auto only supports some environments' + ); + } else if (addonTestCase.kind.type === 'auto') { + expect(await readFile(join(cwd, 'svelte.config.js'), 'utf8')).toMatch('adapter-auto'); + expect(await readFile(join(cwd, 'svelte.config.js'), 'utf8')).toMatch( + 'adapter-auto only supports some environments' + ); + } } -}); +); diff --git a/packages/addons/_tests/tailwindcss/test.ts b/packages/addons/_tests/tailwindcss/test.ts index dacf45f58..35603467b 100644 --- a/packages/addons/_tests/tailwindcss/test.ts +++ b/packages/addons/_tests/tailwindcss/test.ts @@ -3,7 +3,7 @@ import { setupTest } from '../_setup/suite.ts'; import { addFixture } from './fixtures.ts'; import tailwindcss from '../../tailwindcss/index.ts'; -const { test, prepareServer, flavors } = setupTest( +const { test, prepareServer, addonTestCases } = setupTest( { tailwindcss }, { kinds: [ @@ -13,25 +13,25 @@ const { test, prepareServer, flavors } = setupTest( } ); -test.concurrent.for(flavors)( +test.concurrent.for(addonTestCases)( 'tailwindcss $kind.type $variant', - async (flavor, { page, ...ctx }) => { - const cwd = ctx.run(flavor); + async (addonTestCase, { page, ...ctx }) => { + const cwd = ctx.run(addonTestCase); // ...add test files - addFixture(cwd, flavor.variant); + addFixture(cwd, addonTestCase.variant); const { close } = await prepareServer({ cwd, page }); // kill server process when we're done ctx.onTestFinished(async () => await close()); - if (flavor.kind.type === 'none') { + if (addonTestCase.kind.type === 'none') { const el = page.getByTestId('base'); await expect(el).toHaveCSS('background-color', 'oklch(0.446 0.043 257.281)'); await expect(el).toHaveCSS('border-color', 'oklch(0.985 0.002 247.839)'); await expect(el).toHaveCSS('border-width', '4px'); await expect(el).toHaveCSS('margin-top', '4px'); - } else if (flavor.kind.type === 'typography') { + } else if (addonTestCase.kind.type === 'typography') { const el = page.getByTestId('typography'); await expect(el).toHaveCSS('font-size', '18px'); await expect(el).toHaveCSS('line-height', '28px'); diff --git a/packages/addons/_tests/vitest/test.ts b/packages/addons/_tests/vitest/test.ts index b8e47626c..0a9a772b5 100644 --- a/packages/addons/_tests/vitest/test.ts +++ b/packages/addons/_tests/vitest/test.ts @@ -4,13 +4,13 @@ import vitest from '../../vitest-addon/index.ts'; import path from 'node:path'; import fs from 'node:fs'; -const { test, flavors } = setupTest( +const { test, addonTestCases } = setupTest( { vitest }, { kinds: [{ type: 'default', options: { vitest: {} } }], browser: false } ); -test.concurrent.for(flavors)('vitest $variant', (flavor, { expect, ...ctx }) => { - const cwd = ctx.run(flavor); +test.concurrent.for(addonTestCases)('vitest $variant', (addonTestCase, { expect, ...ctx }) => { + const cwd = ctx.run(addonTestCase); expect(() => execSync('pnpm install', { cwd, stdio: 'pipe' })).not.toThrow(); @@ -18,7 +18,7 @@ test.concurrent.for(flavors)('vitest $variant', (flavor, { expect, ...ctx }) => expect(() => execSync('pnpm test', { cwd, stdio: 'pipe' })).not.toThrow(); - const ext = flavor.variant.includes('ts') ? 'ts' : 'js'; + const ext = addonTestCase.variant.includes('ts') ? 'ts' : 'js'; const viteFile = path.resolve(cwd, `vite.config.${ext}`); const viteContent = fs.readFileSync(viteFile, 'utf8'); From c74d103e60ae574ac3c94b95886e640828249bb5 Mon Sep 17 00:00:00 2001 From: "jyc.dev" Date: Fri, 3 Oct 2025 09:32:39 +0200 Subject: [PATCH 22/30] Update packages/addons/_tests/_setup/suite.ts Co-authored-by: Manuel <30698007+manuel3108@users.noreply.github.com> --- packages/addons/_tests/_setup/suite.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/addons/_tests/_setup/suite.ts b/packages/addons/_tests/_setup/suite.ts index a1d5f3e5b..238c3dc31 100644 --- a/packages/addons/_tests/_setup/suite.ts +++ b/packages/addons/_tests/_setup/suite.ts @@ -66,7 +66,7 @@ export function setupTest( vitest.beforeAll(async ({ name }) => { testName = path.dirname(name).split('/').at(-1)!; - // constructs a builder for create test projects + // constructs a builder to create test projects create = createProject({ cwd, templatesDir, testName }); // creates a pnpm workspace in each addon dir From d2bc07a90d1c06d7111cfb4752a374c621075cc5 Mon Sep 17 00:00:00 2001 From: jycouet Date: Fri, 3 Oct 2025 09:34:05 +0200 Subject: [PATCH 23/30] oupy yes full rename to AddonTestCase --- community-addon-template/tests/setup/suite.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/community-addon-template/tests/setup/suite.ts b/community-addon-template/tests/setup/suite.ts index 66b382ac8..90ba25ddc 100644 --- a/community-addon-template/tests/setup/suite.ts +++ b/community-addon-template/tests/setup/suite.ts @@ -21,10 +21,10 @@ const SETUP_DIR = fileURLToPath(new URL('.', import.meta.url)); type Fixtures = { page: Page; - run(addonTestCase: Flavor): string; + run(addonTestCase: AddonTestCase): string; }; -type Flavor = { +type AddonTestCase = { variant: ProjectVariant; kind: { type: string; options: OptionMap }; }; @@ -32,8 +32,8 @@ type Flavor = { export function setupTest( addons: Addons, options?: { - kinds: Array['kind']>; - filter?: (addonTestCase: Flavor) => boolean; + kinds: Array['kind']>; + filter?: (addonTestCase: AddonTestCase) => boolean; browser?: boolean; } ) { @@ -53,7 +53,7 @@ export function setupTest( }); } - const addonTestCases: Array> = []; + const addonTestCases: Array> = []; for (const kind of options?.kinds ?? []) { for (const variant of variants) { const addonTestCase = { variant, kind }; From c97827d30b905be35cf5181269baeda6a2080d6b Mon Sep 17 00:00:00 2001 From: jycouet Date: Fri, 3 Oct 2025 09:36:22 +0200 Subject: [PATCH 24/30] improve typing --- packages/core/tooling/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/tooling/index.ts b/packages/core/tooling/index.ts index b2fbe43f2..68f3dc0b4 100644 --- a/packages/core/tooling/index.ts +++ b/packages/core/tooling/index.ts @@ -244,6 +244,6 @@ export function parseYaml(content: string): ReturnType): string { return yaml.stringify(data, { singleQuote: true }); } From 2acf0b7e5d251b0f0f746f229cbe58a24bd96752 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sun, 5 Oct 2025 01:37:00 -0400 Subject: [PATCH 25/30] tweak name --- packages/addons/_tests/_setup/suite.ts | 10 ++++---- packages/addons/_tests/all-addons/test.ts | 19 ++++++-------- packages/addons/_tests/devtools-json/test.ts | 8 +++--- packages/addons/_tests/drizzle/test.ts | 14 +++++------ packages/addons/_tests/eslint/test.ts | 6 ++--- packages/addons/_tests/lucia/test.ts | 8 +++--- packages/addons/_tests/mdsvex/test.ts | 8 +++--- packages/addons/_tests/paraglide/test.ts | 25 ++++++++----------- packages/addons/_tests/playwright/test.ts | 8 +++--- packages/addons/_tests/prettier/test.ts | 6 ++--- packages/addons/_tests/storybook/test.ts | 8 +++--- .../addons/_tests/sveltekit-adapter/test.ts | 12 ++++----- packages/addons/_tests/tailwindcss/test.ts | 14 +++++------ packages/addons/_tests/vitest/test.ts | 8 +++--- 14 files changed, 74 insertions(+), 80 deletions(-) diff --git a/packages/addons/_tests/_setup/suite.ts b/packages/addons/_tests/_setup/suite.ts index 238c3dc31..25e52c84e 100644 --- a/packages/addons/_tests/_setup/suite.ts +++ b/packages/addons/_tests/_setup/suite.ts @@ -53,12 +53,12 @@ export function setupTest( }); } - const addonTestCases: Array> = []; + const testCases: Array> = []; for (const kind of options?.kinds ?? []) { for (const variant of variants) { const addonTestCase = { variant, kind }; - if (!options?.filter || options?.filter?.(addonTestCase)) { - addonTestCases.push(addonTestCase); + if (options?.filter === undefined || options.filter(addonTestCase)) { + testCases.push(addonTestCase); } } } @@ -85,7 +85,7 @@ export function setupTest( }) ); - for (const { variant, kind } of addonTestCases) { + for (const { variant, kind } of testCases) { const cwd = create({ testId: `${kind.type}-${variant}`, variant }); // test metadata @@ -124,7 +124,7 @@ export function setupTest( }; }); - return { test, addonTestCases, prepareServer }; + return { test, testCases, prepareServer }; } type PrepareServerOptions = { diff --git a/packages/addons/_tests/all-addons/test.ts b/packages/addons/_tests/all-addons/test.ts index f547c9470..e2cce8fca 100644 --- a/packages/addons/_tests/all-addons/test.ts +++ b/packages/addons/_tests/all-addons/test.ts @@ -19,20 +19,17 @@ const defaultOptions = Object.values(officialAddons).reduce addonTestCase.variant.startsWith('kit') }); -test.concurrent.for(addonTestCases)( - 'run all addons - $variant', - async (addonTestCase, { page, ...ctx }) => { - const cwd = ctx.run(addonTestCase); +test.concurrent.for(testCases)('run all addons - $variant', async (testCase, { page, ...ctx }) => { + const cwd = ctx.run(testCase); - const { close } = await prepareServer({ cwd, page }); - // kill server process when we're done - ctx.onTestFinished(async () => await close()); + const { close } = await prepareServer({ cwd, page }); + // kill server process when we're done + ctx.onTestFinished(async () => await close()); - expect(true).toBe(true); - } -); + expect(true).toBe(true); +}); diff --git a/packages/addons/_tests/devtools-json/test.ts b/packages/addons/_tests/devtools-json/test.ts index 3c47d99a9..7ac93b1c2 100644 --- a/packages/addons/_tests/devtools-json/test.ts +++ b/packages/addons/_tests/devtools-json/test.ts @@ -4,15 +4,15 @@ import devtoolsJson from '../../devtools-json/index.ts'; import fs from 'node:fs'; import path from 'node:path'; -const { test, addonTestCases } = setupTest( +const { test, testCases } = setupTest( { devtoolsJson }, { kinds: [{ type: 'default', options: { devtoolsJson: {} } }], browser: false } ); -test.concurrent.for(addonTestCases)('devtools-json $variant', (addonTestCase, ctx) => { - const cwd = ctx.run(addonTestCase); +test.concurrent.for(testCases)('devtools-json $variant', (testCase, ctx) => { + const cwd = ctx.run(testCase); - const ext = addonTestCase.variant.includes('ts') ? 'ts' : 'js'; + const ext = testCase.variant.includes('ts') ? 'ts' : 'js'; const viteFile = path.resolve(cwd, `vite.config.${ext}`); const viteContent = fs.readFileSync(viteFile, 'utf8'); diff --git a/packages/addons/_tests/drizzle/test.ts b/packages/addons/_tests/drizzle/test.ts index d5e7e0900..00809fa18 100644 --- a/packages/addons/_tests/drizzle/test.ts +++ b/packages/addons/_tests/drizzle/test.ts @@ -12,7 +12,7 @@ import { pageServer, pageComp } from './fixtures.ts'; // only linux is supported for running docker containers in github runners const noDocker = process.env.CI && process.platform !== 'linux'; -const { test, addonTestCases, prepareServer } = setupTest( +const { test, testCases, prepareServer } = setupTest( { drizzle }, { kinds: [ @@ -33,7 +33,7 @@ const { test, addonTestCases, prepareServer } = setupTest( options: { drizzle: { database: 'postgresql', postgresql: 'postgres.js', docker: true } } } ], - filter: (addonTestCase) => addonTestCase.variant.includes('kit') + filter: (testCase) => testCase.variant.includes('kit') } ); @@ -52,13 +52,13 @@ beforeAll(() => { }; }); -test.concurrent.for(addonTestCases)( +test.concurrent.for(testCases)( 'drizzle $kind.type $variant', - async (addonTestCase, { page, ...ctx }) => { - if (addonTestCase.kind.options.drizzle.docker && noDocker) ctx.skip(); - const cwd = ctx.run(addonTestCase); + async (testCase, { page, ...ctx }) => { + if (testCase.kind.options.drizzle.docker && noDocker) ctx.skip(); + const cwd = ctx.run(testCase); - const ts = addonTestCase.variant === 'kit-ts'; + const ts = testCase.variant === 'kit-ts'; const drizzleConfig = path.resolve(cwd, `drizzle.config.${ts ? 'ts' : 'js'}`); const content = fs.readFileSync(drizzleConfig, 'utf8').replace(/strict: true[,\s]/, ''); fs.writeFileSync(drizzleConfig, content, 'utf8'); diff --git a/packages/addons/_tests/eslint/test.ts b/packages/addons/_tests/eslint/test.ts index 5d6f8d30f..59e6c906d 100644 --- a/packages/addons/_tests/eslint/test.ts +++ b/packages/addons/_tests/eslint/test.ts @@ -4,13 +4,13 @@ import { execSync } from 'node:child_process'; import { setupTest } from '../_setup/suite.ts'; import eslint from '../../eslint/index.ts'; -const { test, addonTestCases } = setupTest( +const { test, testCases } = setupTest( { eslint }, { kinds: [{ type: 'default', options: { eslint: {} } }], browser: false } ); -test.concurrent.for(addonTestCases)('eslint $variant', (addonTestCase, { expect, ...ctx }) => { - const cwd = ctx.run(addonTestCase); +test.concurrent.for(testCases)('eslint $variant', (testCase, { expect, ...ctx }) => { + const cwd = ctx.run(testCase); const unlintedFile = 'let foo = "";\nif (Boolean(foo)) {\n//\n}'; fs.writeFileSync(path.resolve(cwd, 'src/lib/foo.js'), unlintedFile, 'utf8'); diff --git a/packages/addons/_tests/lucia/test.ts b/packages/addons/_tests/lucia/test.ts index b3668faaa..c38df9c80 100644 --- a/packages/addons/_tests/lucia/test.ts +++ b/packages/addons/_tests/lucia/test.ts @@ -5,7 +5,7 @@ import drizzle from '../../drizzle/index.ts'; import path from 'node:path'; import fs from 'node:fs'; -const { test, addonTestCases, prepareServer } = setupTest( +const { test, testCases, prepareServer } = setupTest( { drizzle, lucia }, { kinds: [ @@ -18,14 +18,14 @@ const { test, addonTestCases, prepareServer } = setupTest( } ); -test.concurrent.for(addonTestCases)('lucia $variant', async (addonTestCase, { page, ...ctx }) => { - const cwd = ctx.run(addonTestCase); +test.concurrent.for(testCases)('lucia $variant', async (testCase, { page, ...ctx }) => { + const cwd = ctx.run(testCase); const { close } = await prepareServer({ cwd, page }); // kill server process when we're done ctx.onTestFinished(async () => await close()); - const ext = addonTestCase.variant.includes('ts') ? 'ts' : 'js'; + const ext = testCase.variant.includes('ts') ? 'ts' : 'js'; const filePath = path.resolve(cwd, `src/routes/demo/lucia/+page.server.${ext}`); const fileContent = fs.readFileSync(filePath, 'utf8'); expect(fileContent).toContain(`export const actions`); diff --git a/packages/addons/_tests/mdsvex/test.ts b/packages/addons/_tests/mdsvex/test.ts index 42e344baa..6b903ee7b 100644 --- a/packages/addons/_tests/mdsvex/test.ts +++ b/packages/addons/_tests/mdsvex/test.ts @@ -8,16 +8,16 @@ import { setupTest } from '../_setup/suite.ts'; import { svxFile } from './fixtures.ts'; import mdsvex from '../../mdsvex/index.ts'; -const { test, addonTestCases, prepareServer } = setupTest( +const { test, testCases, prepareServer } = setupTest( { mdsvex }, { kinds: [{ type: 'default', options: { mdsvex: {} } }] } ); -test.concurrent.for(addonTestCases)('mdsvex $variant', async (addonTestCase, { page, ...ctx }) => { - const cwd = ctx.run(addonTestCase); +test.concurrent.for(testCases)('mdsvex $variant', async (testCase, { page, ...ctx }) => { + const cwd = ctx.run(testCase); // ...add test files - addFixture(cwd, addonTestCase.variant); + addFixture(cwd, testCase.variant); const { close } = await prepareServer({ cwd, page }); // kill server process when we're done diff --git a/packages/addons/_tests/paraglide/test.ts b/packages/addons/_tests/paraglide/test.ts index 59b6747fd..a05907ae4 100644 --- a/packages/addons/_tests/paraglide/test.ts +++ b/packages/addons/_tests/paraglide/test.ts @@ -6,7 +6,7 @@ import path from 'node:path'; const langs = ['en', 'fr', 'hu']; -const { test, addonTestCases, prepareServer } = setupTest( +const { test, testCases, prepareServer } = setupTest( { paraglide }, { kinds: [ @@ -16,19 +16,16 @@ const { test, addonTestCases, prepareServer } = setupTest( } ); -test.concurrent.for(addonTestCases)( - 'paraglide $variant', - async (addonTestCase, { page, ...ctx }) => { - const cwd = ctx.run(addonTestCase); +test.concurrent.for(testCases)('paraglide $variant', async (testCase, { page, ...ctx }) => { + const cwd = ctx.run(testCase); - const { close } = await prepareServer({ cwd, page }); - // kill server process when we're done - ctx.onTestFinished(async () => await close()); + const { close } = await prepareServer({ cwd, page }); + // kill server process when we're done + ctx.onTestFinished(async () => await close()); - for (const lang of langs) { - const filePath = path.resolve(cwd, `src/lib/paraglide/messages/${lang}.js`); - const fileContent = fs.readFileSync(filePath, 'utf8'); - expect(fileContent).toContain(`hello_world`); - } + for (const lang of langs) { + const filePath = path.resolve(cwd, `src/lib/paraglide/messages/${lang}.js`); + const fileContent = fs.readFileSync(filePath, 'utf8'); + expect(fileContent).toContain(`hello_world`); } -); +}); diff --git a/packages/addons/_tests/playwright/test.ts b/packages/addons/_tests/playwright/test.ts index 532c89446..7ebf6a5b4 100644 --- a/packages/addons/_tests/playwright/test.ts +++ b/packages/addons/_tests/playwright/test.ts @@ -3,15 +3,15 @@ import path from 'node:path'; import { setupTest } from '../_setup/suite.ts'; import playwright from '../../playwright/index.ts'; -const { test, addonTestCases } = setupTest( +const { test, testCases } = setupTest( { playwright }, { kinds: [{ type: 'default', options: { playwright: {} } }], browser: false } ); -test.concurrent.for(addonTestCases)('playwright $variant', (addonTestCase, { expect, ...ctx }) => { - const cwd = ctx.run(addonTestCase); +test.concurrent.for(testCases)('playwright $variant', (testCase, { expect, ...ctx }) => { + const cwd = ctx.run(testCase); - const ext = addonTestCase.variant.includes('ts') ? 'ts' : 'js'; + const ext = testCase.variant.includes('ts') ? 'ts' : 'js'; const playwrightConfig = path.resolve(cwd, `playwright.config.${ext}`); const configContent = fs.readFileSync(playwrightConfig, 'utf8'); diff --git a/packages/addons/_tests/prettier/test.ts b/packages/addons/_tests/prettier/test.ts index d32e2f522..7429cfa02 100644 --- a/packages/addons/_tests/prettier/test.ts +++ b/packages/addons/_tests/prettier/test.ts @@ -4,13 +4,13 @@ import { execSync } from 'node:child_process'; import { setupTest } from '../_setup/suite.ts'; import prettier from '../../prettier/index.ts'; -const { test, addonTestCases } = setupTest( +const { test, testCases } = setupTest( { prettier }, { kinds: [{ type: 'default', options: { prettier: {} } }], browser: false } ); -test.concurrent.for(addonTestCases)('prettier $variant', (addonTestCase, { expect, ...ctx }) => { - const cwd = ctx.run(addonTestCase); +test.concurrent.for(testCases)('prettier $variant', (testCase, { expect, ...ctx }) => { + const cwd = ctx.run(testCase); const unformattedFile = 'const foo = "bar"'; fs.writeFileSync(path.resolve(cwd, 'src/lib/foo.js'), unformattedFile, 'utf8'); diff --git a/packages/addons/_tests/storybook/test.ts b/packages/addons/_tests/storybook/test.ts index 01ef63943..6b6412ea8 100644 --- a/packages/addons/_tests/storybook/test.ts +++ b/packages/addons/_tests/storybook/test.ts @@ -7,7 +7,7 @@ import storybook from '../../storybook/index.ts'; import eslint from '../../eslint/index.ts'; // we're including the `eslint` add-on to prevent `storybook` from modifying this repo's `eslint.config.js` -const { test, addonTestCases, prepareServer } = setupTest( +const { test, testCases, prepareServer } = setupTest( { storybook, eslint }, { kinds: [{ type: 'default', options: { storybook: {}, eslint: {} } }] } ); @@ -22,11 +22,11 @@ beforeAll(() => { } }); -test.for(addonTestCases)( +test.for(testCases)( 'storybook $variant', { concurrent: !CI }, - async (addonTestCase, { page, ...ctx }) => { - const cwd = ctx.run(addonTestCase); + async (testCase, { page, ...ctx }) => { + const cwd = ctx.run(testCase); const { close } = await prepareServer({ cwd, diff --git a/packages/addons/_tests/sveltekit-adapter/test.ts b/packages/addons/_tests/sveltekit-adapter/test.ts index 24cbfb237..0f92e92f0 100644 --- a/packages/addons/_tests/sveltekit-adapter/test.ts +++ b/packages/addons/_tests/sveltekit-adapter/test.ts @@ -5,7 +5,7 @@ import sveltekitAdapter from '../../sveltekit-adapter/index.ts'; import { setupTest } from '../_setup/suite.ts'; const addonId = sveltekitAdapter.id; -const { test, addonTestCases, prepareServer } = setupTest( +const { test, testCases, prepareServer } = setupTest( { [addonId]: sveltekitAdapter }, { kinds: [ @@ -16,21 +16,21 @@ const { test, addonTestCases, prepareServer } = setupTest( } ); -test.concurrent.for(addonTestCases)( +test.concurrent.for(testCases)( 'adapter $kind.type $variant', - async (addonTestCase, { page, ...ctx }) => { - const cwd = ctx.run(addonTestCase); + async (testCase, { page, ...ctx }) => { + const cwd = ctx.run(testCase); const { close } = await prepareServer({ cwd, page }); // kill server process when we're done ctx.onTestFinished(async () => await close()); - if (addonTestCase.kind.type === 'node') { + if (testCase.kind.type === 'node') { expect(await readFile(join(cwd, 'svelte.config.js'), 'utf8')).not.toMatch('adapter-auto'); expect(await readFile(join(cwd, 'svelte.config.js'), 'utf8')).not.toMatch( 'adapter-auto only supports some environments' ); - } else if (addonTestCase.kind.type === 'auto') { + } else if (testCase.kind.type === 'auto') { expect(await readFile(join(cwd, 'svelte.config.js'), 'utf8')).toMatch('adapter-auto'); expect(await readFile(join(cwd, 'svelte.config.js'), 'utf8')).toMatch( 'adapter-auto only supports some environments' diff --git a/packages/addons/_tests/tailwindcss/test.ts b/packages/addons/_tests/tailwindcss/test.ts index 35603467b..00258472f 100644 --- a/packages/addons/_tests/tailwindcss/test.ts +++ b/packages/addons/_tests/tailwindcss/test.ts @@ -3,7 +3,7 @@ import { setupTest } from '../_setup/suite.ts'; import { addFixture } from './fixtures.ts'; import tailwindcss from '../../tailwindcss/index.ts'; -const { test, prepareServer, addonTestCases } = setupTest( +const { test, prepareServer, testCases } = setupTest( { tailwindcss }, { kinds: [ @@ -13,25 +13,25 @@ const { test, prepareServer, addonTestCases } = setupTest( } ); -test.concurrent.for(addonTestCases)( +test.concurrent.for(testCases)( 'tailwindcss $kind.type $variant', - async (addonTestCase, { page, ...ctx }) => { - const cwd = ctx.run(addonTestCase); + async (testCase, { page, ...ctx }) => { + const cwd = ctx.run(testCase); // ...add test files - addFixture(cwd, addonTestCase.variant); + addFixture(cwd, testCase.variant); const { close } = await prepareServer({ cwd, page }); // kill server process when we're done ctx.onTestFinished(async () => await close()); - if (addonTestCase.kind.type === 'none') { + if (testCase.kind.type === 'none') { const el = page.getByTestId('base'); await expect(el).toHaveCSS('background-color', 'oklch(0.446 0.043 257.281)'); await expect(el).toHaveCSS('border-color', 'oklch(0.985 0.002 247.839)'); await expect(el).toHaveCSS('border-width', '4px'); await expect(el).toHaveCSS('margin-top', '4px'); - } else if (addonTestCase.kind.type === 'typography') { + } else if (testCase.kind.type === 'typography') { const el = page.getByTestId('typography'); await expect(el).toHaveCSS('font-size', '18px'); await expect(el).toHaveCSS('line-height', '28px'); diff --git a/packages/addons/_tests/vitest/test.ts b/packages/addons/_tests/vitest/test.ts index 0a9a772b5..a11339e5c 100644 --- a/packages/addons/_tests/vitest/test.ts +++ b/packages/addons/_tests/vitest/test.ts @@ -4,13 +4,13 @@ import vitest from '../../vitest-addon/index.ts'; import path from 'node:path'; import fs from 'node:fs'; -const { test, addonTestCases } = setupTest( +const { test, testCases } = setupTest( { vitest }, { kinds: [{ type: 'default', options: { vitest: {} } }], browser: false } ); -test.concurrent.for(addonTestCases)('vitest $variant', (addonTestCase, { expect, ...ctx }) => { - const cwd = ctx.run(addonTestCase); +test.concurrent.for(testCases)('vitest $variant', (testCase, { expect, ...ctx }) => { + const cwd = ctx.run(testCase); expect(() => execSync('pnpm install', { cwd, stdio: 'pipe' })).not.toThrow(); @@ -18,7 +18,7 @@ test.concurrent.for(addonTestCases)('vitest $variant', (addonTestCase, { expect, expect(() => execSync('pnpm test', { cwd, stdio: 'pipe' })).not.toThrow(); - const ext = addonTestCase.variant.includes('ts') ? 'ts' : 'js'; + const ext = testCase.variant.includes('ts') ? 'ts' : 'js'; const viteFile = path.resolve(cwd, `vite.config.${ext}`); const viteContent = fs.readFileSync(viteFile, 'utf8'); From 94984d55477faa9e414c108f5d0dfd9fbc006ded Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sun, 5 Oct 2025 01:42:12 -0400 Subject: [PATCH 26/30] change `ctx.run` to `ctx.cwd` --- community-addon-template/tests/custom-addon.test.ts | 2 +- community-addon-template/tests/setup/suite.ts | 10 +++++----- packages/addons/_tests/_setup/suite.ts | 10 +++++----- packages/addons/_tests/all-addons/test.ts | 2 +- packages/addons/_tests/devtools-json/test.ts | 2 +- packages/addons/_tests/drizzle/test.ts | 2 +- packages/addons/_tests/eslint/test.ts | 2 +- packages/addons/_tests/lucia/test.ts | 2 +- packages/addons/_tests/mdsvex/test.ts | 2 +- packages/addons/_tests/paraglide/test.ts | 2 +- packages/addons/_tests/playwright/test.ts | 2 +- packages/addons/_tests/prettier/test.ts | 2 +- packages/addons/_tests/storybook/test.ts | 2 +- packages/addons/_tests/sveltekit-adapter/test.ts | 2 +- packages/addons/_tests/tailwindcss/test.ts | 2 +- packages/addons/_tests/vitest/test.ts | 2 +- 16 files changed, 24 insertions(+), 24 deletions(-) diff --git a/community-addon-template/tests/custom-addon.test.ts b/community-addon-template/tests/custom-addon.test.ts index 2b6f07f3b..8cc944167 100644 --- a/community-addon-template/tests/custom-addon.test.ts +++ b/community-addon-template/tests/custom-addon.test.ts @@ -12,7 +12,7 @@ const { test, addonTestCases, prepareServer } = setupTest( test.concurrent.for(addonTestCases)( 'community-addon $variant', async (addonTestCase, { page, ...ctx }) => { - const cwd = ctx.run(addonTestCase); + const cwd = ctx.cwd(addonTestCase); // ...add files if (addonTestCase.variant.startsWith('kit')) { diff --git a/community-addon-template/tests/setup/suite.ts b/community-addon-template/tests/setup/suite.ts index 90ba25ddc..19a3ebb8f 100644 --- a/community-addon-template/tests/setup/suite.ts +++ b/community-addon-template/tests/setup/suite.ts @@ -19,9 +19,9 @@ const variants = vitest.inject('variants'); const SETUP_DIR = fileURLToPath(new URL('.', import.meta.url)); -type Fixtures = { +type Fixtures = { page: Page; - run(addonTestCase: AddonTestCase): string; + cwd(addonTestCase: AddonTestCase): string; }; type AddonTestCase = { @@ -37,7 +37,7 @@ export function setupTest( browser?: boolean; } ) { - const test = vitest.test.extend>({} as any); + const test = vitest.test.extend({} as any); const withBrowser = options?.browser ?? true; @@ -105,14 +105,14 @@ export function setupTest( }); // runs before each test case - vitest.beforeEach>(async (ctx) => { + vitest.beforeEach(async (ctx) => { let browserCtx: BrowserContext; if (withBrowser) { browserCtx = await browser.newContext(); ctx.page = await browserCtx.newPage(); } - ctx.run = (addonTestCase) => { + ctx.cwd = (addonTestCase) => { return path.join(cwd, testName, `${addonTestCase.kind.type}-${addonTestCase.variant}`); }; diff --git a/packages/addons/_tests/_setup/suite.ts b/packages/addons/_tests/_setup/suite.ts index 25e52c84e..48c211747 100644 --- a/packages/addons/_tests/_setup/suite.ts +++ b/packages/addons/_tests/_setup/suite.ts @@ -19,9 +19,9 @@ const variants = vitest.inject('variants'); export const execAsync = promisify(exec); -type Fixtures = { +type Fixtures = { page: Page; - run(addonTestCase: AddonTestCase): string; + cwd(addonTestCase: AddonTestCase): string; }; type AddonTestCase = { @@ -37,7 +37,7 @@ export function setupTest( browser?: boolean; } ) { - const test = vitest.test.extend>({} as any); + const test = vitest.test.extend({} as any); const withBrowser = options?.browser ?? true; @@ -105,14 +105,14 @@ export function setupTest( }); // runs before each test case - vitest.beforeEach>(async (ctx) => { + vitest.beforeEach(async (ctx) => { let browserCtx: BrowserContext; if (withBrowser) { browserCtx = await browser.newContext(); ctx.page = await browserCtx.newPage(); } - ctx.run = (addonTestCase) => { + ctx.cwd = (addonTestCase) => { return path.join(cwd, testName, `${addonTestCase.kind.type}-${addonTestCase.variant}`); }; diff --git a/packages/addons/_tests/all-addons/test.ts b/packages/addons/_tests/all-addons/test.ts index e2cce8fca..20669b452 100644 --- a/packages/addons/_tests/all-addons/test.ts +++ b/packages/addons/_tests/all-addons/test.ts @@ -25,7 +25,7 @@ const { test, testCases, prepareServer } = setupTest(addons, { }); test.concurrent.for(testCases)('run all addons - $variant', async (testCase, { page, ...ctx }) => { - const cwd = ctx.run(testCase); + const cwd = ctx.cwd(testCase); const { close } = await prepareServer({ cwd, page }); // kill server process when we're done diff --git a/packages/addons/_tests/devtools-json/test.ts b/packages/addons/_tests/devtools-json/test.ts index 7ac93b1c2..10f8e3795 100644 --- a/packages/addons/_tests/devtools-json/test.ts +++ b/packages/addons/_tests/devtools-json/test.ts @@ -10,7 +10,7 @@ const { test, testCases } = setupTest( ); test.concurrent.for(testCases)('devtools-json $variant', (testCase, ctx) => { - const cwd = ctx.run(testCase); + const cwd = ctx.cwd(testCase); const ext = testCase.variant.includes('ts') ? 'ts' : 'js'; const viteFile = path.resolve(cwd, `vite.config.${ext}`); diff --git a/packages/addons/_tests/drizzle/test.ts b/packages/addons/_tests/drizzle/test.ts index 00809fa18..6e2c6a590 100644 --- a/packages/addons/_tests/drizzle/test.ts +++ b/packages/addons/_tests/drizzle/test.ts @@ -56,7 +56,7 @@ test.concurrent.for(testCases)( 'drizzle $kind.type $variant', async (testCase, { page, ...ctx }) => { if (testCase.kind.options.drizzle.docker && noDocker) ctx.skip(); - const cwd = ctx.run(testCase); + const cwd = ctx.cwd(testCase); const ts = testCase.variant === 'kit-ts'; const drizzleConfig = path.resolve(cwd, `drizzle.config.${ts ? 'ts' : 'js'}`); diff --git a/packages/addons/_tests/eslint/test.ts b/packages/addons/_tests/eslint/test.ts index 59e6c906d..19cf69133 100644 --- a/packages/addons/_tests/eslint/test.ts +++ b/packages/addons/_tests/eslint/test.ts @@ -10,7 +10,7 @@ const { test, testCases } = setupTest( ); test.concurrent.for(testCases)('eslint $variant', (testCase, { expect, ...ctx }) => { - const cwd = ctx.run(testCase); + const cwd = ctx.cwd(testCase); const unlintedFile = 'let foo = "";\nif (Boolean(foo)) {\n//\n}'; fs.writeFileSync(path.resolve(cwd, 'src/lib/foo.js'), unlintedFile, 'utf8'); diff --git a/packages/addons/_tests/lucia/test.ts b/packages/addons/_tests/lucia/test.ts index c38df9c80..eff0e1b04 100644 --- a/packages/addons/_tests/lucia/test.ts +++ b/packages/addons/_tests/lucia/test.ts @@ -19,7 +19,7 @@ const { test, testCases, prepareServer } = setupTest( ); test.concurrent.for(testCases)('lucia $variant', async (testCase, { page, ...ctx }) => { - const cwd = ctx.run(testCase); + const cwd = ctx.cwd(testCase); const { close } = await prepareServer({ cwd, page }); // kill server process when we're done diff --git a/packages/addons/_tests/mdsvex/test.ts b/packages/addons/_tests/mdsvex/test.ts index 6b903ee7b..07c7a0ecd 100644 --- a/packages/addons/_tests/mdsvex/test.ts +++ b/packages/addons/_tests/mdsvex/test.ts @@ -14,7 +14,7 @@ const { test, testCases, prepareServer } = setupTest( ); test.concurrent.for(testCases)('mdsvex $variant', async (testCase, { page, ...ctx }) => { - const cwd = ctx.run(testCase); + const cwd = ctx.cwd(testCase); // ...add test files addFixture(cwd, testCase.variant); diff --git a/packages/addons/_tests/paraglide/test.ts b/packages/addons/_tests/paraglide/test.ts index a05907ae4..37eb5c07a 100644 --- a/packages/addons/_tests/paraglide/test.ts +++ b/packages/addons/_tests/paraglide/test.ts @@ -17,7 +17,7 @@ const { test, testCases, prepareServer } = setupTest( ); test.concurrent.for(testCases)('paraglide $variant', async (testCase, { page, ...ctx }) => { - const cwd = ctx.run(testCase); + const cwd = ctx.cwd(testCase); const { close } = await prepareServer({ cwd, page }); // kill server process when we're done diff --git a/packages/addons/_tests/playwright/test.ts b/packages/addons/_tests/playwright/test.ts index 7ebf6a5b4..a9a8ad0bf 100644 --- a/packages/addons/_tests/playwright/test.ts +++ b/packages/addons/_tests/playwright/test.ts @@ -9,7 +9,7 @@ const { test, testCases } = setupTest( ); test.concurrent.for(testCases)('playwright $variant', (testCase, { expect, ...ctx }) => { - const cwd = ctx.run(testCase); + const cwd = ctx.cwd(testCase); const ext = testCase.variant.includes('ts') ? 'ts' : 'js'; const playwrightConfig = path.resolve(cwd, `playwright.config.${ext}`); diff --git a/packages/addons/_tests/prettier/test.ts b/packages/addons/_tests/prettier/test.ts index 7429cfa02..fe83d5d66 100644 --- a/packages/addons/_tests/prettier/test.ts +++ b/packages/addons/_tests/prettier/test.ts @@ -10,7 +10,7 @@ const { test, testCases } = setupTest( ); test.concurrent.for(testCases)('prettier $variant', (testCase, { expect, ...ctx }) => { - const cwd = ctx.run(testCase); + const cwd = ctx.cwd(testCase); const unformattedFile = 'const foo = "bar"'; fs.writeFileSync(path.resolve(cwd, 'src/lib/foo.js'), unformattedFile, 'utf8'); diff --git a/packages/addons/_tests/storybook/test.ts b/packages/addons/_tests/storybook/test.ts index 6b6412ea8..01b14ad46 100644 --- a/packages/addons/_tests/storybook/test.ts +++ b/packages/addons/_tests/storybook/test.ts @@ -26,7 +26,7 @@ test.for(testCases)( 'storybook $variant', { concurrent: !CI }, async (testCase, { page, ...ctx }) => { - const cwd = ctx.run(testCase); + const cwd = ctx.cwd(testCase); const { close } = await prepareServer({ cwd, diff --git a/packages/addons/_tests/sveltekit-adapter/test.ts b/packages/addons/_tests/sveltekit-adapter/test.ts index 0f92e92f0..b11a8fd76 100644 --- a/packages/addons/_tests/sveltekit-adapter/test.ts +++ b/packages/addons/_tests/sveltekit-adapter/test.ts @@ -19,7 +19,7 @@ const { test, testCases, prepareServer } = setupTest( test.concurrent.for(testCases)( 'adapter $kind.type $variant', async (testCase, { page, ...ctx }) => { - const cwd = ctx.run(testCase); + const cwd = ctx.cwd(testCase); const { close } = await prepareServer({ cwd, page }); // kill server process when we're done diff --git a/packages/addons/_tests/tailwindcss/test.ts b/packages/addons/_tests/tailwindcss/test.ts index 00258472f..3d49e19af 100644 --- a/packages/addons/_tests/tailwindcss/test.ts +++ b/packages/addons/_tests/tailwindcss/test.ts @@ -16,7 +16,7 @@ const { test, prepareServer, testCases } = setupTest( test.concurrent.for(testCases)( 'tailwindcss $kind.type $variant', async (testCase, { page, ...ctx }) => { - const cwd = ctx.run(testCase); + const cwd = ctx.cwd(testCase); // ...add test files addFixture(cwd, testCase.variant); diff --git a/packages/addons/_tests/vitest/test.ts b/packages/addons/_tests/vitest/test.ts index a11339e5c..9db2f0fbf 100644 --- a/packages/addons/_tests/vitest/test.ts +++ b/packages/addons/_tests/vitest/test.ts @@ -10,7 +10,7 @@ const { test, testCases } = setupTest( ); test.concurrent.for(testCases)('vitest $variant', (testCase, { expect, ...ctx }) => { - const cwd = ctx.run(testCase); + const cwd = ctx.cwd(testCase); expect(() => execSync('pnpm install', { cwd, stdio: 'pipe' })).not.toThrow(); From 5e9639d25157b07aa20b4432233934d5b40a045c Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sun, 5 Oct 2025 01:49:45 -0400 Subject: [PATCH 27/30] redundant `installCommand` --- community-addon-template/tests/setup/suite.ts | 5 ----- packages/addons/_tests/_setup/suite.ts | 5 ----- 2 files changed, 10 deletions(-) diff --git a/community-addon-template/tests/setup/suite.ts b/community-addon-template/tests/setup/suite.ts index 19a3ebb8f..8f5126d3e 100644 --- a/community-addon-template/tests/setup/suite.ts +++ b/community-addon-template/tests/setup/suite.ts @@ -130,7 +130,6 @@ export function setupTest( type PrepareServerOptions = { cwd: string; page: Page; - installCommand?: string; beforeBuild?: () => Promise | any; buildCommand?: string; previewCommand?: string; @@ -139,14 +138,10 @@ type PrepareServerOptions = { async function prepareServer({ cwd, page, - installCommand, // should happen in the beforeAll hook beforeBuild, buildCommand = 'pnpm build', previewCommand = 'pnpm preview' }: PrepareServerOptions) { - // install deps - if (installCommand) execSync(installCommand, { cwd, stdio: 'pipe' }); - // ...do commands and any other extra stuff await beforeBuild?.(); diff --git a/packages/addons/_tests/_setup/suite.ts b/packages/addons/_tests/_setup/suite.ts index 48c211747..6ecb7b728 100644 --- a/packages/addons/_tests/_setup/suite.ts +++ b/packages/addons/_tests/_setup/suite.ts @@ -130,7 +130,6 @@ export function setupTest( type PrepareServerOptions = { cwd: string; page: Page; - installCommand?: string; beforeBuild?: () => Promise | any; buildCommand?: string; previewCommand?: string; @@ -139,14 +138,10 @@ type PrepareServerOptions = { async function prepareServer({ cwd, page, - installCommand, // should happen in the beforeAll hook beforeBuild, buildCommand = 'pnpm build', previewCommand = 'pnpm preview' }: PrepareServerOptions) { - // install deps - if (installCommand) execSync(installCommand, { cwd, stdio: 'pipe' }); - // ...do commands and any other extra stuff await beforeBuild?.(); From 80db5be590178473ed616d3e6019c7792e3172d9 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sun, 5 Oct 2025 01:49:56 -0400 Subject: [PATCH 28/30] missing encoding --- packages/cli/utils/package-manager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/utils/package-manager.ts b/packages/cli/utils/package-manager.ts index 4341a1023..b13d4ae68 100644 --- a/packages/cli/utils/package-manager.ts +++ b/packages/cli/utils/package-manager.ts @@ -141,7 +141,7 @@ export async function addPnpmBuildDependencies( // save the updated package.json const newContent = generateCode(); - if (newContent !== content) fs.writeFileSync(pkgPath, newContent); + if (newContent !== content) fs.writeFileSync(pkgPath, newContent, 'utf8'); } } From fee50f5ee77e9a3679cc08413bf01b86b644d55f Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sun, 5 Oct 2025 01:53:05 -0400 Subject: [PATCH 29/30] `beforeBuild` no longer necessary since `installCommand` moved --- community-addon-template/tests/setup/suite.ts | 5 ----- packages/addons/_tests/_setup/suite.ts | 5 ----- packages/addons/_tests/drizzle/test.ts | 10 +++------- 3 files changed, 3 insertions(+), 17 deletions(-) diff --git a/community-addon-template/tests/setup/suite.ts b/community-addon-template/tests/setup/suite.ts index 8f5126d3e..962f3d776 100644 --- a/community-addon-template/tests/setup/suite.ts +++ b/community-addon-template/tests/setup/suite.ts @@ -130,7 +130,6 @@ export function setupTest( type PrepareServerOptions = { cwd: string; page: Page; - beforeBuild?: () => Promise | any; buildCommand?: string; previewCommand?: string; }; @@ -138,13 +137,9 @@ type PrepareServerOptions = { async function prepareServer({ cwd, page, - beforeBuild, buildCommand = 'pnpm build', previewCommand = 'pnpm preview' }: PrepareServerOptions) { - // ...do commands and any other extra stuff - await beforeBuild?.(); - // build project if (buildCommand) execSync(buildCommand, { cwd, stdio: 'pipe' }); diff --git a/packages/addons/_tests/_setup/suite.ts b/packages/addons/_tests/_setup/suite.ts index 6ecb7b728..cac333089 100644 --- a/packages/addons/_tests/_setup/suite.ts +++ b/packages/addons/_tests/_setup/suite.ts @@ -130,7 +130,6 @@ export function setupTest( type PrepareServerOptions = { cwd: string; page: Page; - beforeBuild?: () => Promise | any; buildCommand?: string; previewCommand?: string; }; @@ -138,13 +137,9 @@ type PrepareServerOptions = { async function prepareServer({ cwd, page, - beforeBuild, buildCommand = 'pnpm build', previewCommand = 'pnpm preview' }: PrepareServerOptions) { - // ...do commands and any other extra stuff - await beforeBuild?.(); - // build project if (buildCommand) execSync(buildCommand, { cwd, stdio: 'pipe' }); diff --git a/packages/addons/_tests/drizzle/test.ts b/packages/addons/_tests/drizzle/test.ts index 6e2c6a590..d4afdd0c0 100644 --- a/packages/addons/_tests/drizzle/test.ts +++ b/packages/addons/_tests/drizzle/test.ts @@ -70,13 +70,9 @@ test.concurrent.for(testCases)( const pageServerPath = path.resolve(routes, `+page.server.${ts ? 'ts' : 'js'}`); fs.writeFileSync(pageServerPath, pageServer, 'utf8'); - const { close } = await prepareServer({ - cwd, - page, - beforeBuild: () => { - execSync('npm run db:push', { cwd, stdio: 'pipe' }); - } - }); + execSync('npm run db:push', { cwd, stdio: 'pipe' }); + + const { close } = await prepareServer({ cwd, page }); // kill server process when we're done ctx.onTestFinished(async () => await close()); From 74af92a51d8df63aa24870b4e696e90e15b53a22 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sun, 5 Oct 2025 01:59:53 -0400 Subject: [PATCH 30/30] last bit --- packages/cli/utils/package-manager.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/cli/utils/package-manager.ts b/packages/cli/utils/package-manager.ts index b13d4ae68..a63ccbfec 100644 --- a/packages/cli/utils/package-manager.ts +++ b/packages/cli/utils/package-manager.ts @@ -105,7 +105,6 @@ export async function addPnpmBuildDependencies( // find the workspace root (if present) const found = find.up('pnpm-workspace.yaml', { cwd }); - const rootDir = found ? path.dirname(found) : cwd; if (confIn === 'pnpm-workspace.yaml') { const content = found ? fs.readFileSync(found, 'utf-8') : ''; @@ -122,11 +121,11 @@ export async function addPnpmBuildDependencies( data.set('onlyBuiltDependencies', items); const newContent = generateCode(); - const pnpmWorkspacePath = found ?? path.join(cwd, 'pnpm-workspace.yaml'); - if (newContent !== content) fs.writeFileSync(pnpmWorkspacePath, newContent); + if (newContent !== content) fs.writeFileSync(pnpmWorkspacePath, newContent, 'utf-8'); } else { // else is package.json (fallback) + const rootDir = found ? path.dirname(found) : cwd; const pkgPath = path.join(rootDir, 'package.json'); const content = fs.readFileSync(pkgPath, 'utf-8'); const { data, generateCode } = parseJson(content); @@ -141,7 +140,7 @@ export async function addPnpmBuildDependencies( // save the updated package.json const newContent = generateCode(); - if (newContent !== content) fs.writeFileSync(pkgPath, newContent, 'utf8'); + if (newContent !== content) fs.writeFileSync(pkgPath, newContent, 'utf-8'); } }