Skip to content

chore: run the basics server tests against Server.respond - #16872

Open
Nic-Polumeyv wants to merge 3 commits into
head-no-bodyfrom
server-respond-tests
Open

chore: run the basics server tests against Server.respond#16872
Nic-Polumeyv wants to merge 3 commits into
head-no-bodyfrom
server-respond-tests

Conversation

@Nic-Polumeyv

@Nic-Polumeyv Nic-Polumeyv commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

The server tests in basics never needed a browser: they assert on status, headers and body. Running them through Playwright with JavaScript off meant a preview server and a browser per project, repeated in every no-js leg of the matrix, and a 1 to 2 minute loop to run one of them locally. The file said so itself (server.test.js:33, "this would ideally be a unit test of Server").

They now run under vitest from unit-test/server.spec.js, calling the built app's Server.respond directly with no HTTP in between. With KIT_TEST_DEV set the same file goes through Vite's dev server in middleware mode instead, so both modes keep their coverage. The suite runs from the app's own test:dev and test:build after Playwright, against the build Playwright already made, so nothing builds twice and the unit job is untouched. 13 tests stay in Playwright because they assert what vite preview and the dev server do around Server (static assets, prerendered output).

Stacked on #17036: three of the moved HEAD tests need it in build mode.

@pkg-svelte-dev

pkg-svelte-dev Bot commented Aug 20, 2026

Copy link
Copy Markdown

Install the latest version of @sveltejs/kit from f03dc93:

pnpm add https://pkg.svelte.dev/@sveltejs/kit/c/f03dc93598c42b55ecb312e95a62838115842985

Open in pkg.svelte.dev: https://pkg.svelte.dev/repos/kit/pr/16872

@changeset-bot

changeset-bot Bot commented Aug 20, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: f03dc93

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@svelte-docs-bot

Copy link
Copy Markdown

@Rich-Harris

Copy link
Copy Markdown
Member

Noodling on some tweaks in #16879. One thing neither PR covers AFAICT: the existing setup tests the dev server as well as the prod build, but this only tests the latter IIUC?

@Nic-Polumeyv

Nic-Polumeyv commented Aug 20, 2026

Copy link
Copy Markdown
Contributor Author

Dev is back on 535985a, a second vitest project runs the same spec through Vite in middleware mode. 79 build / 67 dev, 12 skipped where Playwright skipped them too.

@coderabbitai

coderabbitai Bot commented Sep 4, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: QUIET

Plan: Advanced

Run ID: 8b913ef6-90e7-4c59-ba51-2be30837fbb5

📥 Commits

Reviewing files that changed from the base of the PR and between 12b6716 and f03dc93.

📒 Files selected for processing (1)
  • packages/kit/src/exports/node/index.spec.js
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • sveltejs/vite-plugin-svelte (manual)
  • vitejs/vite (manual)
  • sveltejs/svelte (manual)

Included review availability: Your plan provides up to 10 included reviews per hour; 3 remain after this review.


📝 Walkthrough

Walkthrough

The basics application now runs a dedicated server-side Vitest suite in development and build modes. The suite covers server requests, errors, routing, cookies, rerouting, tracing, asset preloading, workers, and streaming. Shared helpers read error and trace records. The existing server test file retains selected coverage, and the client Vitest pattern excludes server tests. The Node response mock now tests invalid header handling.

Merge Risk: 🟡 Moderate · up to f03dc

The server-test migration may fail before executing because its configured environment is not declared, and cleanup can mask that failure. Resolve these test-run reliability issues before merging.

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title uses the required chore: prefix and clearly summarises the move of the basics server tests to Server.respond.
Backward Compatibility Impact Disclosure ✅ Passed No public interface breaking change is introduced. The PR changes test infrastructure, private test-basics scripts, test routes, and test helpers. packages/kit/test/apps/basics/package.json is pri…

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/kit/test/apps/basics/package.json (1)

11-12: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Make the build-mode server test self-contained.

When vitest.server.config.js runs without KIT_TEST_DEV, server.spec.js imports .svelte-kit/output/server/manifest.js and index.js. A standalone run can therefore fail because the Vitest configuration has no setup that creates the build. Add a dedicated server-test script that performs the test setup and pnpm build before Vitest. The Playwright && chain is normal fail-fast orchestration and does not require a separate correction.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: QUIET

Plan: Advanced

Run ID: c4e44b90-55b7-4e74-9920-948fba1f971d

📥 Commits

