Repository: sveltejs/kit
Pull request #7696 (2022-11-16 23:50:08)

[chore] upgrade to playwright 1.28.1
the main issue was that checking the stack trace is unreliable

I also changed the test code to ensure we await the console log

https://github.com/microsoft/playwright/issues/18865 has now been fixed, which was causing across-the-board failures in 1.28.0

the lint failure is unrelated: https://github.com/sveltejs/kit/pull/7820#issuecomment-1328272412

changeset-bot[bot]: ###  ⚠️  No Changeset found

Latest commit: 7cdd16ac6918193d6494dda2809ade23914100eb

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.**

<details><summary>This PR includes no changesets</summary>

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

</details>

[Click here to learn what changesets are, and how to add one](https://github.com/changesets/changesets/blob/master/docs/adding-a-changeset.md).

[Click here if you're a maintainer who wants to add a changeset to this PR](https://github.com/benmccann/kit/new/playwright-1.28?filename=.changeset/weak-snails-stare.md&value=---%0A%22create-svelte%22%3A%20patch%0A%22%40sveltejs%2Fkit%22%3A%20patch%0A---%0A%0A%5Bchore%5D%20upgrade%20to%20playwright%201.28.0%0A)


dominikg: triggered a rerun on the mac fail
benmccann: Same failure as https://github.com/sveltejs/kit/pull/7435:

>@sveltejs/kit:test:   1 failed
@sveltejs/kit:test:     [webkit-dev] › test/client.test.js:610:3 › Load › using window.fetch causes a warning ==========

It seems the webkit version has not been able to capture the console logs
Conduitry: IIRC, the stack trace check in `fetcher.js` was written that way so as to avoid giving false positives for the warning when a `fetch` happened to be called when a `load` was running but was not actually called by that `load`. Do we really need to lose that heuristic? Have you ever observed that fail when running an app for real, or just in the tests? If at all possible, I'd much rather have imperfect tests than a flawed feature that we can more easily test.
benmccann: Thanks. I updated it to keep the stack trace and added a comment explaining what it's doing. It appears to be passing still

Patch:
diff --git a/.changeset/nine-rivers-argue.md b/.changeset/nine-rivers-argue.md
new file mode 100644
index 000000000..95182b40c
--- /dev/null
+++ b/.changeset/nine-rivers-argue.md
@@ -0,0 +1,5 @@
+---
+'create-svelte': patch
+---
+
+Upgrade to Playwright 1.28.1
diff --git a/.changeset/pre.json b/.changeset/pre.json
index 3f125e210..d322ccd48 100644
--- a/.changeset/pre.json
+++ b/.changeset/pre.json
@@ -182,6 +182,7 @@
     "clever-geckos-confess",
     "clever-lizards-grab",
     "clever-pillows-sing",
+    "clever-pillows-turn",
     "clever-readers-turn",
     "clever-shrimps-whisper",
     "clever-students-report",
@@ -1028,6 +1029,7 @@
     "rotten-tips-teach",
     "rotten-trees-brush",
     "rotten-wasps-beam",
+    "rude-actors-serve",
     "rude-balloons-return",
     "rude-berries-rush",
     "rude-buttons-bathe",
diff --git a/documentation/docs/30-advanced/40-service-workers.md b/documentation/docs/30-advanced/40-service-workers.md
index 0af6e9598..783312217 100644
--- a/documentation/docs/30-advanced/40-service-workers.md
+++ b/documentation/docs/30-advanced/40-service-workers.md
@@ -4,11 +4,88 @@ title: Service workers
 
 Service workers act as proxy servers that handle network requests inside your app. This makes it possible to make your app work offline, but even if you don't need offline support (or can't realistically implement it because of the type of app you're building), it's often worth using service workers to speed up navigation by precaching your built JS and CSS.
 
-In SvelteKit, if you have a `src/service-worker.js` file (or `src/service-worker.ts`, or `src/service-worker/index.js`, etc) it will be built with Vite and automatically registered. You can disable automatic registration if you need to register the service worker with your own logic (e.g. prompt user for update, configure periodic updates, use `workbox`, etc).
+In SvelteKit, if you have a `src/service-worker.js` file (or `src/service-worker.ts`, `src/service-worker/index.js`, etc) it will be bundled and automatically registered. You can change the [location of your service worker](/docs/configuration#files) if you need to.
 
-> You can change the [location of your service worker](/docs/configuration#files) and [disable automatic registration](/docs/configuration#serviceworker) in your project configuration.
+You can [disable automatic registration](/docs/configuration#serviceworker) if you need to register the service worker with your own logic or use another solution. The default registration looks something like this:
 
-Inside the service worker you have access to the [`$service-worker` module](/docs/modules#$service-worker). If your Vite config specifies `define`, this will be applied to service workers as well as your server/client builds.
+```js
+if ('serviceWorker' in navigator) {
+	addEventListener('load', function () {
+		navigator.serviceWorker.register('./path/to/service-worker.js');
+	});
+}
+```
+
+Inside the service worker you have access to the [`$service-worker` module](/docs/modules#$service-worker), which provides you with the paths to all static assets, build files and prerendered pages. You're also provided with an app version string which you can use for creating a unique cache name. If your Vite config specifies `define` (used for global variable replacements), this will be applied to service workers as well as your server/client builds.
+
+The following example caches the built app and any files in `static` eagerly, and caches all other requests as they happen. This would make each page work offline once visited.
+
+```js
+// @ts-nocheck Official TS Service Worker typings are still a work in progress.
+import { build, files, version } from '$service-worker';
+
+// Create a unique cache name for this deployment
+const CACHE = `cache-${version}`;
+
+const ASSETS = [
+	...build, // the app itself
+	...files  // everything in `static`
+];
+
+self.addEventListener('install', (event) => {
+	// Create a new cache and add all files to it
+	async function addFilesToCache() {
+		const cache = await caches.open(CACHE);
+		await cache.addAll(ASSETS);
+	}
+
+	event.waitUntil(addFilesToCache());
+});
+
+self.addEventListener('activate', (event) => {
+	// Remove previous cached data from disk
+	async function deleteOldCaches() {
+		for (const key of await caches.keys()) {
+			if (key !== CACHE) await caches.delete(key);
+		}
+	}
+
+	event.waitUntil(deleteOldCaches());
+});
+
+self.addEventListener('fetch', (event) => {
+	// ignore POST requests etc
+	if (event.request.method !== 'GET') return;
+
+	async function respond() {
+		const url = new URL(event.request.url);
+		const cache = await caches.open(CACHE);
+
+		// `build`/`files` can always be served from the cache
+		if (ASSETS.includes(url.pathname)) {
+			return cache.match(event.request);
+		}
+
+		// for everything else, try the network first, but
+		// fall back to the cache if we're offline
+		try {
+			const response = await fetch(event.request);
+
+			if (response.status === 200) {
+				cache.put(response.clone());
+			}
+
+			return response;
+		} catch {
+			return cache.match(event.request);
+		}
+	}
+
+	event.respondWith(respond());
+});
+```
+
+> Be careful when caching! In some cases, stale data might be worse than data that's unavailable while offline. Since browsers will empty caches if they get too full, you should also be careful about caching large assets like video files.
 
 The service worker is bundled for production, but not during development. For that reason, only browsers that support [modules in service workers](https://web.dev/es-modules-in-sw) will be able to use them at dev time. If you are manually registering your service worker, you will need to pass the `{ type: 'module' }` option in development:
 
@@ -18,4 +95,8 @@ import { dev } from '$app/environment';
 navigator.serviceWorker.register('/service-worker.js', {
 	type: dev ? 'module' : 'classic'
 });
-```
\ No newline at end of file
+```
+
+> `build` and `prerendered` are empty arrays during development
+
+SvelteKit's service worker implementation is deliberately low-level. If you need a more full-flegded but also more opinionated solution, we recommend looking at solutions like [Vite PWA plugin](https://vite-pwa-org.netlify.app/frameworks/sveltekit.html), which uses [Workbox](https://web.dev/learn/pwa/workbox). For more general information on service workers, we recommend [the MDN web docs](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers).
diff --git a/package.json b/package.json
index a0db35cd1..92185bfe9 100644
--- a/package.json
+++ b/package.json
@@ -27,7 +27,7 @@
 		"@rollup/plugin-json": "^5.0.1",
 		"@rollup/plugin-node-resolve": "^15.0.1",
 		"@svitejs/changesets-changelog-github-compact": "^0.1.1",
-		"playwright": "1.25.0",
+		"playwright": "^1.28.1",
 		"prettier": "^2.7.1",
 		"rollup": "^2.79.1",
 		"svelte": "^3.52.0",
diff --git a/packages/create-svelte/package.json b/packages/create-svelte/package.json
index 3094834ca..1be40da7a 100644
--- a/packages/create-svelte/package.json
+++ b/packages/create-svelte/package.json
@@ -15,7 +15,7 @@
 		"prompts": "^2.4.2"
 	},
 	"devDependencies": {
-		"@playwright/test": "1.25.0",
+		"@playwright/test": "^1.28.1",
 		"@sveltejs/kit": "workspace:*",
 		"@types/gitignore-parser": "^0.0.0",
 		"@types/prettier": "^2.7.1",
diff --git a/packages/kit/CHANGELOG.md b/packages/kit/CHANGELOG.md
index dec87978d..2f971ec44 100644
--- a/packages/kit/CHANGELOG.md
+++ b/packages/kit/CHANGELOG.md
@@ -1,5 +1,13 @@
 # @sveltejs/kit
 
+## 1.0.0-next.564
+
+### Patch Changes
+
+- [chore] upgrade undici ([#7830](https://github.com/sveltejs/kit/pull/7830))
+
+- Make `$page.url` resilient against mutations ([#7827](https://github.com/sveltejs/kit/pull/7827))
+
 ## 1.0.0-next.563
 
 ### Patch Changes
diff --git a/packages/kit/package.json b/packages/kit/package.json
index 3c1826b2e..ea23e8a9d 100644
--- a/packages/kit/package.json
+++ b/packages/kit/package.json
@@ -1,6 +1,6 @@
 {
 	"name": "@sveltejs/kit",
-	"version": "1.0.0-next.563",
+	"version": "1.0.0-next.564",
 	"repository": {
 		"type": "git",
 		"url": "https://github.com/sveltejs/kit",
@@ -24,7 +24,7 @@
 		"undici": "5.13.0"
 	},
 	"devDependencies": {
-		"@playwright/test": "1.25.0",
+		"@playwright/test": "^1.28.1",
 		"@types/connect": "^3.4.35",
 		"@types/marked": "^4.0.7",
 		"@types/mime": "^3.0.1",
diff --git a/packages/kit/src/runtime/client/fetcher.js b/packages/kit/src/runtime/client/fetcher.js
index 552bae15e..31cf15678 100644
--- a/packages/kit/src/runtime/client/fetcher.js
+++ b/packages/kit/src/runtime/client/fetcher.js
@@ -26,7 +26,12 @@ if (import.meta.env.DEV) {
 		const url = input instanceof Request ? input.url : input.toString();
 		const stack = /** @type {string} */ (new Error().stack);
 
-		const heuristic = can_inspect_stack_trace ? stack.includes('load_node') : loading;
+		// check if fetch was called via load_node. the lock method only checks if it was called at the
+		// same time, but not necessarily if it was called from `load`
+		// we use just the filename as the method name sometimes does not appear on the CI
+		const heuristic = can_inspect_stack_trace
+			? stack.includes('src/runtime/client/client.js')
+			: loading;
 		if (heuristic) {
 			console.warn(
 				`Loading ${url} using \`window.fetch\`. For best results, use the \`fetch\` that is passed to your \`load\` function: https://kit.svelte.dev/docs/load#making-fetch-requests`
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 4eac67c0b..2ac513e1f 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -9,7 +9,7 @@ importers:
       '@rollup/plugin-json': ^5.0.1
       '@rollup/plugin-node-resolve': ^15.0.1
       '@svitejs/changesets-changelog-github-compact': ^0.1.1
-      playwright: 1.25.0
+      playwright: ^1.28.1
       prettier: ^2.7.1
       rollup: ^2.79.1
       svelte: ^3.52.0
@@ -22,7 +22,7 @@ importers:
       '@rollup/plugin-json': 5.0.1_rollup@2.79.1
       '@rollup/plugin-node-resolve': 15.0.1_rollup@2.79.1
       '@svitejs/changesets-changelog-github-compact': 0.1.1
-      playwright: 1.25.0
+      playwright: 1.28.1
       prettier: 2.7.1
       rollup: 2.79.1
       svelte: 3.53.1
@@ -199,7 +199,7 @@ importers:
 
   packages/create-svelte:
     specifiers:
-      '@playwright/test': 1.25.0
+      '@playwright/test': ^1.28.1
       '@sveltejs/kit': workspace:*
       '@types/gitignore-parser': ^0.0.0
       '@types/prettier': ^2.7.1
@@ -218,7 +218,7 @@ importers:
       kleur: 4.1.5
       prompts: 2.4.2
     devDependencies:
-      '@playwright/test': 1.25.0
+      '@playwright/test': 1.28.1
       '@sveltejs/kit': link:../kit
       '@types/gitignore-parser': 0.0.0
       '@types/prettier': 2.7.1
@@ -261,7 +261,7 @@ importers:
 
   packages/kit:
     specifiers:
-      '@playwright/test': 1.25.0
+      '@playwright/test': ^1.28.1
       '@sveltejs/vite-plugin-svelte': ^1.3.1
       '@types/connect': ^3.4.35
       '@types/cookie': ^0.5.1
@@ -301,7 +301,7 @@ importers:
       tiny-glob: 0.2.9
       undici: 5.13.0
     devDependencies:
-      '@playwright/test': 1.25.0
+      '@playwright/test': 1.28.1
       '@types/connect': 3.4.35
       '@types/marked': 4.0.7
       '@types/mime': 3.0.1
@@ -1059,13 +1059,13 @@ packages:
       fastq: 1.13.0
     dev: true
 
-  /@playwright/test/1.25.0:
-    resolution: {integrity: sha512-j4EZhTTQI3dBeWblE21EV//swwmBtOpIrLdOIJIRv4uqsLdHgBg1z+JtTg+AeC5o2bAXIE26kDNW5A0TimG8Bg==}
+  /@playwright/test/1.28.1:
+    resolution: {integrity: sha512-xN6spdqrNlwSn9KabIhqfZR7IWjPpFK1835tFNgjrlysaSezuX8PYUwaz38V/yI8TJLG9PkAMEXoHRXYXlpTPQ==}
     engines: {node: '>=14'}
     hasBin: true
     dependencies:
       '@types/node': 18.11.9
-      playwright-core: 1.25.0
+      playwright-core: 1.28.1
     dev: true
 
   /@polka/url/1.0.0-next.21:
@@ -3395,19 +3395,19 @@ packages:
       find-up: 4.1.0
     dev: true
 
-  /playwright-core/1.25.0:
-    resolution: {integrity: sha512-kZ3Jwaf3wlu0GgU0nB8UMQ+mXFTqBIFz9h1svTlNduNKjnbPXFxw7mJanLVjqxHJRn62uBfmgBj93YHidk2N5Q==}
+  /playwright-core/1.28.1:
+    resolution: {integrity: sha512-3PixLnGPno0E8rSBJjtwqTwJe3Yw72QwBBBxNoukIj3lEeBNXwbNiKrNuB1oyQgTBw5QHUhNO3SteEtHaMK6ag==}
     engines: {node: '>=14'}
     hasBin: true
     dev: true
 
-  /playwright/1.25.0:
-    resolution: {integrity: sha512-Z+pQNWI17Qx/tHhnmgMmPsptsisXpKgAnUvYv98kctlHUJaqMt2400P8kTw9vEPoC0xdxqu0JhxO7pDTmaaIKw==}
+  /playwright/1.28.1:
+    resolution: {integrity: sha512-92Sz6XBlfHlb9tK5UCDzIFAuIkHHpemA9zwUaqvo+w7sFMSmVMGmvKcbptof/eJObq63PGnMhM75x7qxhTR78Q==}
     engines: {node: '>=14'}
     hasBin: true
     requiresBuild: true
     dependencies:
-      playwright-core: 1.25.0
+      playwright-core: 1.28.1
     dev: true
 
   /polka/1.0.0-next.22:
diff --git a/turbo.json b/turbo.json
index 7c05925f5..5557ded45 100644
--- a/turbo.json
+++ b/turbo.json
@@ -30,6 +30,9 @@
 		"check": {
 			"dependsOn": ["prepare"],
 			"inputs": [
+				"index.js",
+				"index.d.ts",
+				"ambient.d.ts",
 				"src/**",
 				"types/**",
 				".svelte-kit/types/**",


Test patch:
diff --git a/packages/kit/test/apps/basics/test/client.test.js b/packages/kit/test/apps/basics/test/client.test.js
index 0e6a69c45..8d3c917f7 100644
--- a/packages/kit/test/apps/basics/test/client.test.js
+++ b/packages/kit/test/apps/basics/test/client.test.js
@@ -608,24 +608,28 @@ test.describe('Load', () => {
 
 	if (process.env.DEV) {
 		test('using window.fetch causes a warning', async ({ page, baseURL }) => {
+			await Promise.all([
+				page.goto('/load/window-fetch/incorrect'),
+				page.waitForEvent('console', {
+					predicate: (message) => {
+						return (
+							message.text() ===
+							`Loading ${baseURL}/load/window-fetch/data.json using \`window.fetch\`. For best results, use the \`fetch\` that is passed to your \`load\` function: https://kit.svelte.dev/docs/load#making-fetch-requests`
+						);
+					},
+					timeout: 3_000
+				})
+			]);
+			expect(await page.textContent('h1')).toBe('42');
+
 			/** @type {string[]} */
 			const warnings = [];
-
 			page.on('console', (msg) => {
 				if (msg.type() === 'warning') {
 					warnings.push(msg.text());
 				}
 			});
 
-			await page.goto('/load/window-fetch/incorrect');
-			expect(await page.textContent('h1')).toBe('42');
-
-			expect(warnings).toContain(
-				`Loading ${baseURL}/load/window-fetch/data.json using \`window.fetch\`. For best results, use the \`fetch\` that is passed to your \`load\` function: https://kit.svelte.dev/docs/load#making-fetch-requests`
-			);
-
-			warnings.length = 0;
-
 			await page.goto('/load/window-fetch/correct');
 			expect(await page.textContent('h1')).toBe('42');