diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index e8ae352a8a..ee2de64b93 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -2,8 +2,8 @@ name: Deploy docs
on:
push:
- tags:
- - 'v*'
+ branches:
+ - main
jobs:
release:
@@ -18,22 +18,10 @@ jobs:
uses: actions/setup-node@v3
with:
node-version: 16.18.0
+ cache: yarn
- - name: Cache
- id: yarn-cache-dir-path
- run: echo "::set-output name=dir::$(yarn config get cacheFolder)"
-
- - name: Restore
- uses: actions/cache@v3
- id: yarn-cache
- with:
- path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
- key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
- restore-keys: |
- ${{ runner.os }}-yarn-
-
- - name: yarn install
- run: yarn install
+ - name: yarn
+ run: yarn
- name: yarn @bud build
run: yarn @bud build
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 53afd938b2..84df1ef314 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -20,39 +20,23 @@ jobs:
uses: actions/setup-node@v3
with:
node-version: 16.18.0
-
- - name: Cache
- id: yarn-cache-dir-path
- run: echo "::set-output name=dir::$(yarn config get cacheFolder)"
-
- - name: Restore
- uses: actions/cache@v3
- id: yarn-cache
- with:
- path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
- key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
- restore-keys: |
- ${{ runner.os }}-yarn-
+ cache: yarn
- name: set npmAuthToken
run: |
yarn config set npmAuthToken ${{ secrets.NODE_AUTH_TOKEN }}
- name: Set npmPublishRegistry
- run: |
- yarn config set npmPublishRegistry https://registry.npmjs.org/
+ run: yarn config set npmPublishRegistry https://registry.npmjs.org/
- name: Set npmRegistryServer
- run: |
- yarn config set npmRegistryServer https://registry.npmjs.org/
+ run: yarn config set npmRegistryServer https://registry.npmjs.org/
- name: Release v${{ github.event.inputs.version }}
- run: |
- yarn @bud release --tag latest --version ${{ github.event.inputs.version }}
+ run: yarn @bud release --tag latest --version ${{ github.event.inputs.version }}
- - name: reset npmAuthToken
- run: |
- yarn config set npmAuthToken "${NPM_AUTH_TOKEN:-fallback}"
+ - name: Reset npmAuthToken
+ run: yarn config set npmAuthToken "${NPM_AUTH_TOKEN:-fallback}"
- name: Configure Git
run: |
@@ -60,8 +44,7 @@ jobs:
git config user.email "<>"
- name: Create v${{ github.event.inputs.version }} branch
- run: |
- git checkout -b v${{ github.event.inputs.version }}
+ run: git checkout -b v${{ github.event.inputs.version }}
- name: Commit v${{ github.event.inputs.version }}
run: |
diff --git a/.github/workflows/test.e2e.yml b/.github/workflows/test.e2e.yml
index c767082f64..59f00e2422 100644
--- a/.github/workflows/test.e2e.yml
+++ b/.github/workflows/test.e2e.yml
@@ -20,41 +20,25 @@ jobs:
runs-on: ${{matrix.platform}}
steps:
- - name: Setup
- uses: actions/setup-node@v3
- with:
- node-version: ${{matrix.node}}
-
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- - name: Cache
- id: yarn-cache-dir-path
- run: echo "::set-output name=dir::$(yarn config get cacheFolder)"
-
- - name: Restore
- uses: actions/cache@v3
- id: yarn-cache
+ - name: Setup
+ uses: actions/setup-node@v3
with:
- path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
- key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
- restore-keys: |
- ${{ runner.os }}-yarn-
+ node-version: ${{matrix.node}}
+ cache: yarn
- - name: yarn install
- run: |
- yarn install
+ - name: yarn
+ run: yarn
- name: yarn @bud registry start
- run: |
- yarn @bud registry start
+ run: yarn @bud registry start
- name: yarn @bud release --tag latest
- run: |
- yarn @bud release --tag latest
+ run: yarn @bud release --tag latest
- name: yarn @bud test e2e
- run: |
- yarn @bud test e2e
+ run: yarn @bud test e2e
diff --git a/.github/workflows/test.format.yml b/.github/workflows/test.format.yml
index 8b8273cbef..827a783148 100644
--- a/.github/workflows/test.format.yml
+++ b/.github/workflows/test.format.yml
@@ -16,49 +16,32 @@ jobs:
node:
- 16.18.0
- name: test node@${{matrix.node}}/${{matrix.platform}}
+ name: format-check (node@v${{matrix.node}}/${{matrix.platform}})
runs-on: ${{matrix.platform}}
steps:
- - name: Setup
- uses: actions/setup-node@v3
- with:
- node-version: ${{matrix.node}}
-
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- - name: Cache
- id: yarn-cache-dir-path
- run: echo "::set-output name=dir::$(yarn config get cacheFolder)"
-
- - name: Restore
- uses: actions/cache@v3
- id: yarn-cache
+ - name: Setup
+ uses: actions/setup-node@v3
with:
- path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
- key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
- restore-keys: |
- ${{ runner.os }}-yarn-
+ node-version: ${{matrix.node}}
+ cache: yarn
- - name: yarn install
- run: |
- yarn install
+ - name: yarn
+ run: yarn
- name: yarn @bud lint dependencies
- run: |
- yarn @bud lint dependencies
+ run: yarn @bud lint dependencies
- name: yarn @bud lint
- run: |
- yarn @bud lint
+ run: yarn @bud lint
- name: yarn @bud format
- run: |
- yarn @bud format --no-fix
+ run: yarn @bud format --no-fix
- name: yarn @bud lint exports
- run: |
- yarn @bud lint exports
+ run: yarn @bud lint exports
diff --git a/.github/workflows/test.integration.yml b/.github/workflows/test.integration.yml
index 6883f9852d..9c44fef42c 100644
--- a/.github/workflows/test.integration.yml
+++ b/.github/workflows/test.integration.yml
@@ -16,45 +16,29 @@ jobs:
node:
- 16.18.0
- name: test node@${{matrix.node}}/${{matrix.platform}}
+ name: integration test (node@v${{matrix.node}}/${{matrix.platform}})
runs-on: ${{matrix.platform}}
steps:
- - name: Setup
- uses: actions/setup-node@v3
- with:
- node-version: ${{matrix.node}}
-
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- - name: Cache
- id: yarn-cache-dir-path
- run: echo "::set-output name=dir::$(yarn config get cacheFolder)"
-
- - name: Restore
- uses: actions/cache@v3
- id: yarn-cache
+ - name: Setup
+ uses: actions/setup-node@v3
with:
- path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
- key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
- restore-keys: |
- ${{ runner.os }}-yarn-
+ node-version: ${{matrix.node}}
+ cache: yarn
- - name: yarn install
- run: |
- yarn install
+ - name: yarn
+ run: yarn
- name: yarn @bud registry start
- run: |
- yarn @bud registry start
+ run: yarn @bud registry start
- name: yarn @bud release --tag latest
- run: |
- yarn @bud release --tag latest
+ run: yarn @bud release --tag latest
- name: yarn @bud test integration
- run: |
- yarn @bud test integration run
+ run: yarn @bud test integration run
diff --git a/.github/workflows/test.unit.yml b/.github/workflows/test.unit.yml
index 89788c36ad..897d835d59 100644
--- a/.github/workflows/test.unit.yml
+++ b/.github/workflows/test.unit.yml
@@ -16,37 +16,23 @@ jobs:
node:
- 16.18.0
- name: test node@${{matrix.node}}/${{matrix.platform}}
+ name: unit test (node@v${{matrix.node}}/${{matrix.platform}})
runs-on: ${{matrix.platform}}
steps:
- - name: Setup
- uses: actions/setup-node@v3
- with:
- node-version: ${{matrix.node}}
-
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- - name: Cache
- id: yarn-cache-dir-path
- run: echo "::set-output name=dir::$(yarn config get cacheFolder)"
-
- - name: Restore
- uses: actions/cache@v3
- id: yarn-cache
+ - name: Setup
+ uses: actions/setup-node@v3
with:
- path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
- key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
- restore-keys: |
- ${{ runner.os }}-yarn-
+ node-version: ${{matrix.node}}
+ cache: yarn
- - name: yarn install
- run: |
- yarn install
+ - name: yarn
+ run: yarn
- name: yarn @bud test unit
- run: |
- yarn @bud test unit run --coverage
+ run: yarn @bud test unit run --coverage
diff --git a/config/eslint.config.cjs b/config/eslint.config.cjs
index ed21a4db8b..df8075e4b8 100644
--- a/config/eslint.config.cjs
+++ b/config/eslint.config.cjs
@@ -84,6 +84,7 @@ module.exports = {
],
[`n/no-missing-import`]: OFF,
[`n/no-path-concat`]: ERROR,
+ [`n/shebang`]: OFF,
[`react/prop-types`]: OFF,
[`react/react-in-jsx-scope`]: ERROR,
[`react-hooks/rules-of-hooks`]: ERROR,
diff --git a/examples/react/bud.config.cjs b/examples/react/bud.config.cjs
index 0b0364c508..519ff6a165 100644
--- a/examples/react/bud.config.cjs
+++ b/examples/react/bud.config.cjs
@@ -9,4 +9,5 @@ module.exports = async app => {
.when(app.isProduction, () => {
app.runtime('single').splitChunks().minimize()
})
+ .serve(3015)
}
diff --git a/sources/@roots/bud-compiler/src/compiler.service.ts b/sources/@roots/bud-compiler/src/compiler.service.ts
index cfc3d653bf..52674d3b0e 100644
--- a/sources/@roots/bud-compiler/src/compiler.service.ts
+++ b/sources/@roots/bud-compiler/src/compiler.service.ts
@@ -99,7 +99,13 @@ d * @public
async (_stats, callback) => {
try {
await this.app.hooks.fire(`compiler.after`)
- } catch (error) {}
+ } catch (error) {
+ const err = new Error(
+ error?.message ?? error?.toString() ?? ``,
+ )
+ err.name = `CompilerError (afterEmit)`
+ throw err
+ }
return callback()
},
@@ -112,7 +118,9 @@ d * @public
})
return this.instance
- } catch (error) {}
+ } catch (error) {
+ throw error
+ }
}
/**
diff --git a/sources/@roots/bud-framework/src/configuration/index.ts b/sources/@roots/bud-framework/src/configuration/index.ts
index 1ef40471f1..451871989f 100644
--- a/sources/@roots/bud-framework/src/configuration/index.ts
+++ b/sources/@roots/bud-framework/src/configuration/index.ts
@@ -23,21 +23,39 @@ export const process = async (app: Bud) => {
await Promise.all(
findConfigs(`base`, false).map(async description => {
app.log(`processing base configuration`, description.name)
- await configuration.run(description)
+ try {
+ await configuration.run(description)
+ } catch (error) {
+ const err = new Error(error?.toString() ?? ``)
+ err.name = `Configuration Error: ${description.name}`
+ throw err
+ }
}),
).then(async () => await app.api.processQueue())
await Promise.all(
findConfigs(`base`, true).map(async description => {
app.log(`processing local configuration`, description.name)
- await configuration.run(description)
+ try {
+ await configuration.run(description)
+ } catch (error) {
+ const err = new Error(error?.toString() ?? ``)
+ err.name = `Configuration Error: ${description.name}`
+ throw err
+ }
}),
).then(async () => await app.api.processQueue())
await Promise.all(
findConfigs(app.mode, false).map(async description => {
app.log(`processing ${app.mode} configuration`, description.name)
- await configuration.run(description)
+ try {
+ await configuration.run(description)
+ } catch (error) {
+ const err = new Error(error?.toString() ?? ``)
+ err.name = `Configuration Error: ${description.name}`
+ throw err
+ }
}),
).then(async () => await app.api.processQueue())
@@ -47,7 +65,13 @@ export const process = async (app: Bud) => {
`processing ${app.mode} local configuration`,
description.name,
)
- await configuration.run(description)
+ try {
+ await configuration.run(description)
+ } catch (error) {
+ const err = new Error(error?.toString() ?? ``)
+ err.name = `Configuration Error: ${description.name}`
+ throw err
+ }
}),
).then(async () => await app.api.processQueue())
} catch (error) {
@@ -57,19 +81,23 @@ export const process = async (app: Bud) => {
try {
await app.hooks.fire(`config.after`)
} catch (error) {
- throw error
+ const err = new Error(error?.toString() ?? ``)
+ err.name = `Post configuration error`
+ throw err
}
if (app.hasChildren) {
- try {
- await Promise.all(
- Object.values(app.children).map(async child => {
+ await Promise.all(
+ Object.values(app.children).map(async child => {
+ try {
await child.api.processQueue()
await child.hooks.fire(`config.after`)
- }),
- )
- } catch (error) {
- throw error
- }
+ } catch (error) {
+ const err = new Error(error?.toString() ?? ``)
+ err.name = `Post config: error processing ${child.label}`
+ throw err
+ }
+ }),
+ )
}
}
diff --git a/sources/@roots/bud-server/src/server/base.ts b/sources/@roots/bud-server/src/server/base.ts
index 2cdb10e21b..3b8e5661cd 100644
--- a/sources/@roots/bud-server/src/server/base.ts
+++ b/sources/@roots/bud-server/src/server/base.ts
@@ -54,7 +54,7 @@ export abstract class BaseServer implements Connection {
* @public
*/
public get url(): URL {
- return this.app.hooks.filter(`dev.url`)
+ return this.app.hooks.filter(`dev.url`, new URL(`http://0.0.0.0:3000`))
}
/**
@@ -138,6 +138,8 @@ export abstract class BaseServer implements Connection {
*/
@bind
public onError(error: Error) {
- this.app.error(error)
+ error.name = `bud.js server error`
+ error.message = error?.message ?? error.toString()
+ throw error
}
}
diff --git a/sources/@roots/bud/src/cli/commands/bud.build.tsx b/sources/@roots/bud/src/cli/commands/bud.build.tsx
index 5ac54bf324..2ad62f1462 100644
--- a/sources/@roots/bud/src/cli/commands/bud.build.tsx
+++ b/sources/@roots/bud/src/cli/commands/bud.build.tsx
@@ -200,8 +200,12 @@ export default class BudBuildCommand extends BudCommand {
*/
@bind
public override async execute() {
- await this.makeBud(this)
- await this.healthcheck(this)
- await this.run(this)
+ try {
+ await this.makeBud(this)
+ await this.healthcheck(this)
+ await this.run(this)
+ } catch (error) {
+ throw error
+ }
}
}
diff --git a/sources/@roots/bud/src/cli/commands/bud.clean.tsx b/sources/@roots/bud/src/cli/commands/bud.clean.tsx
index 7fc641d310..d408c49dda 100644
--- a/sources/@roots/bud/src/cli/commands/bud.clean.tsx
+++ b/sources/@roots/bud/src/cli/commands/bud.clean.tsx
@@ -4,7 +4,6 @@ import {Command, Option} from '@roots/bud-support/clipanion'
import {bind} from '@roots/bud-support/decorators'
import {ensureDir, remove} from '@roots/bud-support/fs'
import {Box, Text} from '@roots/bud-support/ink'
-import {isString} from '@roots/bud-support/lodash-es'
import React from '@roots/bud-support/react'
/**
@@ -16,6 +15,7 @@ import React from '@roots/bud-support/react'
@dry
export default class BudCleanCommand extends BudCommand {
public static override paths = [[`clean`]]
+
public static override usage = Command.Usage({
category: `tasks`,
description: `Clean project artifacts and caches`,
@@ -64,20 +64,57 @@ export default class BudCleanCommand extends BudCommand {
@bind
public async cleanOutput() {
try {
- await remove(this.bud.path(`@dist`))
+ if (this.bud.hasChildren) {
+ return await Promise.all(
+ Object.values(this.bud.children).map(async child => {
+ try {
+ await remove(child.path(`@dist`))
+ await this.renderOnce(
+
+
+ ✔ emptied {child.path(`@dist`)}
+
+ ,
+ )
+ } catch (error) {
+ throw error
+ }
+ }),
+ )
+ }
+ await remove(this.bud.path(`@dist`))
await this.renderOnce(
✔ emptied {this.bud.path(`@dist`)}
,
)
- } catch (err) {
- this.context.stderr.write(err)
+ } catch (error) {
+ throw error
}
}
@bind
public async cleanStorage() {
+ if (this.bud.hasChildren) {
+ return await Promise.all(
+ Object.values(this.bud.children).map(async child => {
+ try {
+ await remove(child.path(`@dist`))
+ await this.renderOnce(
+
+
+ ✔ emptied {child.path(`@storage`)}
+
+ ,
+ )
+ } catch (error) {
+ throw error
+ }
+ }),
+ )
+ }
+
try {
await ensureDir(this.bud.path(`@storage`))
await remove(this.bud.path(`@storage`))
@@ -86,14 +123,8 @@ export default class BudCleanCommand extends BudCommand {
✔ emptied {this.bud.path(`@storage`)}
,
)
- } catch (err) {
- await this.renderOnce(
-
-
- {err?.message ?? isString(err) ? err : JSON.stringify(err)}
-
- ,
- )
+ } catch (error) {
+ throw error
}
}
}
diff --git a/sources/@roots/bud/src/cli/commands/bud.tsx b/sources/@roots/bud/src/cli/commands/bud.tsx
index bb1530f5d2..698d2ed9e9 100644
--- a/sources/@roots/bud/src/cli/commands/bud.tsx
+++ b/sources/@roots/bud/src/cli/commands/bud.tsx
@@ -109,6 +109,11 @@ export default class BudCommand extends Command {
await this.renderer?.text(text)
}
+ public constructor() {
+ super()
+ this.renderer = new Renderer(process.stdout)
+ }
+
public async execute() {}
public override async catch(value: unknown) {
@@ -166,8 +171,6 @@ export default class BudCommand extends Command {
}
public async makeBud(command: T) {
- this.renderer = new Renderer(process.stdout)
-
command.context.basedir = command.basedir
? resolve(command.context.basedir, command.basedir)
: command.context.basedir
diff --git a/sources/@roots/bud/src/cli/decorators/command.dry.ts b/sources/@roots/bud/src/cli/decorators/command.dry.ts
index d2229eeab6..80f0a9cfa0 100644
--- a/sources/@roots/bud/src/cli/decorators/command.dry.ts
+++ b/sources/@roots/bud/src/cli/decorators/command.dry.ts
@@ -7,15 +7,12 @@ export function dry BudCommand>(
return class extends constructor {
public constructor(...args: any[]) {
super(...args)
- if (this.withArguments) {
- const existingFn = this.withArguments
- this.withArguments = async (args: CommandContext[`args`]) => {
- args = await existingFn(args)
- return {
- ...args,
- dry: true,
- }
- }
+
+ const fn = this.withArguments?.bind(this) ?? (value => value)
+
+ this.withArguments = async (args: CommandContext[`args`]) => {
+ args = await fn(args)
+ return {...args, dry: true}
}
}
}
diff --git a/tests/e2e/__snapshots__/babel.test.ts.snap b/tests/e2e/__snapshots__/babel.test.ts.snap
new file mode 100644
index 0000000000..cae3cb0d0e
--- /dev/null
+++ b/tests/e2e/__snapshots__/babel.test.ts.snap
@@ -0,0 +1,5 @@
+// Vitest Snapshot v1
+
+exports[`html output of examples/babel > rebuilds on change > rgb(0, 0, 0) none repeat scroll 0% 0% / auto padding-box border-box 1`] = `"rgb(0, 0, 0) none repeat scroll 0% 0% / auto padding-box border-box"`;
+
+exports[`html output of examples/babel > rebuilds on change > rgb(88, 19, 213) none repeat scroll 0% 0% / auto padding-box border-box 1`] = `"rgb(88, 19, 213) none repeat scroll 0% 0% / auto padding-box border-box"`;
diff --git a/tests/e2e/babel.test.ts b/tests/e2e/babel.test.ts
index 32a4e57464..de5a5f2da5 100644
--- a/tests/e2e/babel.test.ts
+++ b/tests/e2e/babel.test.ts
@@ -3,37 +3,18 @@ import {execa, ExecaChildProcess} from 'execa'
import fs from 'fs-extra'
import {join} from 'path'
import {Browser, chromium, Page} from 'playwright'
-import {describe, expect, it} from 'vitest'
+import {
+ afterEach,
+ beforeAll,
+ beforeEach,
+ describe,
+ expect,
+ it,
+} from 'vitest'
-import copy from './util/copy'
+import * as cp from './util/copy'
import install from './util/install'
-const reset = async () =>
- fs.writeFile(
- join(paths.mocks, `yarn`, `@examples`, `babel`, `src`, `global.css`),
- `\
-html,
-body {
- padding: 0;
- margin: 0;
-}
-
-.app {
- align-items: center;
- background: rgb(88, 19, 213);
- color: white;
- display: flex;
- font-family: sans-serif;
- height: 100vh;
- justify-content: center;
- letter-spacing: 0.2em;
- text-align: center;
- text-transform: uppercase;
- width: 100vw;
-}
-`,
- )
-
const update = async () =>
fs.writeFile(
join(paths.mocks, `yarn`, `@examples`, `babel`, `src`, `global.css`),
@@ -65,56 +46,61 @@ describe(`html output of examples/babel`, () => {
let page: Page
let devProcess: ExecaChildProcess
- it(`rebuilds on change`, async () => {
+ beforeAll(async () => {
+ await cp.example(`babel`)
+ await install(`babel`)
+ })
+
+ beforeEach(async () => {
try {
- await reset()
- await copy(`babel`)
- .then(install(`babel`))
- .then(async () => {
- devProcess = execa(
- `node`,
- [`./node_modules/.bin/bud`, `dev`, `--no-cache`],
- {
- cwd: join(paths.mocks, `yarn`, `@examples`, `babel`),
- timeout: 10000,
- },
- )
- })
+ await cp.source(`babel`)
- devProcess.stdout?.pipe(process.stdout)
- browser = await chromium.launch()
- page = await browser?.newPage()
+ devProcess = execa(
+ `node`,
+ [`./node_modules/.bin/bud`, `dev`, `--no-cache`],
+ {
+ cwd: join(paths.mocks, `yarn`, `@examples`, `babel`),
+ },
+ )
+ } catch (error) {
+ throw error
+ }
- await page?.goto(`http://0.0.0.0:3005/`)
+ browser = await chromium.launch()
+ page = await browser?.newPage()
+ await page.waitForTimeout(5000)
+ })
- const title = await page.title()
- expect(title).toBe(`Webpack App`)
+ afterEach(async () => {
+ await page?.close()
+ await browser?.close()
+ devProcess?.kill(`SIGINT`)
+ })
- const app = await page.$(`.app`)
- expect(app).toBeTruthy()
+ it(`rebuilds on change`, async () => {
+ await page?.goto(`http://0.0.0.0:3005/`)
- const color = await app?.evaluate(el => {
- return window.getComputedStyle(el).getPropertyValue(`background`)
- })
- expect(color).toMatchSnapshot(
- `rgb(88, 19, 213) none repeat scroll 0% 0% / auto padding-box border-box`,
- )
+ const title = await page.title()
+ expect(title).toBe(`Webpack App`)
- await update()
- await page.waitForTimeout(12000)
+ const app = await page.$(`.app`)
+ expect(app).toBeTruthy()
- const color2 = await app?.evaluate(el => {
- return window.getComputedStyle(el).getPropertyValue(`background`)
- })
- expect(color2).toMatchSnapshot(
- `rgb(0, 0, 0) none repeat scroll 0% 0% / auto padding-box border-box`,
- )
+ const color = await app?.evaluate(el => {
+ return window.getComputedStyle(el).getPropertyValue(`background`)
+ })
+ expect(color).toMatchSnapshot(
+ `rgb(88, 19, 213) none repeat scroll 0% 0% / auto padding-box border-box`,
+ )
- await page?.close()
- await browser?.close()
- devProcess?.kill(`SIGINT`)
- } catch (error) {
- return
- }
+ await update()
+ await page.waitForTimeout(12000)
+
+ const color2 = await app?.evaluate(el => {
+ return window.getComputedStyle(el).getPropertyValue(`background`)
+ })
+ expect(color2).toMatchSnapshot(
+ `rgb(0, 0, 0) none repeat scroll 0% 0% / auto padding-box border-box`,
+ )
})
})
diff --git a/tests/e2e/basic.test.ts b/tests/e2e/basic.test.ts
index 0cfe3bfb3c..5d009962d1 100644
--- a/tests/e2e/basic.test.ts
+++ b/tests/e2e/basic.test.ts
@@ -5,7 +5,6 @@ import {execa, ExecaChildProcess} from 'execa'
import fs from 'fs-extra'
import {Browser, chromium, Page} from 'playwright'
import {
- afterAll,
afterEach,
beforeAll,
beforeEach,
@@ -14,21 +13,9 @@ import {
it,
} from 'vitest'
-import copy from './util/copy'
+import * as cp from './util/copy'
import install from './util/install'
-const reset = async () =>
- await fs.writeFile(
- join(paths.mocks, `yarn`, `@examples`, `basic`, `src`, `index.js`),
- `\
-import './styles.css'
-
-document.querySelector('body')?.classList.add('init')
-
-module?.hot?.accept()
-`,
- )
-
const update = async () =>
await fs.writeFile(
join(paths.mocks, `yarn`, `@examples`, `basic`, `src`, `index.js`),
@@ -41,47 +28,54 @@ module?.hot?.accept()
`,
)
-let browser: Browser
-let page: Page
-let devProcess: ExecaChildProcess
-
describe(`html output of examples/basic`, () => {
- it(`rebuilds on change`, async () => {
+ let browser: Browser
+ let page: Page
+ let devProcess: ExecaChildProcess
+
+ beforeAll(async () => {
+ await cp.example(`basic`)
+ await install(`basic`)
+ })
+
+ beforeEach(async () => {
try {
- await reset()
- await copy(`basic`)
- .then(install(`basic`))
- .then(async () => {
- devProcess = execa(
- `node`,
- [`./node_modules/.bin/bud`, `dev`, `--no-cache`, `--html`],
- {
- cwd: join(paths.mocks, `yarn`, `@examples`, `basic`),
- timeout: 10000,
- },
- )
- })
+ await cp.source(`basic`)
+
+ devProcess = execa(
+ `node`,
+ [`./node_modules/.bin/bud`, `dev`, `--no-cache`, `--html`],
+ {
+ cwd: join(paths.mocks, `yarn`, `@examples`, `basic`),
+ },
+ )
+ } catch (error) {
+ throw error
+ }
- browser = await chromium.launch()
- page = await browser?.newPage()
+ browser = await chromium.launch()
+ page = await browser?.newPage()
+ await page?.waitForTimeout(5000)
+ })
+
+ afterEach(async () => {
+ await page?.close()
+ await browser?.close()
+ devProcess?.kill(`SIGINT`)
+ })
- await page?.goto(`http://0.0.0.0:3000/`)
- const title = await page.title()
- expect(title).toBe(`%APP_TITLE%`)
- const init = await page.$(`.init`)
- expect(init).toBeTruthy()
+ it(`rebuilds on change`, async () => {
+ await page?.goto(`http://0.0.0.0:3000/`)
- await update()
- await page.waitForTimeout(12000)
+ const title = await page.title()
+ expect(title).toBe(`%APP_TITLE%`)
+ const init = await page.$(`.init`)
+ expect(init).toBeTruthy()
- const hot = await page.$(`.hot`)
- expect(hot).toBeTruthy()
+ await update()
+ await page.waitForTimeout(12000)
- await page?.close()
- await browser?.close()
- devProcess?.kill(`SIGINT`)
- } catch (error) {
- return
- }
+ const hot = await page.$(`.hot`)
+ expect(hot).toBeTruthy()
})
})
diff --git a/tests/e2e/react.test.ts b/tests/e2e/react.test.ts
index d2a998c0ec..905bc3d7f2 100644
--- a/tests/e2e/react.test.ts
+++ b/tests/e2e/react.test.ts
@@ -7,7 +7,6 @@ import {execa, ExecaChildProcess} from 'execa'
import fs from 'fs-extra'
import {Browser, chromium, Page} from 'playwright'
import {
- afterAll,
afterEach,
beforeAll,
beforeEach,
@@ -16,39 +15,9 @@ import {
it,
} from 'vitest'
-import copy from './util/copy'
+import * as cp from './util/copy'
import install from './util/install'
-const reset = async () =>
- fs.writeFile(
- join(
- paths.mocks,
- `yarn`,
- `@examples`,
- `react`,
- `src`,
- `components`,
- `App.js`,
- ),
- `\
-import React from 'react'
-
-import logo from './logo.svg'
-
-export const App = () => {
- return (
-
-
-
![logo]({logo})
- Edit
src/components/App.js
and save to
- reload
-
-
- )
-}
-`,
- )
-
const update = async () =>
fs.writeFile(
join(
@@ -78,45 +47,50 @@ export const App = () => {
`,
)
-let browser: Browser
-let page: Page
-let devProcess: ExecaChildProcess
-
describe(`html output of examples/react`, () => {
- it(`rebuilds on change`, async () => {
+ let browser: Browser
+ let page: Page
+ let devProcess: ExecaChildProcess
+
+ beforeAll(async () => {
+ await cp.example(`react`)
+ await install(`react`)
+ })
+
+ beforeEach(async () => {
try {
- await reset()
- await copy(`react`)
- .then(install(`react`))
- .then(async () => {
- devProcess = execa(
- `node`,
- [`./node_modules/.bin/bud`, `dev`, `--no-cache`, `--html`],
- {
- cwd: join(paths.mocks, `yarn`, `@examples`, `react`),
- timeout: 10000,
- },
- )
- })
+ await cp.source(`react`)
+
+ devProcess = execa(
+ `node`,
+ [`./node_modules/.bin/bud`, `dev`, `--no-cache`],
+ {
+ cwd: join(paths.mocks, `yarn`, `@examples`, `react`),
+ },
+ )
+ } catch (error) {
+ throw error
+ }
- devProcess.stdout?.pipe(process.stdout)
- browser = await chromium.launch()
- page = await browser?.newPage()
+ browser = await chromium.launch()
+ page = await browser?.newPage()
+ await page.waitForTimeout(5000)
+ })
- await page?.goto(`http://0.0.0.0:3000/`)
- expect(await page.$(`.App`)).toBeTruthy()
- expect(await page.$(`.target`)).toBeFalsy()
+ afterEach(async () => {
+ await page?.close()
+ await browser?.close()
+ devProcess?.kill(`SIGINT`)
+ })
- await update()
- await page.waitForTimeout(12000)
- expect(await page.$(`.target`)).toBeTruthy()
+ it(`rebuilds on change`, async () => {
+ await page?.goto(`http://0.0.0.0:3015/`)
- await page?.close()
- await browser?.close()
+ expect(await page.$(`.App`)).toBeTruthy()
+ expect(await page.$(`.target`)).toBeFalsy()
- devProcess?.kill(`SIGINT`)
- } catch (error) {
- return
- }
+ await update()
+ await page.waitForTimeout(12000)
+ expect(await page.$(`.target`)).toBeTruthy()
})
})
diff --git a/tests/e2e/util/copy.ts b/tests/e2e/util/copy.ts
index de90d109f5..12525f8e61 100644
--- a/tests/e2e/util/copy.ts
+++ b/tests/e2e/util/copy.ts
@@ -3,12 +3,7 @@ import {logger} from '@repo/logger'
import fs from 'fs-extra'
import {join} from 'path'
-const options = {
- overwrite: true,
- recursive: true,
-}
-
-const copy = async (designator: string) => {
+export const example = async (designator: string) => {
try {
logger.log(`copying @examples/${designator}`)
@@ -22,6 +17,7 @@ const copy = async (designator: string) => {
designator,
),
)
+
await fs.copy(
join(paths.root, `examples`, designator),
join(
@@ -32,7 +28,10 @@ const copy = async (designator: string) => {
`@examples`,
designator,
),
- options,
+ {
+ overwrite: true,
+ recursive: true,
+ },
)
const file = await fs.readFile(
@@ -59,4 +58,37 @@ const copy = async (designator: string) => {
}
}
-export default copy
+export const source = async (designator: string) => {
+ try {
+ await fs.remove(
+ join(
+ paths.root,
+ `storage`,
+ `mocks`,
+ `yarn`,
+ `@examples`,
+ designator,
+ `src`,
+ ),
+ )
+
+ await fs.copy(
+ join(paths.root, `examples`, designator, `src`),
+ join(
+ paths.root,
+ `storage`,
+ `mocks`,
+ `yarn`,
+ `@examples`,
+ designator,
+ `src`,
+ ),
+ {
+ overwrite: true,
+ recursive: true,
+ },
+ )
+ } catch (error) {
+ throw error
+ }
+}
diff --git a/tests/e2e/util/install.ts b/tests/e2e/util/install.ts
index ca4e764e7a..733ee8c94d 100644
--- a/tests/e2e/util/install.ts
+++ b/tests/e2e/util/install.ts
@@ -14,7 +14,7 @@ const options = (designator: string): Options => ({
),
})
-const install = (designator: string) => async () => {
+const install = async (designator: string) => {
try {
logger.log(`installing @examples/${designator}`)