diff --git a/src/utils/dev.ts b/src/utils/dev.ts index 912e46ce404..3b3859b799d 100644 --- a/src/utils/dev.ts +++ b/src/utils/dev.ts @@ -216,8 +216,15 @@ export const injectEnvVariables = (env) => { } } -// @ts-expect-error TS(7031) FIXME: Binding element 'configuredPort' implicitly has an... Remove this comment to see the full error message -export const acquirePort = async ({ configuredPort, defaultPort, errorMessage }) => { +export const acquirePort = async ({ + configuredPort, + defaultPort, + errorMessage, +}: { + configuredPort?: number + defaultPort: number + errorMessage: string +}) => { const acquiredPort = await getPort({ port: configuredPort || defaultPort }) if (configuredPort && acquiredPort !== configuredPort) { throw new Error(`${errorMessage}: '${configuredPort}'`) diff --git a/tests/integration/__snapshots__/framework-detection.test.js.snap b/tests/integration/__snapshots__/framework-detection.test.js.snap index 95c47bd12ac..904312630e5 100644 --- a/tests/integration/__snapshots__/framework-detection.test.js.snap +++ b/tests/integration/__snapshots__/framework-detection.test.js.snap @@ -6,7 +6,7 @@ exports[`frameworks/framework-detection > should default to process.cwd() and st ◈ Unable to determine public folder to serve files from. Using current working directory ◈ Setup a netlify.toml file with a [dev] section to specify your dev server settings. ◈ See docs at: https://docs.netlify.com/cli/local-development/#project-detection -◈ Running static server from \\"site-with-index-file\\" +◈ Running static server from \\"should-default-to-process-cwd-and-static-server\\" ◈ Setting up local development server ◈ Static server listening to 88888 @@ -35,7 +35,7 @@ exports[`frameworks/framework-detection > should filter frameworks with no dev c ◈ Unable to determine public folder to serve files from. Using current working directory ◈ Setup a netlify.toml file with a [dev] section to specify your dev server settings. ◈ See docs at: https://docs.netlify.com/cli/local-development/#project-detection -◈ Running static server from \\"site-with-gulp\\" +◈ Running static server from \\"should-filter-frameworks-with-no-dev-command\\" ◈ Setting up local development server ◈ Static server listening to 88888 @@ -54,21 +54,6 @@ exports[`frameworks/framework-detection > should force a specific framework when ◈ Failed running command: react-scripts start. Please verify 'react-scripts' exists" `; -exports[`frameworks/framework-detection > should log the command if using static server and \`command\` is configured 1`] = ` -"◈ Netlify Dev ◈ -◈ Using simple static server because '--dir' flag was specified -◈ Running static server from \\"site-with-index-file/public\\" -◈ Setting up local development server - -◈ Static server listening to 88888 - - ┌──────────────────────────────────────────────────┐ - │ │ - │ ◈ Server now ready on http://localhost:88888 │ - │ │ - └──────────────────────────────────────────────────┘" -`; - exports[`frameworks/framework-detection > should not run framework detection if command and targetPort are configured 1`] = ` "◈ Netlify Dev ◈ ◈ Unable to determine public folder to serve files from. Using current working directory @@ -162,7 +147,7 @@ exports[`frameworks/framework-detection > should throw when forcing a non suppor exports[`frameworks/framework-detection > should use static server when --dir flag is passed 1`] = ` "◈ Netlify Dev ◈ ◈ Using simple static server because '--dir' flag was specified -◈ Running static server from \\"site-with-index-file/public\\" +◈ Running static server from \\"should-use-static-server-when-dir-flag-is-passed/public\\" ◈ Setting up local development server ◈ Static server listening to 88888 @@ -180,7 +165,7 @@ exports[`frameworks/framework-detection > should use static server when framewor ◈ Unable to determine public folder to serve files from. Using current working directory ◈ Setup a netlify.toml file with a [dev] section to specify your dev server settings. ◈ See docs at: https://docs.netlify.com/cli/local-development/#project-detection -◈ Running static server from \\"site-with-index-file\\" +◈ Running static server from \\"should-use-static-server-when-framework-is-set-to-static\\" ◈ Setting up local development server ◈ Static server listening to 88888 @@ -197,7 +182,7 @@ exports[`frameworks/framework-detection > should warn if using static server and ◈ Using simple static server because '--dir' flag was specified ◈ Ignoring 'targetPort' setting since using a simple static server. ◈ Use --staticServerPort or [dev.staticServerPort] to configure the static server port -◈ Running static server from \\"site-with-index-file/public\\" +◈ Running static server from \\"should-warn-if-using-static-server-and-target-port-is-configured/public\\" ◈ Setting up local development server ◈ Static server listening to 88888 diff --git a/tests/integration/framework-detection.test.js b/tests/integration/framework-detection.test.js index 8d1218c2c52..41018cbfac7 100644 --- a/tests/integration/framework-detection.test.js +++ b/tests/integration/framework-detection.test.js @@ -12,99 +12,79 @@ const content = 'Hello World!' describe.concurrent('frameworks/framework-detection', () => { test('should default to process.cwd() and static server', async (t) => { - await withSiteBuilder('site-with-index-file', async (builder) => { + await withSiteBuilder(t, async (builder) => { await builder .withContentFile({ path: 'index.html', content, }) - .buildAsync() + .build() await withDevServer({ cwd: builder.directory }, async ({ output, url }) => { - const response = await fetch(url).then((res) => res.text()) - t.expect(response).toEqual(content) + const response = await fetch(url) + const responseContent = await response.text() + t.expect(responseContent).toEqual(content) t.expect(normalize(output, { duration: true, filePath: true })).toMatchSnapshot() }) }) }) test('should use static server when --dir flag is passed', async (t) => { - await withSiteBuilder('site-with-index-file', async (builder) => { + await withSiteBuilder(t, async (builder) => { await builder .withContentFile({ path: 'public/index.html', content, }) - .buildAsync() + .build() await withDevServer({ cwd: builder.directory, args: ['--dir', 'public'] }, async ({ output, url }) => { - const response = await fetch(url).then((res) => res.text()) - t.expect(response).toEqual(content) + const response = await fetch(url) + const responseContent = await response.text() + t.expect(responseContent).toEqual(content) t.expect(normalize(output, { duration: true, filePath: true })).toMatchSnapshot() }) }) }) test('should use static server when framework is set to #static', async (t) => { - await withSiteBuilder('site-with-index-file', async (builder) => { + await withSiteBuilder(t, async (builder) => { await builder .withContentFile({ path: 'index.html', content, }) .withNetlifyToml({ config: { dev: { framework: '#static' } } }) - .buildAsync() + .build() await withDevServer({ cwd: builder.directory }, async ({ output, url }) => { - const response = await fetch(url).then((res) => res.text()) - t.expect(response).toEqual(content) + const response = await fetch(url) + const responseContent = await response.text() + t.expect(responseContent).toEqual(content) t.expect(normalize(output, { duration: true, filePath: true })).toMatchSnapshot() }) }) }) - // This test has a race condition that occasionally causes it to fail when run concurrently. - // Running it in isolation (or removing the '.concurrent' on the describe block above) - // fixes it. See CT-1094 for more details - test.skip('should log the command if using static server and `command` is configured', async (t) => { - await withSiteBuilder('site-with-index-file', async (builder) => { - await builder - .withContentFile({ - path: 'public/index.html', - content, - }) - .buildAsync() - - await withDevServer( - { cwd: builder.directory, args: ['--dir', 'public', '--command', 'npm run start'] }, - async ({ output, url }) => { - const response = await fetch(url).then((res) => res.text()) - t.expect(response).toEqual(content) - - t.expect(normalize(output, { duration: true, filePath: true })).toMatchSnapshot() - }, - ) - }) - }) - test('should warn if using static server and `targetPort` is configured', async (t) => { - await withSiteBuilder('site-with-index-file', async (builder) => { + await withSiteBuilder(t, async (builder) => { await builder .withContentFile({ path: 'public/index.html', content, }) - .buildAsync() + .build() await withDevServer( { cwd: builder.directory, args: ['--dir', 'public', '--target-port', '3000'] }, async ({ output, url }) => { - const response = await fetch(url).then((res) => res.text()) - t.expect(response).toEqual(content) + const response = await fetch(url) + const responseContent = await response.text() + t.expect(responseContent).toEqual(content) t.expect(normalize(output, { duration: true, filePath: true })).toMatchSnapshot() }, ) @@ -112,8 +92,8 @@ describe.concurrent('frameworks/framework-detection', () => { }) test('should run `command` when both `command` and `targetPort` are configured', async (t) => { - await withSiteBuilder('empty-site', async (builder) => { - await builder.withNetlifyToml({ config: { build: { publish: 'public' } } }).buildAsync() + await withSiteBuilder(t, async (builder) => { + await builder.withNetlifyToml({ config: { build: { publish: 'public' } } }).build() // a failure is expected since we use `echo hello` instead of starting a server const error = await withDevServer( @@ -127,8 +107,8 @@ describe.concurrent('frameworks/framework-detection', () => { }) test('should force a specific framework when configured', async (t) => { - await withSiteBuilder('site-with-mocked-cra', async (builder) => { - await builder.withNetlifyToml({ config: { dev: { framework: 'create-react-app' } } }).buildAsync() + await withSiteBuilder(t, async (builder) => { + await builder.withNetlifyToml({ config: { dev: { framework: 'create-react-app' } } }).build() // a failure is expected since this is not a true create-react-app project const error = await withDevServer({ cwd: builder.directory }, () => {}, true).catch((error_) => error_) @@ -137,8 +117,8 @@ describe.concurrent('frameworks/framework-detection', () => { }) test('should throw when forcing a non supported framework', async (t) => { - await withSiteBuilder('site-with-unknown-framework', async (builder) => { - await builder.withNetlifyToml({ config: { dev: { framework: 'to-infinity-and-beyond-js' } } }).buildAsync() + await withSiteBuilder(t, async (builder) => { + await builder.withNetlifyToml({ config: { dev: { framework: 'to-infinity-and-beyond-js' } } }).build() const error = await withDevServer({ cwd: builder.directory }, () => {}, true).catch((error_) => error_) t.expect(normalize(error.stdout, { duration: true, filePath: true })).toMatchSnapshot() @@ -146,12 +126,12 @@ describe.concurrent('frameworks/framework-detection', () => { }) test('should detect a known framework', async (t) => { - await withSiteBuilder('site-with-cra', async (builder) => { + await withSiteBuilder(t, async (builder) => { await builder .withPackageJson({ packageJson: { dependencies: { 'react-scripts': '1.0.0' }, scripts: { start: 'react-scripts start' } }, }) - .buildAsync() + .build() // a failure is expected since this is not a true create-react-app project const error = await withDevServer({ cwd: builder.directory }, () => {}, true).catch((error_) => error_) @@ -160,8 +140,8 @@ describe.concurrent('frameworks/framework-detection', () => { }) test('should throw if framework=#custom but command is missing', async (t) => { - await withSiteBuilder('site-with-framework-and-no-command', async (builder) => { - await builder.withNetlifyToml({ config: { dev: { framework: '#custom' } } }).buildAsync() + await withSiteBuilder(t, async (builder) => { + await builder.withNetlifyToml({ config: { dev: { framework: '#custom' } } }).build() const error = await withDevServer( { cwd: builder.directory, args: ['--target-port', '3000'] }, @@ -173,8 +153,8 @@ describe.concurrent('frameworks/framework-detection', () => { }) test('should throw if framework=#custom but targetPort is missing', async (t) => { - await withSiteBuilder('site-with-framework-and-no-command', async (builder) => { - await builder.withNetlifyToml({ config: { dev: { framework: '#custom' } } }).buildAsync() + await withSiteBuilder(t, async (builder) => { + await builder.withNetlifyToml({ config: { dev: { framework: '#custom' } } }).build() const error = await withDevServer( { cwd: builder.directory, args: ['--command', 'echo hello'] }, @@ -186,8 +166,8 @@ describe.concurrent('frameworks/framework-detection', () => { }) test('should start custom command if framework=#custom, command and targetPort are configured', async (t) => { - await withSiteBuilder('site-with-custom-framework', async (builder) => { - await builder.withNetlifyToml({ config: { dev: { framework: '#custom', publish: 'public' } } }).buildAsync() + await withSiteBuilder(t, async (builder) => { + await builder.withNetlifyToml({ config: { dev: { framework: '#custom', publish: 'public' } } }).build() const error = await withDevServer( { cwd: builder.directory, args: ['--command', 'echo hello', '--target-port', '3000'] }, @@ -199,8 +179,8 @@ describe.concurrent('frameworks/framework-detection', () => { }) test(`should print specific error when command doesn't exist`, async (t) => { - await withSiteBuilder('site-with-custom-framework', async (builder) => { - await builder.buildAsync() + await withSiteBuilder(t, async (builder) => { + await builder.build() const error = await withDevServer( { @@ -223,7 +203,7 @@ describe.concurrent('frameworks/framework-detection', () => { }) test('should prompt when multiple frameworks are detected', async (t) => { - await withSiteBuilder('site-with-multiple-frameworks', async (builder) => { + await withSiteBuilder(t, async (builder) => { await builder .withPackageJson({ packageJson: { @@ -232,7 +212,7 @@ describe.concurrent('frameworks/framework-detection', () => { }, }) .withContentFile({ path: 'gatsby-config.js', content: '' }) - .buildAsync() + .build() // a failure is expected since this is not a true framework project const asyncErrorBlock = async () => { @@ -257,7 +237,7 @@ describe.concurrent('frameworks/framework-detection', () => { }) test('should fail in CI when multiple frameworks are detected', async (t) => { - await withSiteBuilder('site-with-multiple-frameworks', async (builder) => { + await withSiteBuilder(t, async (builder) => { await builder .withPackageJson({ packageJson: { @@ -266,7 +246,7 @@ describe.concurrent('frameworks/framework-detection', () => { }, }) .withContentFile({ path: 'gatsby-config.js', content: '' }) - .buildAsync() + .build() // a failure is expected since this is not a true framework project const asyncErrorBlock = async () => { @@ -288,8 +268,8 @@ describe.concurrent('frameworks/framework-detection', () => { }) test('should not run framework detection if command and targetPort are configured', async (t) => { - await withSiteBuilder('site-with-hugo-config', async (builder) => { - await builder.withContentFile({ path: 'config.toml', content: '' }).buildAsync() + await withSiteBuilder(t, async (builder) => { + await builder.withContentFile({ path: 'config.toml', content: '' }).build() // a failure is expected since the command exits early const error = await withDevServer( @@ -303,7 +283,7 @@ describe.concurrent('frameworks/framework-detection', () => { }) test('should filter frameworks with no dev command', async (t) => { - await withSiteBuilder('site-with-gulp', async (builder) => { + await withSiteBuilder(t, async (builder) => { await builder .withContentFile({ path: 'index.html', @@ -312,19 +292,20 @@ describe.concurrent('frameworks/framework-detection', () => { .withPackageJson({ packageJson: { dependencies: { gulp: '1.0.0' } }, }) - .buildAsync() + .build() await withDevServer({ cwd: builder.directory }, async ({ output, url }) => { - const response = await fetch(url).then((res) => res.text()) - t.expect(response).toEqual(content) + const response = await fetch(url) + const responseContent = await response.text() + t.expect(responseContent).toEqual(content) t.expect(normalize(output, { duration: true, filePath: true })).toMatchSnapshot() }) }) }) test('should pass framework-info env to framework sub process', async (t) => { - await withSiteBuilder('site-with-gatsby', async (builder) => { + await withSiteBuilder(t, async (builder) => { await builder .withPackageJson({ packageJson: { @@ -332,7 +313,7 @@ describe.concurrent('frameworks/framework-detection', () => { scripts: { dev: 'node -p process.env.NODE_VERSION' }, }, }) - .buildAsync() + .build() // a failure is expected since this is not a true Gatsby project const error = await withDevServer({ cwd: builder.directory }, () => {}, true).catch((error_) => error_) @@ -341,8 +322,8 @@ describe.concurrent('frameworks/framework-detection', () => { }) test('should start static service for frameworks without port, forced framework', async (t) => { - await withSiteBuilder('site-with-remix', async (builder) => { - await builder.withNetlifyToml({ config: { dev: { framework: 'remix' } } }).buildAsync() + await withSiteBuilder(t, async (builder) => { + await builder.withNetlifyToml({ config: { dev: { framework: 'remix' } } }).build() // a failure is expected since this is not a true remix project const error = await withDevServer({ cwd: builder.directory }, () => {}, true).catch((error_) => error_) @@ -351,7 +332,7 @@ describe.concurrent('frameworks/framework-detection', () => { }) test('should start static service for frameworks without port, detected framework', async (t) => { - await withSiteBuilder('site-with-remix', async (builder) => { + await withSiteBuilder(t, async (builder) => { await builder .withPackageJson({ packageJson: { @@ -360,7 +341,7 @@ describe.concurrent('frameworks/framework-detection', () => { }, }) .withContentFile({ path: 'remix.config.js', content: '' }) - .buildAsync() + .build() // a failure is expected since this is not a true remix project const error = await withDevServer({ cwd: builder.directory }, () => {}, true).catch((error_) => error_) @@ -369,7 +350,7 @@ describe.concurrent('frameworks/framework-detection', () => { }) test('should run and serve a production build when using the `serve` command', async (t) => { - await withSiteBuilder('site-with-framework', async (builder) => { + await withSiteBuilder(t, async (builder) => { await builder .withNetlifyToml({ config: { @@ -405,13 +386,14 @@ describe.concurrent('frameworks/framework-detection', () => { }, }, }) - .buildAsync() + .build() await withDevServer( { cwd: builder.directory, context: null, debug: true, serve: true }, async ({ output, url }) => { - const response = await fetch(`${url}/hello`).then((res) => res.json()) - t.expect(response).toStrictEqual({ CONTEXT_CHECK: 'PRODUCTION' }) + const response = await fetch(`${url}/hello`) + const responseJson = await response.json() + t.expect(responseJson).toStrictEqual({ CONTEXT_CHECK: 'PRODUCTION' }) const normalizedText = normalize(output, { duration: true, filePath: true }) t.expect( diff --git a/tests/integration/utils/site-builder.ts b/tests/integration/utils/site-builder.ts index 3a126a2242b..4e719618d5f 100644 --- a/tests/integration/utils/site-builder.ts +++ b/tests/integration/utils/site-builder.ts @@ -11,13 +11,14 @@ import tomlify from 'tomlify-j0.4' import { v4 as uuidv4 } from 'uuid' import type { TaskContext } from 'vitest' -const ensureDir = (file) => mkdir(file, { recursive: true }) +const ensureDir = (directory: string) => mkdir(directory, { recursive: true }) type Task = () => Promise export class SiteBuilder { tasks: Task[] = [] + // eslint-disable-next-line no-useless-constructor constructor(public readonly directory: string) {} ensureDirectoryExists(directory: string) { @@ -273,13 +274,6 @@ export class SiteBuilder { return this } - - /** - * @deprecated - */ - async cleanupAsync() { - return this.cleanup() - } } export const createSiteBuilder = ({ siteName }: { siteName: string }) => { diff --git a/tests/unit/utils/headers.test.js b/tests/unit/utils/headers.test.js index 75c2a306bce..e2d13f82800 100644 --- a/tests/unit/utils/headers.test.js +++ b/tests/unit/utils/headers.test.js @@ -73,13 +73,13 @@ describe('_headers', () => { `, }) - await builder.buildAsync() + await builder.build() context.builder = builder }) afterEach(async (context) => { - await context.builder.cleanupAsync() + await context.builder.cleanup() }) test('syntax validates as expected', async (context) => {