Add prettier. Format.
This commit is contained in:
@@ -1,92 +1,157 @@
|
||||
import { expect, test } from '@playwright/test'
|
||||
import { expect, test } from "@playwright/test";
|
||||
|
||||
const iphoneUserAgent = 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_5 like Mac OS X) AppleWebKit/605.1.15 Version/18.5 Mobile/15E148 Safari/604.1'
|
||||
const iphoneUserAgent =
|
||||
"Mozilla/5.0 (iPhone; CPU iPhone OS 18_5 like Mac OS X) AppleWebKit/605.1.15 Version/18.5 Mobile/15E148 Safari/604.1";
|
||||
|
||||
async function dispatchTouchStart(page: import('@playwright/test').Page, clientX: number) {
|
||||
return await page.locator('.nvr-navigator').evaluate((element, x) => {
|
||||
const event = new Event('touchstart', { bubbles: true, cancelable: true })
|
||||
Object.defineProperty(event, 'touches', {
|
||||
async function dispatchTouchStart(
|
||||
page: import("@playwright/test").Page,
|
||||
clientX: number,
|
||||
) {
|
||||
return await page.locator(".nvr-navigator").evaluate((element, x) => {
|
||||
const event = new Event("touchstart", { bubbles: true, cancelable: true });
|
||||
Object.defineProperty(event, "touches", {
|
||||
value: [{ identifier: 7, clientX: x, clientY: 240 }],
|
||||
})
|
||||
return { dispatched: element.dispatchEvent(event), prevented: event.defaultPrevented }
|
||||
}, clientX)
|
||||
});
|
||||
return {
|
||||
dispatched: element.dispatchEvent(event),
|
||||
prevented: event.defaultPrevented,
|
||||
};
|
||||
}, clientX);
|
||||
}
|
||||
|
||||
test('ships an installable standalone manifest and iOS metadata', async ({ page, request }) => {
|
||||
await page.goto('/inbox')
|
||||
await expect(page.locator('meta[name="apple-mobile-web-app-capable"]')).toHaveAttribute('content', 'yes')
|
||||
await expect(page.locator('meta[name="apple-mobile-web-app-status-bar-style"]')).toHaveAttribute('content', 'black-translucent')
|
||||
const touchIconPath = await page.locator('link[rel="apple-touch-icon"]').evaluate((link) =>
|
||||
new URL(link.getAttribute('href') ?? '', document.baseURI).pathname,
|
||||
)
|
||||
expect(touchIconPath).toBe('/apple-touch-icon.png')
|
||||
test("ships an installable standalone manifest and iOS metadata", async ({
|
||||
page,
|
||||
request,
|
||||
}) => {
|
||||
await page.goto("/inbox");
|
||||
await expect(
|
||||
page.locator('meta[name="apple-mobile-web-app-capable"]'),
|
||||
).toHaveAttribute("content", "yes");
|
||||
await expect(
|
||||
page.locator('meta[name="apple-mobile-web-app-status-bar-style"]'),
|
||||
).toHaveAttribute("content", "black-translucent");
|
||||
const touchIconPath = await page
|
||||
.locator('link[rel="apple-touch-icon"]')
|
||||
.evaluate(
|
||||
(link) =>
|
||||
new URL(link.getAttribute("href") ?? "", document.baseURI).pathname,
|
||||
);
|
||||
expect(touchIconPath).toBe("/apple-touch-icon.png");
|
||||
|
||||
const manifestResponse = await request.get('/manifest.webmanifest')
|
||||
expect(manifestResponse.ok()).toBe(true)
|
||||
const manifest = await manifestResponse.json()
|
||||
expect(manifest).toMatchObject({ id: '/', scope: '/', start_url: '/', display: 'standalone' })
|
||||
expect(manifest.icons).toEqual(expect.arrayContaining([
|
||||
expect.objectContaining({ src: '/pwa-192.png', sizes: '192x192', type: 'image/png' }),
|
||||
expect.objectContaining({ src: '/pwa-512.png', sizes: '512x512', type: 'image/png' }),
|
||||
]))
|
||||
expect((await request.get('/apple-touch-icon.png')).headers()['content-type']).toContain('image/png')
|
||||
const workerResponse = await request.get('/sw.js')
|
||||
expect(workerResponse.ok()).toBe(true)
|
||||
expect(workerResponse.headers()['cache-control']).toContain('no-cache')
|
||||
const worker = await workerResponse.text()
|
||||
expect(worker).toContain('self.skipWaiting()')
|
||||
expect(worker).toContain('clientsClaim()')
|
||||
})
|
||||
const manifestResponse = await request.get("/manifest.webmanifest");
|
||||
expect(manifestResponse.ok()).toBe(true);
|
||||
const manifest = await manifestResponse.json();
|
||||
expect(manifest).toMatchObject({
|
||||
id: "/",
|
||||
scope: "/",
|
||||
start_url: "/",
|
||||
display: "standalone",
|
||||
});
|
||||
expect(manifest.icons).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
src: "/pwa-192.png",
|
||||
sizes: "192x192",
|
||||
type: "image/png",
|
||||
}),
|
||||
expect.objectContaining({
|
||||
src: "/pwa-512.png",
|
||||
sizes: "512x512",
|
||||
type: "image/png",
|
||||
}),
|
||||
]),
|
||||
);
|
||||
expect(
|
||||
(await request.get("/apple-touch-icon.png")).headers()["content-type"],
|
||||
).toContain("image/png");
|
||||
const workerResponse = await request.get("/sw.js");
|
||||
expect(workerResponse.ok()).toBe(true);
|
||||
expect(workerResponse.headers()["cache-control"]).toContain("no-cache");
|
||||
const worker = await workerResponse.text();
|
||||
expect(worker).toContain("self.skipWaiting()");
|
||||
expect(worker).toContain("clientsClaim()");
|
||||
});
|
||||
|
||||
test('does not interfere with Safari edge touches before Home Screen installation', async ({ page }) => {
|
||||
test("does not interfere with Safari edge touches before Home Screen installation", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.addInitScript((userAgent) => {
|
||||
Object.defineProperty(navigator, 'userAgent', { configurable: true, value: userAgent })
|
||||
Object.defineProperty(navigator, 'standalone', { configurable: true, value: false })
|
||||
}, iphoneUserAgent)
|
||||
await page.goto('/chat/maya')
|
||||
await expect(page.locator('html')).toHaveAttribute('data-pwa-display-mode', 'browser')
|
||||
await expect(page.locator('html')).toHaveAttribute('data-pwa-edge-guard', 'inactive')
|
||||
expect((await dispatchTouchStart(page, 1)).prevented).toBe(false)
|
||||
})
|
||||
Object.defineProperty(navigator, "userAgent", {
|
||||
configurable: true,
|
||||
value: userAgent,
|
||||
});
|
||||
Object.defineProperty(navigator, "standalone", {
|
||||
configurable: true,
|
||||
value: false,
|
||||
});
|
||||
}, iphoneUserAgent);
|
||||
await page.goto("/chat/maya");
|
||||
await expect(page.locator("html")).toHaveAttribute(
|
||||
"data-pwa-display-mode",
|
||||
"browser",
|
||||
);
|
||||
await expect(page.locator("html")).toHaveAttribute(
|
||||
"data-pwa-edge-guard",
|
||||
"inactive",
|
||||
);
|
||||
expect((await dispatchTouchStart(page, 1)).prevented).toBe(false);
|
||||
});
|
||||
|
||||
test('reserves only the leading edge in an installed iOS PWA', async ({ page }) => {
|
||||
test("reserves only the leading edge in an installed iOS PWA", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.addInitScript((userAgent) => {
|
||||
Object.defineProperty(navigator, 'userAgent', { configurable: true, value: userAgent })
|
||||
Object.defineProperty(navigator, 'standalone', { configurable: true, value: true })
|
||||
}, iphoneUserAgent)
|
||||
await page.goto('/chat/maya')
|
||||
const root = page.locator('html')
|
||||
await expect(root).toHaveAttribute('data-pwa-platform', 'ios')
|
||||
await expect(root).toHaveAttribute('data-pwa-display-mode', 'standalone')
|
||||
await expect(root).toHaveAttribute('data-pwa-edge-guard', 'active')
|
||||
Object.defineProperty(navigator, "userAgent", {
|
||||
configurable: true,
|
||||
value: userAgent,
|
||||
});
|
||||
Object.defineProperty(navigator, "standalone", {
|
||||
configurable: true,
|
||||
value: true,
|
||||
});
|
||||
}, iphoneUserAgent);
|
||||
await page.goto("/chat/maya");
|
||||
const root = page.locator("html");
|
||||
await expect(root).toHaveAttribute("data-pwa-platform", "ios");
|
||||
await expect(root).toHaveAttribute("data-pwa-display-mode", "standalone");
|
||||
await expect(root).toHaveAttribute("data-pwa-edge-guard", "active");
|
||||
|
||||
expect((await dispatchTouchStart(page, 80)).prevented).toBe(false)
|
||||
expect((await dispatchTouchStart(page, 1)).prevented).toBe(true)
|
||||
await expect(root).toHaveAttribute('data-pwa-edge-claims', '1')
|
||||
})
|
||||
expect((await dispatchTouchStart(page, 80)).prevented).toBe(false);
|
||||
expect((await dispatchTouchStart(page, 1)).prevented).toBe(true);
|
||||
await expect(root).toHaveAttribute("data-pwa-edge-claims", "1");
|
||||
});
|
||||
|
||||
test('registers and activates the offline service worker', async ({ page }) => {
|
||||
await page.goto('/inbox')
|
||||
test("registers and activates the offline service worker", async ({ page }) => {
|
||||
await page.goto("/inbox");
|
||||
const workerUrl = await page.evaluate(async () => {
|
||||
const registration = await navigator.serviceWorker.ready
|
||||
return registration.active?.scriptURL ?? ''
|
||||
})
|
||||
expect(workerUrl).toMatch(/\/sw\.js$/)
|
||||
await expect(page.locator('html')).not.toHaveAttribute('data-pwa-update-checks', '0')
|
||||
})
|
||||
const registration = await navigator.serviceWorker.ready;
|
||||
return registration.active?.scriptURL ?? "";
|
||||
});
|
||||
expect(workerUrl).toMatch(/\/sw\.js$/);
|
||||
await expect(page.locator("html")).not.toHaveAttribute(
|
||||
"data-pwa-update-checks",
|
||||
"0",
|
||||
);
|
||||
});
|
||||
|
||||
test('precaches lazily split routes for offline navigation', async ({ page }) => {
|
||||
await page.goto('/inbox')
|
||||
await page.evaluate(async () => { await navigator.serviceWorker.ready })
|
||||
test("precaches lazily split routes for offline navigation", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.goto("/inbox");
|
||||
await page.evaluate(async () => {
|
||||
await navigator.serviceWorker.ready;
|
||||
});
|
||||
const cachedUrls = await page.evaluate(async () => {
|
||||
const urls: string[] = []
|
||||
const urls: string[] = [];
|
||||
for (const name of await caches.keys()) {
|
||||
const cache = await caches.open(name)
|
||||
urls.push(...(await cache.keys()).map((request) => request.url))
|
||||
const cache = await caches.open(name);
|
||||
urls.push(...(await cache.keys()).map((request) => request.url));
|
||||
}
|
||||
return urls
|
||||
})
|
||||
expect(cachedUrls.some((url) => /StoriesView-.*\.js$/.test(url))).toBe(true)
|
||||
expect(cachedUrls.some((url) => /ProfileView-.*\.js$/.test(url))).toBe(true)
|
||||
expect(cachedUrls.some((url) => /RuntimeLabView-.*\.js$/.test(url))).toBe(true)
|
||||
})
|
||||
return urls;
|
||||
});
|
||||
expect(cachedUrls.some((url) => /StoriesView-.*\.js$/.test(url))).toBe(true);
|
||||
expect(cachedUrls.some((url) => /ProfileView-.*\.js$/.test(url))).toBe(true);
|
||||
expect(cachedUrls.some((url) => /RuntimeLabView-.*\.js$/.test(url))).toBe(
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user