如何通过修改HTTP响应来触发剧作家中的服务工作者更新?
我正在为我最近添加了一个服务工作者的水疗中心工作,该水疗中心使用缓存优先策略预先插入了应用程序外壳,并使用网络 - firt策略来缓存导航请求。
该水疗中心包含一些显示“新版本可用的逻辑!”当它检测到“等待”服务工作者时,页面顶部的“重新加载”按钮的横幅。我想为此逻辑编写端到端测试,以及“重新加载”按钮背后的逻辑,但无法弄清楚如何触发剧作家中的服务工作者更新。
我一直使用的方法是在安装服务工作者并触发页面重新加载后修改服务工作者的响应。我可以修改响应及其响应标头,但它不会在浏览器中触发更新事件。
这是测试代码:
test("shows an update button when the service worker file has changed", async ({
page,
context
}, testInfo) => {
const newScriptBytes = "/*test*/"
const timeout = testInfo.timeout
await page.goto("/")
await waitForReadyServiceWorker({ context, page, timeout })
// change the bytes of all additional service worker requests
await page.route("/service-worker.js", async route => {
const serverResponse = await page.request.fetch(serviceWorkerUrl, {
ignoreHTTPSErrors: true
})
let serviceWorkerScript = await serverResponse.text()
serviceWorkerScript = serviceWorkerScript.concat(newScriptBytes)
await route.fulfill({
response: serverResponse,
body: serviceWorkerScript,
headers: {
...serverResponse.headers(),
"Etag": "v1",
"Last-Modified": new Date().toUTCString(),
"Content-Length": serviceWorkerScript.length.toString()
}
})
})
await page.reload()
await expect(
page.locator(`text=A new version is available!`)
).toBeVisible()
})
export async function waitForReadyServiceWorker(args: {
context: BrowserContext
page: Page
timeout?: number
}): Promise<Worker | undefined> {
const timeoutId = createOperationTimeout(args.timeout)
const url = await args.page.evaluate(async () => {
const readySw = await navigator.serviceWorker.ready
return readySw.active.scriptURL
})
clearTimeout(timeoutId)
return args.context.serviceWorkers().find(worker => worker.url() === url)
}
这是初始服务工作者响应
这是修改后的服务工作者响应
I am working on an SPA that I recently added a service worker to, which pre-caches the application shell using a cache-first strategy and caches navigation requests using a network -first strategy.
The SPA contains some logic that displays a "A new version is available!" banner with a "Reload" button at the top of the page when it detects a "waiting" service worker. I would like to write an end-to-end test for this logic and the logic behind the "Reload" button but cannot figure out how to trigger a service worker update in Playwright.
The approach that I have been playing with is modifying the service worker response after the service worker has been installed and a page reload has been triggered. I can modify the response and its response headers but it is not triggering an update event in the browser.
Here is the test code:
test("shows an update button when the service worker file has changed", async ({
page,
context
}, testInfo) => {
const newScriptBytes = "/*test*/"
const timeout = testInfo.timeout
await page.goto("/")
await waitForReadyServiceWorker({ context, page, timeout })
// change the bytes of all additional service worker requests
await page.route("/service-worker.js", async route => {
const serverResponse = await page.request.fetch(serviceWorkerUrl, {
ignoreHTTPSErrors: true
})
let serviceWorkerScript = await serverResponse.text()
serviceWorkerScript = serviceWorkerScript.concat(newScriptBytes)
await route.fulfill({
response: serverResponse,
body: serviceWorkerScript,
headers: {
...serverResponse.headers(),
"Etag": "v1",
"Last-Modified": new Date().toUTCString(),
"Content-Length": serviceWorkerScript.length.toString()
}
})
})
await page.reload()
await expect(
page.locator(`text=A new version is available!`)
).toBeVisible()
})
export async function waitForReadyServiceWorker(args: {
context: BrowserContext
page: Page
timeout?: number
}): Promise<Worker | undefined> {
const timeoutId = createOperationTimeout(args.timeout)
const url = await args.page.evaluate(async () => {
const readySw = await navigator.serviceWorker.ready
return readySw.active.scriptURL
})
clearTimeout(timeoutId)
return args.context.serviceWorkers().find(worker => worker.url() === url)
}
Here is the initial service worker response
Here is the modified service worker response
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论