Reviewing files that changed from the base of the PR and between a2ba146 and cc5e1b8.

📒 Files selected for processing (11)
  • .changeset/quiet-heads-rest.md
  • packages/kit/src/runtime/server/index.js
  • packages/kit/test/apps/basics/package.json
  • packages/kit/test/apps/basics/src/routes/endpoint-output/fetch-asset/absolute/+server.js
  • packages/kit/test/apps/basics/src/routes/endpoint-output/head-write-error/+server.js
  • packages/kit/test/apps/basics/test/server.test.js
  • packages/kit/test/apps/basics/unit-test/server.spec.js
  • packages/kit/test/apps/basics/vite.config.js
  • packages/kit/test/apps/basics/vitest.server.config.js
  • packages/kit/test/records.js
  • packages/kit/test/utils.js
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • sveltejs/vite-plugin-svelte (manual)
  • vitejs/vite (manual)
  • sveltejs/svelte (manual)
💤 Files with no reviewable changes (3)
  • packages/kit/test/apps/basics/src/routes/endpoint-output/fetch-asset/absolute/+server.js
  • packages/kit/test/apps/basics/src/routes/endpoint-output/head-write-error/+server.js
  • packages/kit/test/apps/basics/test/server.test.js

Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review.

test: {
name: 'kit-basics-server',
// for DOMParser
environment: 'jsdom',

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

🔎 Supported by static analysis

🏁 Script executed:

#!/bin/bash
# Description: Check jsdom declarations, catalog entries and hoisting settings.
set -uo pipefail

echo '--- jsdom in any package.json ---'
fd -H -t f 'package.json' -E node_modules --exec rg -n '"jsdom"' {} \; -X true 2>/dev/null
fd -H -t f 'package.json' -E node_modules | while IFS= read -r f; do
  rg -n '"jsdom"' "$f" | sed "s|^|$f: |"
done

echo '--- catalog entries ---'
fd -H -t f 'pnpm-workspace.yaml' -E node_modules | while IFS= read -r f; do
  rg -n -A3 'jsdom|catalog' "$f" | head -50
done

echo '--- hoisting configuration ---'
fd -H -t f '.npmrc' -E node_modules | while IFS= read -r f; do
  echo "== $f"; cat "$f"
done

echo '--- other vitest configs that use jsdom ---'
rg -n --glob '!node_modules' "environment: '(jsdom|happy-dom)'"

Repository: sveltejs/kit

Length of output: 1265


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- test app package and Vitest config ---'
cat -n packages/kit/test/apps/basics/package.json
cat -n packages/kit/test/apps/basics/vitest.server.config.js

printf '%s\n' '--- DOMParser usage ---'
sed -n '85,115p' packages/kit/test/apps/basics/src/server.spec.js 2>/dev/null || \
sed -n '85,115p' packages/kit/test/apps/basics/server.spec.js 2>/dev/null || true

printf '%s\n' '--- workspace and package-manager settings ---'
cat -n pnpm-workspace.yaml | sed -n '1,115p'
find . -maxdepth 3 -name '.npmrc' -o -name 'pnpm-workspace.yaml' | sort

Repository: sveltejs/kit

Length of output: 6570


🤖 get_repo_knowledge executed:

get_repo_knowledge sveltejs/kit /tmp/coderabbit-repo-knowledge/sveltejs-kit-ab1bcef7

Length of output: 546


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- server test and lockfile importers ---'
cat -n packages/kit/test/apps/basics/unit-test/server.spec.js | sed -n '95,112p'
rg -n -A35 -B5 'test/apps/basics|test-basics|jsdom' pnpm-lock.yaml packages/kit/package.json packages/kit/test/apps/basics/package.json

printf '%s\n' '--- all workspace packages that declare jsdom ---'
rg -n -g 'package.json' '"jsdom"\s*:' .

Repository: sveltejs/kit

Length of output: 50368


🏁 Script executed (no clone):

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- Vitest package contract ---'
curl -fsSL https://registry.npmjs.org/vitest/4.1.10 | python3 -c '
import json, sys
p = json.load(sys.stdin)["versions"]["4.1.10"]
print(json.dumps({
  "version": p.get("version"),
  "dependencies": p.get("dependencies", {}),
  "peerDependencies": p.get("peerDependencies", {}),
  "peerDependenciesMeta": p.get("peerDependenciesMeta", {})
}, indent=2))
'

Length of output: 252


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- exact basics importer ---'
sed -n '859,901p' pnpm-lock.yaml

printf '%s\n' '--- exact Vitest package entries ---'
rg -n -A18 -B3 '^  vitest@4\.1\.10|^  vitest:' pnpm-lock.yaml | head -120

Repository: sveltejs/kit

Length of output: 3856


🌐 Web query:

Vitest 4.1 jsdom environment install jsdom package peer dependency documentation

💡 Result:

In Vitest 4.1, the jsdom environment is not included by default and must be installed as a separate development dependency [1][2][3]. To use the jsdom environment, you must install the jsdom package: npm install -D jsdom Once installed, you can configure Vitest to use it by setting the environment option in your configuration file [1][2]: // vitest.config.ts import { defineConfig } from 'vitest/config' export default defineConfig({ test: { environment: 'jsdom', }, }) If you are using TypeScript and want proper type support for the jsdom global, you should also add the following to your tsconfig.json [4]: { "compilerOptions": { "types": ["vitest/jsdom"] } } Vitest does not manage the jsdom package as a direct peer dependency that is automatically installed, though it does include logic to check for its presence and may prompt you to install it if it is missing when you first attempt to use the jsdom environment [5][3]. The jsdom package is used dynamically by Vitest to emulate the browser environment [1][6].

Citations:


Declare jsdom in the test-basics devDependencies.

Vitest does not include jsdom by default. This configuration selects the jsdom environment, and unit-test/server.spec.js calls new DOMParser(). Add "jsdom": "catalog:" to packages/kit/test/apps/basics/package.json; otherwise the suite can fail during environment setup.

@Nic-Polumeyv
Nic-Polumeyv changed the base branch from version-3 to head-no-body September 4, 2026 16:47

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

Quiet mode is enabled, so only the most important comments were posted inline. Other review comments are grouped below.

🟡 Other comments (1)
packages/kit/test/apps/basics/unit-test/server.spec.js-66-69 (1)

66-69: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Guard listener in afterAll so setup failures are not masked.

beforeAll can throw before line 38 or line 56, for example when the dynamic import of the built output at line 43 or line 44 fails. listener is then undefined, and line 68 throws TypeError: Cannot read properties of undefined. That second error hides the real setup failure.

🐛 Proposed fix
 afterAll(async () => {
 	await vite?.close();
-	await new Promise((resolve) => listener.close(resolve));
+	if (listener) await new Promise((resolve) => listener.close(resolve));
 });
🧹 Nitpick comments (2)
packages/kit/test/apps/basics/unit-test/server.spec.js (2)

97-102: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Cap the redirect loop in load.

The loop follows redirects without a limit. If a fixture ever returns a redirect cycle, the test hangs until the Vitest timeout and reports no useful cause. Add a small cap and fail with an explicit message.

♻️ Proposed refactor
+	let redirects = 0;
 	while (response.status >= 300 && response.status < 400) {
+		if (++redirects > 10) throw new Error(`too many redirects from ${pathname}`);
 		const location = /** `@type` {string} */ (response.headers.get('location'));
 		const redirected = new URL(location, origin + pathname);
 
 		response = await get(redirected.pathname + redirected.search, init);
 	}

838-848: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Reject the promise when the raw http.get request fails.

The promise settles only in the end handler. If the request emits error, or the response never ends, the promise never settles. The test then hangs until the Vitest timeout without the underlying error. Attach an error handler that rejects.

♻️ Proposed refactor
-		const html = await new Promise((fulfil) => {
-			http.get(
+		const html = await new Promise((fulfil, reject) => {
+			const req = http.get(
 				`${origin}/load/fetch-request-headers`,
 				{ headers: { accept: '*/*', 'user-agent': 'node' } },
 				(res) => {
 					let body = '';
 					res.on('data', (chunk) => (body += chunk));
 					res.on('end', () => fulfil(body));
+					res.on('error', reject);
 				}
 			);
+			req.on('error', reject);
 		});

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: QUIET

Plan: Advanced

Run ID: 3aa70f18-e3b9-4fc9-8840-e5dae98a2a3d

📥 Commits

Reviewing files that changed from the base of the PR and between cc5e1b8 and 7b36829.

📒 Files selected for processing (1)
  • packages/kit/test/apps/basics/unit-test/server.spec.js
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • sveltejs/vite-plugin-svelte (manual)
  • vitejs/vite (manual)
  • sveltejs/svelte (manual)

Included review availability: Your plan provides up to 10 included reviews per hour; 7 remain after this review.

Co-authored-by: Rich Harris <rich.harris@vercel.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants