diff --git a/packages/kit/test/apps/amp/test/test.js b/packages/kit/test/apps/amp/test/test.js index e3a0b6007a32..759481f966b9 100644 --- a/packages/kit/test/apps/amp/test/test.js +++ b/packages/kit/test/apps/amp/test/test.js @@ -47,7 +47,7 @@ test('only includes CSS for rendered components', async ({ page, baseURL }) => { test('http-equiv tags are removed', async ({ page }) => { await page.goto('/http-equiv/cache-control'); - expect(await page.textContent('h1')).toBe( + await expect(page.locator('h1')).toHaveText( 'the cache-control headers should be removed from this page' ); expect(await page.innerHTML('head')).not.toContain('http-equiv="cache-control"'); @@ -67,7 +67,7 @@ test.skip('prints validation errors', async ({ page, baseURL }) => { test.skip('throws error on encountering stylesheet links', async ({ page }) => { await page.goto('/invalid/has-stylesheet'); - expect(await page.textContent('body')).toContain( + await expect(page.locator('body')).toContainText( 'An AMP document cannot contain — ensure that inlineStyleThreshold is set to Infinity, and remove links from your page template and elements' ); }); diff --git a/packages/kit/test/apps/basics/test/client.test.js b/packages/kit/test/apps/basics/test/client.test.js index 350d91d0fbb3..aeabdcb921cc 100644 --- a/packages/kit/test/apps/basics/test/client.test.js +++ b/packages/kit/test/apps/basics/test/client.test.js @@ -44,48 +44,48 @@ test.describe('Load', () => { test('load function is only called when necessary', async ({ app, page }) => { test.slow(); await page.goto('/load/change-detection/one/a'); - expect(await page.textContent('h1')).toBe('layout loads: 1'); - expect(await page.textContent('h2')).toBe('x: a: 1'); + await expect(page.locator('h1')).toHaveText('layout loads: 1'); + await expect(page.locator('h2')).toHaveText('x: a: 1'); await app.goto('/load/change-detection/one/a?unused=whatever'); - expect(await page.textContent('h2')).toBe('x: a: 1'); + await expect(page.locator('h2')).toHaveText('x: a: 1'); await app.goto('/load/change-detection/two/b'); - expect(await page.textContent('h2')).toBe('y: b: 1'); + await expect(page.locator('h2')).toHaveText('y: b: 1'); await app.goto('/load/change-detection/one/a'); - expect(await page.textContent('h2')).toBe('x: a: 2'); + await expect(page.locator('h2')).toHaveText('x: a: 2'); await app.goto('/load/change-detection/one/b'); - expect(await page.textContent('h2')).toBe('x: b: 3'); + await expect(page.locator('h2')).toHaveText('x: b: 3'); await app.invalidate('/load/change-detection/data.json'); - expect(await page.textContent('h1')).toBe('layout loads: 2'); - expect(await page.textContent('h2')).toBe('x: b: 3'); + await expect(page.locator('h1')).toHaveText('layout loads: 2'); + await expect(page.locator('h2')).toHaveText('x: b: 3'); await app.invalidate('/load/change-detection/data.json'); - expect(await page.textContent('h1')).toBe('layout loads: 3'); - expect(await page.textContent('h2')).toBe('x: b: 3'); + await expect(page.locator('h1')).toHaveText('layout loads: 3'); + await expect(page.locator('h2')).toHaveText('x: b: 3'); await app.invalidate('custom:change-detection-layout'); - expect(await page.textContent('h1')).toBe('layout loads: 4'); - expect(await page.textContent('h2')).toBe('x: b: 3'); + await expect(page.locator('h1')).toHaveText('layout loads: 4'); + await expect(page.locator('h2')).toHaveText('x: b: 3'); await page.click('button:has-text("invalidate change-detection/data.json")'); await page.waitForFunction('window.invalidated'); - expect(await page.textContent('h1')).toBe('layout loads: 5'); - expect(await page.textContent('h2')).toBe('x: b: 3'); + await expect(page.locator('h1')).toHaveText('layout loads: 5'); + await expect(page.locator('h2')).toHaveText('x: b: 3'); await page.click('button:has-text("invalidate all")'); await page.waitForFunction('window.invalidated'); - expect(await page.textContent('h1')).toBe('layout loads: 6'); - expect(await page.textContent('h2')).toBe('x: b: 4'); + await expect(page.locator('h1')).toHaveText('layout loads: 6'); + await expect(page.locator('h2')).toHaveText('x: b: 4'); }); if (process.env.DEV) { test('accessing url.hash from load errors and suggests using page state', async ({ page }) => { await page.goto('/load/url-hash#please-dont-send-me-to-load'); - expect(await page.textContent('#message')).toBe( + await expect(page.locator('#message')).toHaveText( 'This is your custom error page saying: "Cannot access event.url.hash. Consider using `page.url.hash` inside a component instead (500 Internal Error)"' ); }); @@ -93,7 +93,7 @@ test.describe('Load', () => { test('url instance methods work in load', async ({ page }) => { await page.goto('/load/url-to-string'); - expect(await page.textContent('h1')).toBe("I didn't break!"); + await expect(page.locator('h1')).toHaveText("I didn't break!"); }); test('server data from previous is not reused if next page has no load function', async ({ @@ -101,14 +101,14 @@ test.describe('Load', () => { app }) => { await page.goto('/load/server-data-reuse/with-server-load'); - expect(await page.textContent('pre')).toBe( + await expect(page.locator('pre')).toHaveText( JSON.stringify({ foo: { bar: 'Custom layout' }, server: true }) ); await app.goto('/load/server-data-reuse/no-load'); - expect(await page.textContent('pre')).toBe(JSON.stringify({ foo: { bar: 'Custom layout' } })); + await expect(page.locator('pre')).toHaveText(JSON.stringify({ foo: { bar: 'Custom layout' } })); await page.goto('/load/server-data-reuse/with-changing-parent/with-server-load'); - expect(await page.textContent('pre')).toBe( + await expect(page.locator('pre')).toHaveText( JSON.stringify({ foo: { bar: 'Custom layout' }, title: '/load/server-data-reuse/with-changing-parent/with-server-load', @@ -116,7 +116,7 @@ test.describe('Load', () => { }) ); await app.goto('/load/server-data-reuse/with-changing-parent/no-load'); - expect(await page.textContent('pre')).toBe( + await expect(page.locator('pre')).toHaveText( JSON.stringify({ foo: { bar: 'Custom layout' }, title: '/load/server-data-reuse/with-changing-parent/no-load' @@ -130,20 +130,20 @@ test.describe('Load', () => { }) => { await page.goto('/load/url-query-param'); - expect(await page.textContent('h1')).toBe('Hello '); - expect(await page.textContent('p')).toBe('This text comes from the server load function'); + await expect(page.locator('h1')).toHaveText('Hello '); + await expect(page.locator('p')).toHaveText('This text comes from the server load function'); await clicknav('a[href="/load/url-query-param?currentClientState=ABC"]'); - expect(await page.textContent('h1')).toBe('Hello ABC'); - expect(await page.textContent('p')).toBe('This text comes from the server load function'); + await expect(page.locator('h1')).toHaveText('Hello ABC'); + await expect(page.locator('p')).toHaveText('This text comes from the server load function'); await clicknav('a[href="/load/url-query-param?currentClientState=DEF"]'); - expect(await page.textContent('h1')).toBe('Hello DEF'); - expect(await page.textContent('p')).toBe('This text comes from the server load function'); + await expect(page.locator('h1')).toHaveText('Hello DEF'); + await expect(page.locator('p')).toHaveText('This text comes from the server load function'); await clicknav('a[href="/load/url-query-param"]'); - expect(await page.textContent('h1')).toBe('Hello '); - expect(await page.textContent('p')).toBe('This text comes from the server load function'); + await expect(page.locator('h1')).toHaveText('Hello '); + await expect(page.locator('p')).toHaveText('This text comes from the server load function'); }); test('load does not call fetch if max-age allows it', async ({ page }) => { @@ -198,8 +198,8 @@ test.describe('Load', () => { test('cache with body hash', async ({ page, clicknav }) => { // 1. go to the page (first load, we expect the right data) await page.goto('/load/fetch-cache-control/load-data'); - expect(await page.textContent('div#fr')).toBe(JSON.stringify({ hi: 'bonjour' })); - expect(await page.textContent('div#hu')).toBe(JSON.stringify({ hi: 'szia' })); + await expect(page.locator('div#fr')).toHaveText(JSON.stringify({ hi: 'bonjour' })); + await expect(page.locator('div#hu')).toHaveText(JSON.stringify({ hi: 'szia' })); // 2. change to another route (client side) await clicknav('[href="/load/fetch-cache-control"]'); @@ -214,8 +214,8 @@ test.describe('Load', () => { await clicknav('[href="/load/fetch-cache-control/load-data"]'); // 4. data should still be the same (and cached) - expect(await page.textContent('div#fr')).toBe(JSON.stringify({ hi: 'bonjour' })); - expect(await page.textContent('div#hu')).toBe(JSON.stringify({ hi: 'szia' })); + await expect(page.locator('div#fr')).toHaveText(JSON.stringify({ hi: 'bonjour' })); + await expect(page.locator('div#hu')).toHaveText(JSON.stringify({ hi: 'szia' })); expect(did_request_data).toBe(false); }); @@ -223,7 +223,7 @@ test.describe('Load', () => { await page.goto('/load/fetch-cache-control/headers-diff'); // 1. We expect the right data - expect(await page.textContent('h2')).toBe('a / b'); + await expect(page.locator('h2')).toHaveText('a / b'); // 2. Change to another route (client side) await clicknav('[href="/load/fetch-cache-control"]'); @@ -235,13 +235,13 @@ test.describe('Load', () => { await clicknav('[href="/load/fetch-cache-control/headers-diff"]'); // 4. We expect the same data and no new request (except a navigation request in case of server-side route resolution) because it was cached. - expect(await page.textContent('h2')).toBe('a / b'); + await expect(page.locator('h2')).toHaveText('a / b'); expect(requests.filter((r) => !r.includes('/__route.js'))).toEqual([]); }); test('use correct cache result when fetching same url multiple times', async ({ page }) => { await page.goto('/load/fetch-same-url'); - expect(await page.textContent('h1')).toBe('the result is 1,2,3'); + await expect(page.locator('h1')).toHaveText('the result is 1,2,3'); }); test('permits 3rd party patching of fetch in universal load functions', async ({ page }) => { @@ -254,7 +254,7 @@ test.describe('Load', () => { }); await page.goto('/load/window-fetch/patching'); - expect(await page.textContent('h1')).toBe('42'); + await expect(page.locator('h1')).toHaveText('42'); expect(logs).toContain('Called a patched window.fetch'); }); @@ -271,7 +271,7 @@ test.describe('Load', () => { await page.getByText('Go To Page with Server Load').click(); - expect(await page.textContent('h1')).toBe('server load data'); + await expect(page.locator('h1')).toHaveText('server load data'); expect(logs).toContain('Called a patched window.fetch for server load request'); }); @@ -305,7 +305,7 @@ test.describe('Load', () => { timeout: 3_000 }) ]); - expect(await page.textContent('h1')).toBe('42'); + await expect(page.locator('h1')).toHaveText('42'); /** @type {string[]} */ const warnings = []; @@ -316,7 +316,7 @@ test.describe('Load', () => { }); await page.goto('/load/window-fetch/correct'); - expect(await page.textContent('h1')).toBe('42'); + await expect(page.locator('h1')).toHaveText('42'); expect(warnings).not.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://svelte.dev/docs/kit/load#making-fetch-requests` @@ -517,12 +517,12 @@ test.describe('Invalidation', () => { clicknav }) => { await page.goto('/load/unchanged/isolated/a'); - expect(await page.textContent('h1')).toBe('slug: a'); - expect(await page.textContent('h2')).toBe('count: 0'); + await expect(page.locator('h1')).toHaveText('slug: a'); + await expect(page.locator('h2')).toHaveText('count: 0'); await clicknav('[href="/load/unchanged/isolated/b"]'); - expect(await page.textContent('h1')).toBe('slug: b'); - expect(await page.textContent('h2')).toBe('count: 0'); + await expect(page.locator('h1')).toHaveText('slug: b'); + await expect(page.locator('h2')).toHaveText('count: 0'); }); test('+layout.server.js re-runs when await parent() is called from downstream load function', async ({ @@ -530,27 +530,27 @@ test.describe('Invalidation', () => { clicknav }) => { await page.goto('/load/unchanged-parent/uses-parent/a'); - expect(await page.textContent('h1')).toBe('slug: a'); - expect(await page.textContent('h2')).toBe('count: 0'); - expect(await page.textContent('h3')).toBe('doubled: 0'); + await expect(page.locator('h1')).toHaveText('slug: a'); + await expect(page.locator('h2')).toHaveText('count: 0'); + await expect(page.locator('h3')).toHaveText('doubled: 0'); await clicknav('[href="/load/unchanged-parent/uses-parent/b"]'); - expect(await page.textContent('h1')).toBe('slug: b'); - expect(await page.textContent('h2')).toBe('count: 0'); + await expect(page.locator('h1')).toHaveText('slug: b'); + await expect(page.locator('h2')).toHaveText('count: 0'); // this looks wrong, but is actually the intended behaviour (the increment side-effect in a GET would be a bug in a real app) - expect(await page.textContent('h3')).toBe('doubled: 2'); + await expect(page.locator('h3')).toHaveText('doubled: 2'); }); test('load function re-runs when searchParams change', async ({ page, clicknav }) => { await page.goto('/load/invalidation/url?a=1'); - expect(await page.textContent('h1')).toBe('1'); + await expect(page.locator('h1')).toHaveText('1'); await clicknav('[href="?a=2"]'); - expect(await page.textContent('h1')).toBe('2'); + await expect(page.locator('h1')).toHaveText('2'); await clicknav('[href="?a=3"]'); - expect(await page.textContent('h1')).toBe('3'); + await expect(page.locator('h1')).toHaveText('3'); }); test('load function only re-runs when tracked searchParams change (universal)', async ({ @@ -558,11 +558,11 @@ test.describe('Invalidation', () => { clicknav }) => { await page.goto('/load/invalidation/search-params/universal?tracked=0'); - expect(await page.textContent('span')).toBe('count: 0'); + await expect(page.locator('span')).toHaveText('count: 0'); await clicknav('[data-id="tracked"]'); - expect(await page.textContent('span')).toBe('count: 1'); + await expect(page.locator('span')).toHaveText('count: 1'); await clicknav('[data-id="untracked"]'); - expect(await page.textContent('span')).toBe('count: 1'); + await expect(page.locator('span')).toHaveText('count: 1'); }); test('load function only re-runs when tracked searchParams change (server)', async ({ @@ -570,41 +570,41 @@ test.describe('Invalidation', () => { clicknav }) => { await page.goto('/load/invalidation/search-params/server?tracked=0'); - expect(await page.textContent('span')).toBe('count: 0'); + await expect(page.locator('span')).toHaveText('count: 0'); await clicknav('[data-id="tracked"]'); - expect(await page.textContent('span')).toBe('count: 1'); + await expect(page.locator('span')).toHaveText('count: 1'); await clicknav('[data-id="untracked"]'); - expect(await page.textContent('span')).toBe('count: 1'); + await expect(page.locator('span')).toHaveText('count: 1'); }); test('server-only load functions are re-run following forced invalidation', async ({ page }) => { await page.goto('/load/invalidation/forced'); - expect(await page.textContent('h1')).toBe('a: 0, b: 1'); + await expect(page.locator('h1')).toHaveText('a: 0, b: 1'); await page.click('button.invalidateall'); await page.evaluate( () => /** @type {Window & typeof globalThis & { promise: Promise }} */ (window).promise ); - expect(await page.textContent('h1')).toBe('a: 2, b: 3'); + await expect(page.locator('h1')).toHaveText('a: 2, b: 3'); await page.click('button.invalidateall'); await page.evaluate( () => /** @type {Window & typeof globalThis & { promise: Promise }} */ (window).promise ); - expect(await page.textContent('h1')).toBe('a: 4, b: 5'); + await expect(page.locator('h1')).toHaveText('a: 4, b: 5'); }); test('server-only load functions are re-run following goto with forced invalidation', async ({ page }) => { await page.goto('/load/invalidation/forced-goto'); - expect(await page.textContent('h1')).toBe('a: 0, b: 1'); + await expect(page.locator('h1')).toHaveText('a: 0, b: 1'); await page.click('button.goto'); await page.evaluate( () => /** @type {Window & typeof globalThis & { promise: Promise }} */ (window).promise ); - expect(await page.textContent('h1')).toBe('a: 2, b: 3'); + await expect(page.locator('h1')).toHaveText('a: 2, b: 3'); }); test('multiple invalidations run concurrently', async ({ page }) => { @@ -639,8 +639,8 @@ test.describe('Invalidation', () => { test('+layout(.server).js is re-run when server dep is invalidated', async ({ page }) => { await page.goto('/load/invalidation/depends'); - const server = await page.textContent('p.server'); - const shared = await page.textContent('p.shared'); + const server = await page.locator('p.server').textContent(); + const shared = await page.locator('p.shared').textContent(); expect(server).toBeDefined(); expect(shared).toBeDefined(); @@ -648,8 +648,8 @@ test.describe('Invalidation', () => { await page.evaluate( () => /** @type {Window & typeof globalThis & { promise: Promise }} */ (window).promise ); - const next_server = await page.textContent('p.server'); - const next_shared = await page.textContent('p.shared'); + const next_server = await page.locator('p.server').textContent(); + const next_shared = await page.locator('p.shared').textContent(); expect(server).not.toBe(next_server); expect(shared).not.toBe(next_shared); @@ -657,8 +657,8 @@ test.describe('Invalidation', () => { await page.evaluate( () => /** @type {Window & typeof globalThis & { promise: Promise }} */ (window).promise ); - expect(await page.textContent('p.server')).toBe(next_server); - expect(await page.textContent('p.shared')).toBe(next_shared); + await expect(page.locator('p.server')).toHaveText(next_server); + await expect(page.locator('p.shared')).toHaveText(next_shared); }); test('fetch in server load cannot be invalidated', async ({ page, app, request }) => { @@ -668,15 +668,15 @@ test.describe('Invalidation', () => { await page.goto('/load/invalidation/server-fetch'); const selector = '[data-testid="count"]'; - expect(await page.textContent(selector)).toBe('1'); + await expect(page.locator(selector)).toHaveText('1'); await app.invalidate('/load/invalidation/server-fetch/count.json'); - expect(await page.textContent(selector)).toBe('1'); + await expect(page.locator(selector)).toHaveText('1'); }); test('+layout.js is re-run when shared dep is invalidated', async ({ page }) => { await page.goto('/load/invalidation/depends'); - const server = await page.textContent('p.server'); - const shared = await page.textContent('p.shared'); + const server = await page.locator('p.server').textContent(); + const shared = await page.locator('p.shared').textContent(); expect(server).toBeDefined(); expect(shared).toBeDefined(); @@ -684,8 +684,8 @@ test.describe('Invalidation', () => { await page.evaluate( () => /** @type {Window & typeof globalThis & { promise: Promise }} */ (window).promise ); - const next_server = await page.textContent('p.server'); - const next_shared = await page.textContent('p.shared'); + const next_server = await page.locator('p.server').textContent(); + const next_shared = await page.locator('p.shared').textContent(); expect(server).toBe(next_server); expect(shared).not.toBe(next_shared); @@ -693,17 +693,17 @@ test.describe('Invalidation', () => { await page.evaluate( () => /** @type {Window & typeof globalThis & { promise: Promise }} */ (window).promise ); - expect(await page.textContent('p.server')).toBe(next_server); - expect(await page.textContent('p.shared')).toBe(next_shared); + await expect(page.locator('p.server')).toHaveText(next_server); + await expect(page.locator('p.shared')).toHaveText(next_shared); }); test('+page(.server).js is re-run when server dep is invalidated following goto', async ({ page }) => { await page.goto('/load/invalidation/depends-goto'); - const layout = await page.textContent('p.layout'); - const server = await page.textContent('p.server'); - const shared = await page.textContent('p.shared'); + const layout = await page.locator('p.layout').textContent(); + const server = await page.locator('p.server').textContent(); + const shared = await page.locator('p.shared').textContent(); expect(layout).toBeDefined(); expect(server).toBeDefined(); expect(shared).toBeDefined(); @@ -712,9 +712,9 @@ test.describe('Invalidation', () => { await page.evaluate( () => /** @type {Window & typeof globalThis & { promise: Promise }} */ (window).promise ); - const next_layout = await page.textContent('p.layout'); - const next_server = await page.textContent('p.server'); - const next_shared = await page.textContent('p.shared'); + const next_layout = await page.locator('p.layout').textContent(); + const next_server = await page.locator('p.server').textContent(); + const next_shared = await page.locator('p.shared').textContent(); expect(layout).toBe(next_layout); expect(server).not.toBe(next_server); expect(shared).not.toBe(next_shared); @@ -723,16 +723,16 @@ test.describe('Invalidation', () => { await page.evaluate( () => /** @type {Window & typeof globalThis & { promise: Promise }} */ (window).promise ); - expect(await page.textContent('p.layout')).toBe(next_layout); - expect(await page.textContent('p.server')).toBe(next_server); - expect(await page.textContent('p.shared')).toBe(next_shared); + await expect(page.locator('p.layout')).toHaveText(next_layout); + await expect(page.locator('p.server')).toHaveText(next_server); + await expect(page.locator('p.shared')).toHaveText(next_shared); }); test('+page.js is re-run when shared dep is invalidated following goto', async ({ page }) => { await page.goto('/load/invalidation/depends-goto'); - const layout = await page.textContent('p.layout'); - const server = await page.textContent('p.server'); - const shared = await page.textContent('p.shared'); + const layout = await page.locator('p.layout').textContent(); + const server = await page.locator('p.server').textContent(); + const shared = await page.locator('p.shared').textContent(); expect(layout).toBeDefined(); expect(server).toBeDefined(); expect(shared).toBeDefined(); @@ -741,9 +741,9 @@ test.describe('Invalidation', () => { await page.evaluate( () => /** @type {Window & typeof globalThis & { promise: Promise }} */ (window).promise ); - const next_layout = await page.textContent('p.layout'); - const next_server = await page.textContent('p.server'); - const next_shared = await page.textContent('p.shared'); + const next_layout = await page.locator('p.layout').textContent(); + const next_server = await page.locator('p.server').textContent(); + const next_shared = await page.locator('p.shared').textContent(); expect(layout).toBe(next_layout); expect(server).toBe(next_server); expect(shared).not.toBe(next_shared); @@ -752,16 +752,16 @@ test.describe('Invalidation', () => { await page.evaluate( () => /** @type {Window & typeof globalThis & { promise: Promise }} */ (window).promise ); - expect(await page.textContent('p.layout')).toBe(next_layout); - expect(await page.textContent('p.server')).toBe(next_server); - expect(await page.textContent('p.shared')).toBe(next_shared); + await expect(page.locator('p.layout')).toHaveText(next_layout); + await expect(page.locator('p.server')).toHaveText(next_server); + await expect(page.locator('p.shared')).toHaveText(next_shared); }); test('Specified dependencies are re-run following goto', async ({ page }) => { await page.goto('/load/invalidation/depends-goto'); - const layout = await page.textContent('p.layout'); - const server = await page.textContent('p.server'); - const shared = await page.textContent('p.shared'); + const layout = await page.locator('p.layout').textContent(); + const server = await page.locator('p.server').textContent(); + const shared = await page.locator('p.shared').textContent(); expect(layout).toBeDefined(); expect(server).toBeDefined(); expect(shared).toBeDefined(); @@ -770,9 +770,9 @@ test.describe('Invalidation', () => { await page.evaluate( () => /** @type {Window & typeof globalThis & { promise: Promise }} */ (window).promise ); - const next_layout = await page.textContent('p.layout'); - const next_server = await page.textContent('p.server'); - const next_shared = await page.textContent('p.shared'); + const next_layout = await page.locator('p.layout').textContent(); + const next_server = await page.locator('p.server').textContent(); + const next_shared = await page.locator('p.shared').textContent(); expect(layout).not.toBe(next_layout); expect(server).toBe(next_server); expect(shared).not.toBe(next_shared); @@ -781,9 +781,9 @@ test.describe('Invalidation', () => { await page.evaluate( () => /** @type {Window & typeof globalThis & { promise: Promise }} */ (window).promise ); - expect(await page.textContent('p.layout')).toBe(next_layout); - expect(await page.textContent('p.server')).toBe(next_server); - expect(await page.textContent('p.shared')).toBe(next_shared); + await expect(page.locator('p.layout')).toHaveText(next_layout); + await expect(page.locator('p.server')).toHaveText(next_server); + await expect(page.locator('p.shared')).toHaveText(next_shared); }); test('Parameter use is tracked even for routes that do not use the parameters', async ({ @@ -793,39 +793,39 @@ test.describe('Invalidation', () => { await page.goto('/load/invalidation/params'); await clicknav('[href="/load/invalidation/params/1"]'); - expect(await page.textContent('pre')).toBe('{"a":"1"}'); + await expect(page.locator('pre')).toHaveText('{"a":"1"}'); await clicknav('[href="/load/invalidation/params/1/x"]'); - expect(await page.textContent('pre')).toBe('{"a":"1","b":"x"}'); + await expect(page.locator('pre')).toHaveText('{"a":"1","b":"x"}'); await page.goBack(); - expect(await page.textContent('pre')).toBe('{"a":"1"}'); + await expect(page.locator('pre')).toHaveText('{"a":"1"}'); }); test('route.id use is tracked for server-only load functions', async ({ page, clicknav }) => { await page.goto('/load/invalidation/route/server/a'); - expect(await page.textContent('h1')).toBe('route.id: /load/invalidation/route/server/a'); + await expect(page.locator('h1')).toHaveText('route.id: /load/invalidation/route/server/a'); await clicknav('[href="/load/invalidation/route/server/b"]'); - expect(await page.textContent('h1')).toBe('route.id: /load/invalidation/route/server/b'); + await expect(page.locator('h1')).toHaveText('route.id: /load/invalidation/route/server/b'); }); test('route.id use is tracked for shared load functions', async ({ page, clicknav }) => { await page.goto('/load/invalidation/route/shared/a'); - expect(await page.textContent('h1')).toBe('route.id: /load/invalidation/route/shared/a'); + await expect(page.locator('h1')).toHaveText('route.id: /load/invalidation/route/shared/a'); await clicknav('[href="/load/invalidation/route/shared/b"]'); - expect(await page.textContent('h1')).toBe('route.id: /load/invalidation/route/shared/b'); + await expect(page.locator('h1')).toHaveText('route.id: /load/invalidation/route/shared/b'); }); test('route.id does not rerun layout if unchanged', async ({ page, clicknav }) => { await page.goto('/load/invalidation/route/shared/unchanged-x'); - expect(await page.textContent('h1')).toBe('route.id: /load/invalidation/route/shared/[x]'); - const id = await page.textContent('h2'); + await expect(page.locator('h1')).toHaveText('route.id: /load/invalidation/route/shared/[x]'); + const id = await page.locator('h2').textContent(); await clicknav('[href="/load/invalidation/route/shared/unchanged-y"]'); - expect(await page.textContent('h1')).toBe('route.id: /load/invalidation/route/shared/[x]'); - expect(await page.textContent('h2')).toBe(id); + await expect(page.locator('h1')).toHaveText('route.id: /load/invalidation/route/shared/[x]'); + await expect(page.locator('h2')).toHaveText(id); }); test('page.url can safely be mutated', async ({ page }) => { @@ -838,8 +838,8 @@ test.describe('Invalidation', () => { test('goto after invalidation does not reset state', async ({ page }) => { await page.goto('/load/invalidation/invalidate-then-goto'); - const layout = await page.textContent('p.layout'); - const _page = await page.textContent('p.page'); + const layout = await page.locator('p.layout').textContent(); + const _page = await page.locator('p.page').textContent(); expect(layout).toBeDefined(); expect(_page).toBeDefined(); @@ -847,8 +847,8 @@ test.describe('Invalidation', () => { await page.evaluate( () => /** @type {Window & typeof globalThis & { promise: Promise }} */ (window).promise ); - const next_layout_1 = await page.textContent('p.layout'); - const next_page_1 = await page.textContent('p.page'); + const next_layout_1 = await page.locator('p.layout').textContent(); + const next_page_1 = await page.locator('p.page').textContent(); expect(next_layout_1).not.toBe(layout); expect(next_page_1).toBe(_page); @@ -856,8 +856,8 @@ test.describe('Invalidation', () => { await page.evaluate( () => /** @type {Window & typeof globalThis & { promise: Promise }} */ (window).promise ); - const next_layout_2 = await page.textContent('p.layout'); - const next_page_2 = await page.textContent('p.page'); + const next_layout_2 = await page.locator('p.layout').textContent(); + const next_page_2 = await page.locator('p.page').textContent(); expect(next_layout_2).toBe(next_layout_1); expect(next_page_2).not.toBe(next_page_1); }); @@ -1165,7 +1165,7 @@ test.describe('Content negotiation', () => { const response = await page.goto('/routing/content-negotiation'); expect(response?.headers()['vary']).toBe('Accept'); - expect(await page.textContent('p')).toBe('Hi'); + await expect(page.locator('p')).toHaveText('Hi'); const pre = page.locator('pre'); for (const method of ['GET', 'PUT', 'PATCH', 'POST', 'DELETE']) { @@ -1518,20 +1518,20 @@ test.describe('goto', () => { test.describe('untrack', () => { test('untracks server load function', async ({ page, clicknav }) => { await page.goto('/untrack/server/1'); - expect(await page.textContent('p.url')).toBe('/untrack/server/1'); - const id = await page.textContent('p.id'); + await expect(page.locator('p.url')).toHaveText('/untrack/server/1'); + const id = await page.locator('p.id').textContent(); await clicknav('a[href="/untrack/server/2"]'); - expect(await page.textContent('p.url')).toBe('/untrack/server/2'); - expect(await page.textContent('p.id')).toBe(id); + await expect(page.locator('p.url')).toHaveText('/untrack/server/2'); + await expect(page.locator('p.id')).toHaveText(id); }); test('untracks universal load function', async ({ page, clicknav }) => { await page.goto('/untrack/universal/1'); - expect(await page.textContent('p.url')).toBe('/untrack/universal/1'); - const id = await page.textContent('p.id'); + await expect(page.locator('p.url')).toHaveText('/untrack/universal/1'); + const id = await page.locator('p.id').textContent(); await clicknav('a[href="/untrack/universal/2"]'); - expect(await page.textContent('p.url')).toBe('/untrack/universal/2'); - expect(await page.textContent('p.id')).toBe(id); + await expect(page.locator('p.url')).toHaveText('/untrack/universal/2'); + await expect(page.locator('p.id')).toHaveText(id); }); }); @@ -1652,7 +1652,7 @@ test.describe('reroute', () => { test('Apply reroute during client side navigation', async ({ page }) => { await page.goto('/reroute/basic'); await page.click("a[href='/reroute/basic/a']"); - expect(await page.textContent('h1')).toContain( + await expect(page.locator('h1')).toContainText( 'Successfully rewritten, URL should still show a: /reroute/basic/a' ); }); @@ -1663,7 +1663,7 @@ test.describe('reroute', () => { .addCookies([{ name: 'reroute-cookie', value: 'yes', path: '/', domain: 'localhost' }]); await page.goto('/reroute/async'); await page.click("a[href='/reroute/async/a']"); - expect(await page.textContent('h1')).toContain( + await expect(page.locator('h1')).toContainText( 'Successfully rewritten, URL should still show a: /reroute/async/a' ); }); @@ -1671,7 +1671,7 @@ test.describe('reroute', () => { test('Apply async prerendered reroute during client side navigation', async ({ page }) => { await page.goto('/reroute/async'); await page.click("a[href='/reroute/async/c']"); - expect(await page.textContent('h1')).toContain( + await expect(page.locator('h1')).toContainText( 'Successfully rewritten, URL should still show a: /reroute/async/c' ); }); @@ -1679,12 +1679,12 @@ test.describe('reroute', () => { test('Apply reroute to prerendered page during client side navigation', async ({ page }) => { await page.goto('/reroute/prerendered'); await page.click("a[href='/reroute/prerendered/to-destination']"); - expect(await page.textContent('h1')).toContain('reroute that points to prerendered page works'); + await expect(page.locator('h1')).toContainText('reroute that points to prerendered page works'); }); test('Apply reroute after client-only redirects', async ({ page }) => { await page.goto('/reroute/client-only-redirect'); - expect(await page.textContent('h1')).toContain('Successfully rewritten'); + await expect(page.locator('h1')).toContainText('Successfully rewritten'); }); test('Apply reroute to preload data', async ({ page }) => { @@ -1692,7 +1692,7 @@ test.describe('reroute', () => { await page.goto('/reroute/preload-data'); await page.click('button'); await page.waitForSelector('pre'); - expect(await page.textContent('pre')).toContain('"success": true'); + await expect(page.locator('pre')).toContainText('"success": true'); }); test('reroute does not get applied to external URLs', async ({ page }) => { @@ -1713,7 +1713,7 @@ test.describe('reroute', () => { //click the link with the text External URL await page.click('a#client-error'); - expect(await page.textContent('h1')).toContain('Full Navigation'); + await expect(page.locator('h1')).toContainText('Full Navigation'); }); test('reroute works with invalidate', async ({ page }) => { diff --git a/packages/kit/test/apps/basics/test/cross-platform/client.test.js b/packages/kit/test/apps/basics/test/cross-platform/client.test.js index 36b84c22eeb6..9dbf5fde7029 100644 --- a/packages/kit/test/apps/basics/test/cross-platform/client.test.js +++ b/packages/kit/test/apps/basics/test/cross-platform/client.test.js @@ -207,7 +207,7 @@ test.describe('Navigation lifecycle functions', () => { await page.click('a[href="#x"]'); await page.goBack(); - expect(await page.textContent('h1')).toBe('before_navigate_ran: false'); + await expect(page.locator('h1')).toHaveText('before_navigate_ran: false'); }); test('beforeNavigate cancel() on an unloading navigation does not prevent subsequent beforeNavigate callbacks', async ({ @@ -248,22 +248,22 @@ test.describe('Navigation lifecycle functions', () => { test('afterNavigate calls callback', async ({ page, clicknav }) => { await page.goto('/navigation-lifecycle/after-navigate/a'); - expect(await page.textContent('h1')).toBe( + await expect(page.locator('h1')).toHaveText( 'undefined -> /navigation-lifecycle/after-navigate/a' ); await clicknav('[href="/navigation-lifecycle/after-navigate/b"]'); - expect(await page.textContent('h1')).toBe( + await expect(page.locator('h1')).toHaveText( '/navigation-lifecycle/after-navigate/a -> /navigation-lifecycle/after-navigate/b' ); }); test('onNavigate calls callback', async ({ page, clicknav }) => { await page.goto('/navigation-lifecycle/on-navigate/a'); - expect(await page.textContent('h1')).toBe('undefined -> undefined (...) false'); + await expect(page.locator('h1')).toHaveText('undefined -> undefined (...) false'); await clicknav('[href="/navigation-lifecycle/on-navigate/b"]'); - expect(await page.textContent('h1')).toBe( + await expect(page.locator('h1')).toHaveText( '/navigation-lifecycle/on-navigate/a -> /navigation-lifecycle/on-navigate/b (link) true' ); }); @@ -273,7 +273,7 @@ test.describe('Navigation lifecycle functions', () => { await clicknav('[href="/navigation-lifecycle/after-navigate-properly-removed/a"]'); await clicknav('[href="/navigation-lifecycle/after-navigate-properly-removed/b"]'); - expect(await page.textContent('.nav-lifecycle-after-nav-removed-test-target')).toBe('false'); + await expect(page.locator('.nav-lifecycle-after-nav-removed-test-target')).toHaveText('false'); }); test('navigation.event is populated', async ({ page, clicknav }) => { @@ -414,15 +414,15 @@ test.describe('Scrolling', () => { await scroll_to(0, target_scroll_y); await page.locator('[href="/scroll/cross-document/b"]').click(); - expect(await page.textContent('h1')).toBe('b'); + await expect(page.locator('h1')).toHaveText('b'); await page.waitForSelector('body.started'); await clicknav('[href="/scroll/cross-document/c"]'); - expect(await page.textContent('h1')).toBe('c'); + await expect(page.locator('h1')).toHaveText('c'); await page.goBack(); // client-side back await page.goBack(); // native back - expect(await page.textContent('h1')).toBe('a'); + await expect(page.locator('h1')).toHaveText('a'); await page.waitForSelector('body.started'); await page.waitForTimeout(250); // needed for the test to fail reliably without the fix @@ -591,8 +591,8 @@ test.describe.serial('Errors', () => { test('client-side load errors', async ({ page }) => { await page.goto('/errors/load-client'); - expect(await page.textContent('footer')).toBe('Custom layout'); - expect(await page.textContent('#message')).toBe( + await expect(page.locator('footer')).toHaveText('Custom layout'); + await expect(page.locator('#message')).toHaveText( 'This is your custom error page saying: "Crashing now (500 Internal Error)"' ); }); @@ -600,8 +600,8 @@ test.describe.serial('Errors', () => { test('client-side module context errors', async ({ page }) => { await page.goto('/errors/module-scope-client'); - expect(await page.textContent('footer')).toBe('Custom layout'); - expect(await page.textContent('#message')).toBe( + await expect(page.locator('footer')).toHaveText('Custom layout'); + await expect(page.locator('#message')).toHaveText( 'This is your custom error page saying: "Crashing now (500 Internal Error)"' ); }); @@ -609,8 +609,8 @@ test.describe.serial('Errors', () => { test('client-side error from load()', async ({ page }) => { await page.goto('/errors/load-error-client'); - expect(await page.textContent('footer')).toBe('Custom layout'); - expect(await page.textContent('#message')).toBe( + await expect(page.locator('footer')).toHaveText('Custom layout'); + await expect(page.locator('#message')).toHaveText( 'This is your custom error page saying: "Not found"' ); expect(await page.innerHTML('h1')).toBe('555'); @@ -619,8 +619,8 @@ test.describe.serial('Errors', () => { test('client-side 4xx status without error from load()', async ({ page }) => { await page.goto('/errors/load-status-without-error-client'); - expect(await page.textContent('footer')).toBe('Custom layout'); - expect(await page.textContent('#message')).toBe( + await expect(page.locator('footer')).toHaveText('Custom layout'); + await expect(page.locator('#message')).toHaveText( 'This is your custom error page saying: "Error: 401"' ); expect(await page.innerHTML('h1')).toBe('401'); @@ -630,8 +630,8 @@ test.describe.serial('Errors', () => { await page.goto('/errors/error-html'); await clicknav('button:text-is("Unexpected")'); - expect(await page.textContent('h1')).toBe('Error - 500'); - expect(await page.textContent('p')).toBe( + await expect(page.locator('h1')).toHaveText('Error - 500'); + await expect(page.locator('p')).toHaveText( 'This is the static error page with the following message: Failed to load (500 Internal Error)' ); }); @@ -640,8 +640,8 @@ test.describe.serial('Errors', () => { await page.goto('/errors/error-html'); await clicknav('button:text-is("Expected")'); - expect(await page.textContent('h1')).toBe('Error - 401'); - expect(await page.textContent('p')).toBe( + await expect(page.locator('h1')).toHaveText('Error - 401'); + await expect(page.locator('p')).toHaveText( 'This is the static error page with the following message: Not allowed' ); }); @@ -785,7 +785,7 @@ test.describe('Routing', () => { page.on('request', (r) => requests.push(r.url())); await clicknav('a[href="/routing/a"]'); - expect(await page.textContent('h1')).toBe('a'); + await expect(page.locator('h1')).toHaveText('a'); expect(requests.filter((url) => !url.endsWith('/favicon.png'))).toEqual([]); }); @@ -793,28 +793,28 @@ test.describe('Routing', () => { test('navigates programmatically', async ({ page, app }) => { await page.goto('/routing/a'); await app.goto('/routing/b'); - expect(await page.textContent('h1')).toBe('b'); + await expect(page.locator('h1')).toHaveText('b'); }); test('page.url.hash is correctly set on page load', async ({ page }) => { await page.goto('/routing/hashes/pagestate#target'); - expect(await page.textContent('#window-hash')).toBe('#target'); - expect(await page.textContent('#page-url-hash')).toBe('#target'); + await expect(page.locator('#window-hash')).toHaveText('#target'); + await expect(page.locator('#page-url-hash')).toHaveText('#target'); }); test('page.url.hash is correctly set on navigation', async ({ page }) => { await page.goto('/routing/hashes/pagestate'); - expect(await page.textContent('#window-hash')).toBe(''); - expect(await page.textContent('#page-url-hash')).toBe(''); + await expect(page.locator('#window-hash')).toHaveText(''); + await expect(page.locator('#page-url-hash')).toHaveText(''); await page.locator('[href="#target"]').click(); - expect(await page.textContent('#window-hash')).toBe('#target'); - expect(await page.textContent('#page-url-hash')).toBe('#target'); + await expect(page.locator('#window-hash')).toHaveText('#target'); + await expect(page.locator('#page-url-hash')).toHaveText('#target'); await page.locator('[href="/routing/hashes/pagestate"]').click(); await expect(page.locator('#window-hash')).toHaveText('#target'); // hashchange doesn't fire for these await expect(page.locator('#page-url-hash')).toHaveText(''); await page.goBack(); - expect(await page.textContent('#window-hash')).toBe('#target'); - expect(await page.textContent('#page-url-hash')).toBe('#target'); + await expect(page.locator('#window-hash')).toHaveText('#target'); + await expect(page.locator('#page-url-hash')).toHaveText('#target'); }); test('clicking on a hash link focuses the associated element', async ({ page }) => { @@ -865,7 +865,7 @@ test.describe('Routing', () => { expect(page.url()).toBe(`${baseURL}/routing/hashes/a#hash-target`); await clicknav('[href="/routing/hashes/b"]'); - expect(await page.textContent('h1')).toBe('b'); + await expect(page.locator('h1')).toHaveText('b'); await expect(page.locator('h1')).toHaveText('b'); await page.goBack(); @@ -903,16 +903,16 @@ test.describe('Routing', () => { test('ignores popstate events from outside the router', async ({ page }) => { await page.goto('/routing/external-popstate'); - expect(await page.textContent('h1')).toBe('hello'); + await expect(page.locator('h1')).toHaveText('hello'); await page.locator('button').click(); - expect(await page.textContent('h1')).toBe('hello'); + await expect(page.locator('h1')).toHaveText('hello'); await page.goBack(); - expect(await page.textContent('h1')).toBe('hello'); + await expect(page.locator('h1')).toHaveText('hello'); await page.goForward(); - expect(await page.textContent('h1')).toBe('hello'); + await expect(page.locator('h1')).toHaveText('hello'); }); test('recognizes clicks outside the app target', async ({ page }) => { @@ -977,10 +977,10 @@ test.describe('Routing', () => { await page.goto('/routing/missing-href'); const selector = '[data-testid="count"]'; - expect(await page.textContent(selector)).toBe('count: 1'); + await expect(page.locator(selector)).toHaveText('count: 1'); await page.locator(selector).click(); - expect(await page.textContent(selector)).toBe('count: 1'); + await expect(page.locator(selector)).toHaveText('count: 1'); }); test('trailing slash redirect', async ({ page, clicknav }) => { @@ -1024,7 +1024,7 @@ test.describe('Shadow DOM', () => { page.on('request', (r) => requests.push(r.url())); await clicknav('div[id="clickme"]'); - expect(await page.textContent('h1')).toBe('a'); + await expect(page.locator('h1')).toHaveText('a'); expect(requests.filter((url) => !url.endsWith('/favicon.png'))).toEqual([]); }); @@ -1054,14 +1054,14 @@ test.describe('Interactivity', () => { }); await page.goto('/interactivity/toggle-element'); - expect(await page.textContent('button')).toBe('remove'); + await expect(page.locator('button')).toHaveText('remove'); await page.locator('button').click(); - expect(await page.textContent('button')).toBe('add'); - expect(await page.textContent('a')).toBe('add'); + await expect(page.locator('button')).toHaveText('add'); + await expect(page.locator('a')).toHaveText('add'); await page.locator('a').filter({ hasText: 'add' }).click(); - expect(await page.textContent('a')).toBe('remove'); + await expect(page.locator('a')).toHaveText('remove'); expect(errored).toBe(false); }); @@ -1079,7 +1079,7 @@ test.describe('Load', () => { }); await page.goto('/load/window-fetch/outside-load'); - expect(await page.textContent('h1')).toBe('42'); + await expect(page.locator('h1')).toHaveText('42'); expect(warnings).not.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://svelte.dev/docs/kit/load#making-fetch-requests` diff --git a/packages/kit/test/apps/basics/test/cross-platform/test.js b/packages/kit/test/apps/basics/test/cross-platform/test.js index c0e73da6df6c..76dca15443f4 100644 --- a/packages/kit/test/apps/basics/test/cross-platform/test.js +++ b/packages/kit/test/apps/basics/test/cross-platform/test.js @@ -63,19 +63,19 @@ test.describe('Shadowed pages', () => { test('Loads props from an endpoint', async ({ page, clicknav }) => { await page.goto('/shadowed'); await clicknav('[href="/shadowed/simple"]'); - expect(await page.textContent('h1')).toBe('The answer is 42'); + await expect(page.locator('h1')).toHaveText('The answer is 42'); }); test('Handles GET redirects', async ({ page, clicknav }) => { await page.goto('/shadowed'); await clicknav('[href="/shadowed/redirect-get"]'); - expect(await page.textContent('h1')).toBe('Redirection was successful'); + await expect(page.locator('h1')).toHaveText('Redirection was successful'); }); test('Handles GET redirects with cookies', async ({ page, context, clicknav }) => { await page.goto('/shadowed'); await clicknav('[href="/shadowed/redirect-get-with-cookie"]'); - expect(await page.textContent('h1')).toBe('Redirection was successful'); + await expect(page.locator('h1')).toHaveText('Redirection was successful'); const cookies = await context.cookies(); expect(cookies).toEqual( @@ -90,7 +90,7 @@ test.describe('Shadowed pages', () => { }) => { await page.goto('/shadowed'); await clicknav('[href="/shadowed/redirect-get-with-cookie-from-fetch"]'); - expect(await page.textContent('h1')).toBe('Redirection was successful'); + await expect(page.locator('h1')).toHaveText('Redirection was successful'); const cookies = await context.cookies(); expect(cookies).toEqual( @@ -103,13 +103,13 @@ test.describe('Shadowed pages', () => { test('Handles POST redirects', async ({ page, clicknav }) => { await page.goto('/shadowed'); await clicknav('#redirect-post'); - expect(await page.textContent('h1')).toBe('Redirection was successful'); + await expect(page.locator('h1')).toHaveText('Redirection was successful'); }); test('Handles POST redirects with cookies', async ({ page, context, clicknav }) => { await page.goto('/shadowed'); await clicknav('#redirect-post-with-cookie'); - expect(await page.textContent('h1')).toBe('Redirection was successful'); + await expect(page.locator('h1')).toHaveText('Redirection was successful'); const cookies = await context.cookies(); expect(cookies).toEqual( @@ -120,54 +120,56 @@ test.describe('Shadowed pages', () => { test('Handles POST success with returned location', async ({ page, clicknav }) => { await page.goto('/shadowed/post-success-redirect'); await clicknav('button'); - expect(await page.textContent('h1')).toBe('POST was successful'); + await expect(page.locator('h1')).toHaveText('POST was successful'); }); test('Renders error page for 4xx and 5xx responses from GET', async ({ page, clicknav }) => { await page.goto('/shadowed'); await clicknav('[href="/shadowed/error-get"]'); - expect(await page.textContent('h1')).toBe('404'); + await expect(page.locator('h1')).toHaveText('404'); }); test('Merges bodies for 4xx and 5xx responses from non-GET', async ({ page }) => { await page.goto('/shadowed'); const [response] = await Promise.all([page.waitForNavigation(), page.click('#error-post')]); - expect(await page.textContent('h1')).toBe('hello from get / echo: posted data'); + await expect(page.locator('h1')).toHaveText('hello from get / echo: posted data'); expect(response?.status()).toBe(400); - expect(await page.textContent('h2')).toBe('status: 400'); + await expect(page.locator('h2')).toHaveText('status: 400'); }); test('Endpoint receives consistent URL', async ({ baseURL, page, clicknav }) => { await page.goto('/shadowed/same-render-entry'); await clicknav('[href="/shadowed/same-render?param1=value1"]'); - expect(await page.textContent('h1')).toBe(`URL: ${baseURL}/shadowed/same-render?param1=value1`); + await expect(page.locator('h1')).toHaveText( + `URL: ${baseURL}/shadowed/same-render?param1=value1` + ); }); test('Works with missing get handler', async ({ page, clicknav }) => { await page.goto('/shadowed'); await clicknav('[href="/shadowed/no-get"]'); - expect(await page.textContent('h1')).toBe('hello'); + await expect(page.locator('h1')).toHaveText('hello'); }); test('Invalidates shadow data when URL changes', async ({ page, clicknav }) => { await page.goto('/shadowed'); await clicknav('[href="/shadowed/dynamic/foo"]'); - expect(await page.textContent('h1')).toBe('slug: foo'); + await expect(page.locator('h1')).toHaveText('slug: foo'); await clicknav('[href="/shadowed/dynamic/bar"]'); - expect(await page.textContent('h1')).toBe('slug: bar'); + await expect(page.locator('h1')).toHaveText('slug: bar'); await page.goto('/shadowed/dynamic/foo'); - expect(await page.textContent('h1')).toBe('slug: foo'); + await expect(page.locator('h1')).toHaveText('slug: foo'); await clicknav('[href="/shadowed/dynamic/bar"]'); - expect(await page.textContent('h1')).toBe('slug: bar'); + await expect(page.locator('h1')).toHaveText('slug: bar'); }); test('Shadow redirect', async ({ page, clicknav }) => { await page.goto('/shadowed/redirect'); await clicknav('[href="/shadowed/redirect/a"]'); - expect(await page.textContent('h1')).toBe('done'); + await expect(page.locator('h1')).toHaveText('done'); }); test('Endpoint without GET', async ({ page, clicknav, baseURL, javaScriptEnabled }) => { @@ -179,7 +181,7 @@ test.describe('Shadowed pages', () => { await clicknav('[href="/shadowed/missing-get"]'); - expect(await page.textContent('h1')).toBe('post without get'); + await expect(page.locator('h1')).toHaveText('post without get'); // check that the router didn't fall back to the server if (javaScriptEnabled) { @@ -218,8 +220,8 @@ test.describe('Shadowed pages', () => { await page.goto('/shadowed'); await clicknav('[href="/shadowed/serialization"]'); - expect(await page.textContent('h1')).toBe('500'); - expect(await page.textContent('#message')).toBe( + await expect(page.locator('h1')).toHaveText('500'); + await expect(page.locator('#message')).toHaveText( 'This is your custom error page saying: "Data returned from `load` while rendering /shadowed/serialization is not serializable: Cannot stringify arbitrary non-POJOs (data.nope).' + ' If you need to serialize/deserialize custom types, use transport hooks: https://svelte.dev/docs/kit/hooks#Universal-hooks-transport. (500 Internal Error)"' ); @@ -234,8 +236,8 @@ test.describe('Errors', () => { test('server-side errors', async ({ page }) => { await page.goto('/errors/serverside'); - expect(await page.textContent('footer')).toBe('Custom layout'); - expect(await page.textContent('#message')).toBe( + await expect(page.locator('footer')).toHaveText('Custom layout'); + await expect(page.locator('#message')).toHaveText( 'This is your custom error page saying: "Crashing now (500 Internal Error)"' ); }); @@ -245,8 +247,8 @@ test.describe('Errors', () => { await page.goto('/errors/module-scope-server'); - expect(await page.textContent('footer')).toBe('Custom layout'); - expect(await page.textContent('#message')).toBe( + await expect(page.locator('footer')).toHaveText('Custom layout'); + await expect(page.locator('#message')).toHaveText( 'This is your custom error page saying: "Crashing now"' ); }); @@ -259,13 +261,13 @@ test.describe('Errors', () => { await page.goto('/errors/invalid-load-response'); } - expect(await page.textContent('footer')).toBe('Custom layout'); + await expect(page.locator('footer')).toHaveText('Custom layout'); const details = javaScriptEnabled ? "related to route '/errors/invalid-load-response'" : 'in src/routes/errors/invalid-load-response/+page.js'; - expect(await page.textContent('#message')).toBe( + await expect(page.locator('#message')).toHaveText( `This is your custom error page saying: "a load function ${details} returned an array, but must return a plain object at the top level (i.e. \`return {...}\`) (500 Internal Error)"` ); }); @@ -282,9 +284,9 @@ test.describe('Errors', () => { await page.goto('/errors/invalid-server-load-response'); } - expect(await page.textContent('footer')).toBe('Custom layout'); + await expect(page.locator('footer')).toHaveText('Custom layout'); - expect(await page.textContent('#message')).toBe( + await expect(page.locator('#message')).toHaveText( 'This is your custom error page saying: "a load function in src/routes/errors/invalid-server-load-response/+page.server.js returned an array, but must return a plain object at the top level (i.e. `return {...}`) (500 Internal Error)"' ); }); @@ -293,8 +295,8 @@ test.describe('Errors', () => { test('server-side load errors', async ({ page, get_computed_style }) => { await page.goto('/errors/load-server'); - expect(await page.textContent('footer')).toBe('Custom layout'); - expect(await page.textContent('#message')).toBe( + await expect(page.locator('footer')).toHaveText('Custom layout'); + await expect(page.locator('#message')).toHaveText( 'This is your custom error page saying: "Crashing now (500 Internal Error)"' ); @@ -304,8 +306,8 @@ test.describe('Errors', () => { test('404', async ({ page }) => { const response = await page.goto('/why/would/anyone/fetch/this/url'); - expect(await page.textContent('footer')).toBe('Custom layout'); - expect(await page.textContent('#message')).toBe( + await expect(page.locator('footer')).toHaveText('Custom layout'); + await expect(page.locator('#message')).toHaveText( 'This is your custom error page saying: "Not found: /why/would/anyone/fetch/this/url (404 Not Found)"' ); expect(/** @type {Response} */ (response).status()).toBe(404); @@ -314,8 +316,8 @@ test.describe('Errors', () => { test('server-side error from load() is a string', async ({ page }) => { const response = await page.goto('/errors/load-error-string-server'); - expect(await page.textContent('footer')).toBe('Custom layout'); - expect(await page.textContent('#message')).toBe( + await expect(page.locator('footer')).toHaveText('Custom layout'); + await expect(page.locator('#message')).toHaveText( 'This is your custom error page saying: "Not found"' ); expect(/** @type {Response} */ (response).status()).toBe(555); @@ -324,8 +326,8 @@ test.describe('Errors', () => { test('server-side error from load() is an Error', async ({ page }) => { const response = await page.goto('/errors/load-error-server'); - expect(await page.textContent('footer')).toBe('Custom layout'); - expect(await page.textContent('#message')).toBe( + await expect(page.locator('footer')).toHaveText('Custom layout'); + await expect(page.locator('#message')).toHaveText( 'This is your custom error page saying: "Not found"' ); expect(/** @type {Response} */ (response).status()).toBe(555); @@ -333,7 +335,7 @@ test.describe('Errors', () => { test('server-side error from load() still has layout data', async ({ page }) => { await page.goto('/errors/load-error-server/layout-data'); - expect(await page.textContent('#error-layout-data')).toBe('42'); + await expect(page.locator('#error-layout-data')).toHaveText('42'); }); test('error in endpoint', async ({ page, read_errors }) => { @@ -348,7 +350,7 @@ test.describe('Errors', () => { } expect(res && res.status()).toBe(500); - expect(await page.textContent('#message')).toBe( + await expect(page.locator('#message')).toHaveText( 'This is your custom error page saying: "500 (500 Internal Error)"' ); }); @@ -365,7 +367,7 @@ test.describe('Errors', () => { } expect(res && res.status()).toBe(500); - expect(await page.textContent('#message')).toBe( + await expect(page.locator('#message')).toHaveText( 'This is your custom error page saying: "nope (500 Internal Error)"' ); }); @@ -376,7 +378,7 @@ test.describe('Errors', () => { expect(read_errors('/errors/endpoint-shadow-not-ok')).toBeUndefined(); expect(res && res.status()).toBe(555); - expect(await page.textContent('#message')).toBe( + await expect(page.locator('#message')).toHaveText( 'This is your custom error page saying: "Error: 555"' ); }); @@ -385,9 +387,9 @@ test.describe('Errors', () => { page }) => { await page.goto('/prerendering/mutative-endpoint'); - expect(await page.textContent('h1')).toBe('500'); + await expect(page.locator('h1')).toHaveText('500'); - expect(await page.textContent('#message')).toBe( + await expect(page.locator('#message')).toHaveText( 'This is your custom error page saying: "Cannot prerender pages with actions (500 Internal Error)"' ); }); @@ -400,7 +402,7 @@ test.describe('Errors', () => { await page.goto('/errors/page-endpoint'); await clicknav('#get-implicit'); - expect(await page.textContent('pre')).toBe( + await expect(page.locator('pre')).toHaveText( JSON.stringify({ status: 500, message: 'oops (500 Internal Error)' }, null, ' ') ); @@ -425,7 +427,7 @@ test.describe('Errors', () => { await page.goto('/errors/page-endpoint'); await clicknav('#get-explicit'); - expect(await page.textContent('pre')).toBe( + await expect(page.locator('pre')).toHaveText( JSON.stringify({ status: 400, message: 'oops' }, null, ' ') ); @@ -443,7 +445,7 @@ test.describe('Errors', () => { await page.goto('/errors/page-endpoint'); await clicknav('#post-implicit'); - expect(await page.textContent('pre')).toBe( + await expect(page.locator('pre')).toHaveText( JSON.stringify({ status: 500, message: 'oops (500 Internal Error)' }, null, ' ') ); @@ -471,7 +473,7 @@ test.describe('Errors', () => { await page.goto('/errors/page-endpoint'); await clicknav('#post-explicit'); - expect(await page.textContent('pre')).toBe( + await expect(page.locator('pre')).toHaveText( JSON.stringify({ status: 400, message: 'oops' }, null, ' ') ); @@ -494,7 +496,7 @@ test.describe('Redirects', () => { await clicknav('[href="/redirect/a"]'); await page.waitForURL('/redirect/c'); - expect(await page.textContent('h1')).toBe('c'); + await expect(page.locator('h1')).toHaveText('c'); expect(page.url()).toBe(`${baseURL}/redirect/c`); await page.goBack(); @@ -509,8 +511,8 @@ test.describe('Redirects', () => { if (javaScriptEnabled) { await page.waitForSelector('#message'); expect(page.url()).toBe(`${baseURL}/redirect/loopy/a`); - expect(await page.textContent('h1')).toBe('500'); - expect(await page.textContent('#message')).toBe( + await expect(page.locator('h1')).toHaveText('500'); + await expect(page.locator('#message')).toHaveText( 'This is your custom error page saying: "Redirect loop (500 Internal Error)"' ); } else { @@ -537,8 +539,8 @@ test.describe('Redirects', () => { const message = process.env.DEV || !javaScriptEnabled ? 'Invalid status code' : 'Redirect loop'; expect(page.url()).toBe(`${baseURL}/redirect/missing-status/a`); - expect(await page.textContent('h1')).toBe('500'); - expect(await page.textContent('#message')).toBe( + await expect(page.locator('h1')).toHaveText('500'); + await expect(page.locator('#message')).toHaveText( `This is your custom error page saying: "${message} (500 Internal Error)"` ); @@ -557,8 +559,8 @@ test.describe('Redirects', () => { const message = process.env.DEV || !javaScriptEnabled ? 'Invalid status code' : 'Redirect loop'; expect(page.url()).toBe(`${baseURL}/redirect/missing-status/b`); - expect(await page.textContent('h1')).toBe('500'); - expect(await page.textContent('#message')).toBe( + await expect(page.locator('h1')).toHaveText('500'); + await expect(page.locator('#message')).toHaveText( `This is your custom error page saying: "${message} (500 Internal Error)"` ); }); @@ -573,7 +575,7 @@ test.describe('Redirects', () => { expect(page.url()).toBe(redirected_to_url); if (javaScriptEnabled) { - expect(await page.textContent('h1')).toBe('Hazaa!'); + await expect(page.locator('h1')).toHaveText('Hazaa!'); } }); @@ -583,7 +585,7 @@ test.describe('Redirects', () => { await clicknav('[href="/redirect/in-handle?response"]'); await page.waitForURL('/redirect/c'); - expect(await page.textContent('h1')).toBe('c'); + await expect(page.locator('h1')).toHaveText('c'); expect(page.url()).toBe(`${baseURL}/redirect/c`); await page.goBack(); @@ -596,7 +598,7 @@ test.describe('Redirects', () => { await clicknav('[href="/redirect/in-handle?throw"]'); await page.waitForURL('/redirect/c'); - expect(await page.textContent('h1')).toBe('c'); + await expect(page.locator('h1')).toHaveText('c'); expect(page.url()).toBe(`${baseURL}/redirect/c`); await page.goBack(); @@ -625,7 +627,7 @@ test.describe('Redirects', () => { test('works when used from another package', async ({ page }) => { await page.goto('/redirect/package'); - expect(await page.textContent('h1')).toBe('c'); + await expect(page.locator('h1')).toHaveText('c'); }); }); @@ -641,13 +643,13 @@ test.describe('Routing', () => { await clicknav('a[href="/routing/"]'); expect(page.url()).toBe(`${baseURL}/routing`); - expect(await page.textContent('h1')).toBe('Great success!'); + await expect(page.locator('h1')).toHaveText('Great success!'); if (javaScriptEnabled) { await page.goto(`${baseURL}/routing/slashes`); await app.goto('/routing/'); expect(page.url()).toBe(`${baseURL}/routing`); - expect(await page.textContent('h1')).toBe('Great success!'); + await expect(page.locator('h1')).toHaveText('Great success!'); } }); @@ -662,13 +664,13 @@ test.describe('Routing', () => { await clicknav('a[href="/routing/?"]'); expect(page.url()).toBe(`${baseURL}/routing`); - expect(await page.textContent('h1')).toBe('Great success!'); + await expect(page.locator('h1')).toHaveText('Great success!'); if (javaScriptEnabled) { await page.goto(`${baseURL}/routing/slashes`); await app.goto('/routing/?'); expect(page.url()).toBe(`${baseURL}/routing`); - expect(await page.textContent('h1')).toBe('Great success!'); + await expect(page.locator('h1')).toHaveText('Great success!'); } }); @@ -683,47 +685,47 @@ test.describe('Routing', () => { await clicknav('a[href="/routing/?foo=bar"]'); expect(page.url()).toBe(`${baseURL}/routing?foo=bar`); - expect(await page.textContent('h1')).toBe('Great success!'); + await expect(page.locator('h1')).toHaveText('Great success!'); if (javaScriptEnabled) { await page.goto(`${baseURL}/routing/slashes`); await app.goto('/routing/?foo=bar'); expect(page.url()).toBe(`${baseURL}/routing?foo=bar`); - expect(await page.textContent('h1')).toBe('Great success!'); + await expect(page.locator('h1')).toHaveText('Great success!'); } }); test('serves static route', async ({ page }) => { await page.goto('/routing/a'); - expect(await page.textContent('h1')).toBe('a'); + await expect(page.locator('h1')).toHaveText('a'); }); test('serves static route from dir/index.html file', async ({ page }) => { await page.goto('/routing/b'); - expect(await page.textContent('h1')).toBe('b'); + await expect(page.locator('h1')).toHaveText('b'); }); test('serves static route under client directory', async ({ baseURL, page }) => { await page.goto('/routing/client/foo'); - expect(await page.textContent('h1')).toBe('foo'); + await expect(page.locator('h1')).toHaveText('foo'); await page.goto(`${baseURL}/routing/client/bar`); - expect(await page.textContent('h1')).toBe('bar'); + await expect(page.locator('h1')).toHaveText('bar'); await page.goto(`${baseURL}/routing/client/bar/b`); - expect(await page.textContent('h1')).toBe('b'); + await expect(page.locator('h1')).toHaveText('b'); }); test('serves dynamic route', async ({ page }) => { await page.goto('/routing/test-slug'); - expect(await page.textContent('h1')).toBe('test-slug'); + await expect(page.locator('h1')).toHaveText('test-slug'); }); test('does not attempt client-side navigation to server routes', async ({ page }) => { await page.goto('/routing'); await page.locator('[href="/routing/ambiguous/ok.json"]').click(); - expect(await page.textContent('body')).toBe('ok'); + await expect(page.locator('body')).toHaveText('ok'); }); test('does not attempt client-side navigation to links with data-sveltekit-reload', async ({ @@ -738,13 +740,13 @@ test.describe('Routing', () => { page.on('request', (r) => requests.push(r.url())); await clicknav('[href="/routing/b"]'); - expect(await page.textContent('h1')).toBe('b'); + await expect(page.locator('h1')).toHaveText('b'); expect(requests).toContain(`${baseURL}/routing/b`); }); test('allows reserved words as route names', async ({ page }) => { await page.goto('/routing/const'); - expect(await page.textContent('h1')).toBe('reserved words are okay as routes'); + await expect(page.locator('h1')).toHaveText('reserved words are okay as routes'); }); test('resets the active element after navigation', async ({ page, clicknav }) => { @@ -755,25 +757,25 @@ test.describe('Routing', () => { test('navigates between routes with empty parts', async ({ page, clicknav }) => { await page.goto('/routing/dirs/foo'); - expect(await page.textContent('h1')).toBe('foo'); + await expect(page.locator('h1')).toHaveText('foo'); await clicknav('[href="bar"]'); - expect(await page.textContent('h1')).toBe('bar'); + await expect(page.locator('h1')).toHaveText('bar'); }); test('navigates between dynamic routes with same segments', async ({ page, clicknav }) => { await page.goto('/routing/dirs/bar/xyz'); - expect(await page.textContent('h1')).toBe('A page'); + await expect(page.locator('h1')).toHaveText('A page'); await clicknav('[href="/routing/dirs/foo/xyz"]'); - expect(await page.textContent('h1')).toBe('B page'); + await expect(page.locator('h1')).toHaveText('B page'); }); test('invalidates page when a segment is skipped', async ({ page, clicknav }) => { await page.goto('/routing/skipped/x/1'); - expect(await page.textContent('h1')).toBe('x/1'); + await expect(page.locator('h1')).toHaveText('x/1'); await clicknav('#goto-y1'); - expect(await page.textContent('h1')).toBe('y/1'); + await expect(page.locator('h1')).toHaveText('y/1'); }); test('back button returns to initial route', async ({ page, clicknav }) => { @@ -781,7 +783,7 @@ test.describe('Routing', () => { await clicknav('[href="/routing/a"]'); await page.goBack(); - expect(await page.textContent('h1')).toBe('Great success!'); + await expect(page.locator('h1')).toHaveText('Great success!'); }); test('focus works if page load has hash', async ({ page, browserName }) => { @@ -817,8 +819,8 @@ test.describe('Routing', () => { test('last parameter in a segment wins in cases of ambiguity', async ({ page, clicknav }) => { await page.goto('/routing/split-params'); await clicknav('[href="/routing/split-params/x-y-z"]'); - expect(await page.textContent('h1')).toBe('x'); - expect(await page.textContent('h2')).toBe('y-z'); + await expect(page.locator('h1')).toHaveText('x'); + await expect(page.locator('h2')).toHaveText('y-z'); }); test('ignores navigation to URLs the app does not own', async ({ page, start_server }) => { @@ -835,66 +837,66 @@ test.describe('Routing', () => { test('navigates to ...rest', async ({ page, clicknav }) => { await page.goto('/routing/rest/abc/xyz'); - expect(await page.textContent('h1')).toBe('abc/xyz'); + await expect(page.locator('h1')).toHaveText('abc/xyz'); await clicknav('[href="/routing/rest/xyz/abc/def/ghi"]'); - expect(await page.textContent('h1')).toBe('xyz/abc/def/ghi'); - expect(await page.textContent('h2')).toBe('xyz/abc/def/ghi'); + await expect(page.locator('h1')).toHaveText('xyz/abc/def/ghi'); + await expect(page.locator('h2')).toHaveText('xyz/abc/def/ghi'); await clicknav('[href="/routing/rest/xyz/abc/def"]'); - expect(await page.textContent('h1')).toBe('xyz/abc/def'); - expect(await page.textContent('h2')).toBe('xyz/abc/def'); + await expect(page.locator('h1')).toHaveText('xyz/abc/def'); + await expect(page.locator('h2')).toHaveText('xyz/abc/def'); await clicknav('[href="/routing/rest/xyz/abc"]'); - expect(await page.textContent('h1')).toBe('xyz/abc'); - expect(await page.textContent('h2')).toBe('xyz/abc'); + await expect(page.locator('h1')).toHaveText('xyz/abc'); + await expect(page.locator('h2')).toHaveText('xyz/abc'); await clicknav('[href="/routing/rest"]'); - expect(await page.textContent('h1')).toBe(''); - expect(await page.textContent('h2')).toBe(''); + await expect(page.locator('h1')).toHaveText(''); + await expect(page.locator('h2')).toHaveText(''); await clicknav('[href="/routing/rest/xyz/abc/deep"]'); - expect(await page.textContent('h1')).toBe('xyz/abc'); - expect(await page.textContent('h2')).toBe('xyz/abc'); + await expect(page.locator('h1')).toHaveText('xyz/abc'); + await expect(page.locator('h2')).toHaveText('xyz/abc'); await page.locator('[href="/routing/rest/xyz/abc/qwe/deep.json"]').click(); - expect(await page.textContent('body')).toBe('xyz/abc/qwe'); + await expect(page.locator('body')).toHaveText('xyz/abc/qwe'); }); test('rest parameters do not swallow characters', async ({ page, clicknav }) => { await page.goto('/routing/rest/non-greedy'); await clicknav('[href="/routing/rest/non-greedy/foo/one/two"]'); - expect(await page.textContent('h1')).toBe('non-greedy'); - expect(await page.textContent('h2')).toBe('{"rest":"one/two"}'); + await expect(page.locator('h1')).toHaveText('non-greedy'); + await expect(page.locator('h2')).toHaveText('{"rest":"one/two"}'); await clicknav('[href="/routing/rest/non-greedy/food/one/two"]'); - expect(await page.textContent('h1')).not.toBe('non-greedy'); + await expect(page.locator('h1')).not.toHaveText('non-greedy'); await page.goBack(); await clicknav('[href="/routing/rest/non-greedy/one-bar/two/three"]'); - expect(await page.textContent('h1')).toBe('non-greedy'); - expect(await page.textContent('h2')).toBe('{"dynamic":"one","rest":"two/three"}'); + await expect(page.locator('h1')).toHaveText('non-greedy'); + await expect(page.locator('h2')).toHaveText('{"dynamic":"one","rest":"two/three"}'); await clicknav('[href="/routing/rest/non-greedy/one-bard/two/three"]'); - expect(await page.textContent('h1')).not.toBe('non-greedy'); + await expect(page.locator('h1')).not.toHaveText('non-greedy'); }); test('reloads when navigating between ...rest pages', async ({ page, clicknav }) => { await page.goto('/routing/rest/path/one'); - expect(await page.textContent('h1')).toBe('path: /routing/rest/path/one'); + await expect(page.locator('h1')).toHaveText('path: /routing/rest/path/one'); await clicknav('[href="/routing/rest/path/two"]'); - expect(await page.textContent('h1')).toBe('path: /routing/rest/path/two'); + await expect(page.locator('h1')).toHaveText('path: /routing/rest/path/two'); await clicknav('[href="/routing/rest/path/three"]'); - expect(await page.textContent('h1')).toBe('path: /routing/rest/path/three'); + await expect(page.locator('h1')).toHaveText('path: /routing/rest/path/three'); }); test('allows rest routes to have prefixes and suffixes', async ({ page }) => { await page.goto('/routing/rest/complex/prefix-one/two/three'); - expect(await page.textContent('h1')).toBe('parts: one/two/three'); + await expect(page.locator('h1')).toHaveText('parts: one/two/three'); }); test('links to unmatched routes result in a full page navigation, not a 404', async ({ @@ -903,7 +905,7 @@ test.describe('Routing', () => { }) => { await page.goto('/routing'); await clicknav('[href="/static.json"]'); - expect(await page.textContent('body')).toBe('"static file"\n'); + await expect(page.locator('body')).toHaveText('"static file"\n'); }); test('navigation is cancelled upon subsequent navigation', async ({ @@ -934,19 +936,21 @@ test.describe('Routing', () => { await page.goto('/routing/route-id'); await clicknav('[href="/routing/route-id/foo"]'); - expect(await page.textContent('h1')).toBe('route.id in load: /routing/route-id/[x]'); - expect(await page.textContent('h2')).toBe('route.id in store: /routing/route-id/[x]'); + await expect(page.locator('h1')).toHaveText('route.id in load: /routing/route-id/[x]'); + await expect(page.locator('h2')).toHaveText('route.id in store: /routing/route-id/[x]'); }); test('serves a page that clashes with a root directory', async ({ page }) => { await page.goto('/static'); - expect(await page.textContent('h1')).toBe('hello'); + await expect(page.locator('h1')).toHaveText('hello'); }); test('shows "Not Found" in 404 case', async ({ page }) => { await page.goto('/404-fallback'); - expect(await page.textContent('h1')).toBe('404'); - expect(await page.textContent('p')).toBe('This is your custom error page saying: "Not Found"'); + await expect(page.locator('h1')).toHaveText('404'); + await expect(page.locator('p')).toHaveText( + 'This is your custom error page saying: "Not Found"' + ); }); if (process.platform !== 'win32') { @@ -954,17 +958,17 @@ test.describe('Routing', () => { await page.goto('/routing'); await clicknav('[href="/routing/symlink-from"]'); - expect(await page.textContent('h1')).toBe('symlinked'); + await expect(page.locator('h1')).toHaveText('symlinked'); }); } test('trailing slash server with config always', async ({ page, clicknav }) => { await page.goto('/routing/trailing-slash-server'); await clicknav('[href="/routing/trailing-slash-server/always"]'); - expect(await page.textContent('[data-test-id="pathname-store"]')).toBe( + await expect(page.locator('[data-test-id="pathname-store"]')).toHaveText( '/routing/trailing-slash-server/always/' ); - expect(await page.textContent('[data-test-id="pathname-data"]')).toBe( + await expect(page.locator('[data-test-id="pathname-data"]')).toHaveText( '/routing/trailing-slash-server/always/' ); }); @@ -975,10 +979,10 @@ test.describe('Routing', () => { }) => { await page.goto('/routing/trailing-slash-server'); await clicknav('[href="/routing/trailing-slash-server/ignore"]'); - expect(await page.textContent('[data-test-id="pathname-store"]')).toBe( + await expect(page.locator('[data-test-id="pathname-store"]')).toHaveText( '/routing/trailing-slash-server/ignore' ); - expect(await page.textContent('[data-test-id="pathname-data"]')).toBe( + await expect(page.locator('[data-test-id="pathname-data"]')).toHaveText( '/routing/trailing-slash-server/ignore' ); }); @@ -989,10 +993,10 @@ test.describe('Routing', () => { }) => { await page.goto('/routing/trailing-slash-server'); await clicknav('[href="/routing/trailing-slash-server/ignore/"]'); - expect(await page.textContent('[data-test-id="pathname-store"]')).toBe( + await expect(page.locator('[data-test-id="pathname-store"]')).toHaveText( '/routing/trailing-slash-server/ignore/' ); - expect(await page.textContent('[data-test-id="pathname-data"]')).toBe( + await expect(page.locator('[data-test-id="pathname-data"]')).toHaveText( '/routing/trailing-slash-server/ignore/' ); }); @@ -1000,10 +1004,10 @@ test.describe('Routing', () => { test('trailing slash server with config never', async ({ page, clicknav }) => { await page.goto('/routing/trailing-slash-server'); await clicknav('[href="/routing/trailing-slash-server/never/"]'); - expect(await page.textContent('[data-test-id="pathname-store"]')).toBe( + await expect(page.locator('[data-test-id="pathname-store"]')).toHaveText( '/routing/trailing-slash-server/never' ); - expect(await page.textContent('[data-test-id="pathname-data"]')).toBe( + await expect(page.locator('[data-test-id="pathname-data"]')).toHaveText( '/routing/trailing-slash-server/never' ); }); @@ -1013,14 +1017,13 @@ test.describe('XSS', () => { test('replaces %sveltekit.xxx% tags safely', async ({ page }) => { await page.goto('/unsafe-replacement'); - const content = await page.textContent('body'); - expect(content).toMatch('$& $&'); + await expect(page.locator('body')).toContainText('$& $&'); }); test('escapes inline data', async ({ page, javaScriptEnabled }) => { await page.goto('/xss'); - expect(await page.textContent('h1')).toBe( + await expect(page.locator('h1')).toHaveText( 'user.name is ' ); @@ -1036,7 +1039,7 @@ test.describe('XSS', () => { test('no xss via dynamic route path', async ({ page }) => { await page.goto(`/xss/${uri_xss_payload_encoded}`); - expect(await page.textContent('h1')).toBe(uri_xss_payload); + await expect(page.locator('h1')).toHaveText(uri_xss_payload); // @ts-expect-error - check global injected variable expect(await page.evaluate(() => window.pwned)).toBeUndefined(); @@ -1045,8 +1048,8 @@ test.describe('XSS', () => { test('no xss via query param', async ({ page }) => { await page.goto(`/xss/query?key=${uri_xss_payload_encoded}`); - expect(await page.textContent('#one')).toBe(JSON.stringify({ key: [uri_xss_payload] })); - expect(await page.textContent('#two')).toBe(JSON.stringify({ key: [uri_xss_payload] })); + await expect(page.locator('#one')).toHaveText(JSON.stringify({ key: [uri_xss_payload] })); + await expect(page.locator('#two')).toHaveText(JSON.stringify({ key: [uri_xss_payload] })); // @ts-expect-error - check global injected variable expect(await page.evaluate(() => window.pwned)).toBeUndefined(); @@ -1057,7 +1060,7 @@ test.describe('XSS', () => { // @ts-expect-error - check global injected variable expect(await page.evaluate(() => window.pwned)).toBeUndefined(); - expect(await page.textContent('h1')).toBe( + await expect(page.locator('h1')).toHaveText( 'user.name is ' ); }); @@ -1075,23 +1078,20 @@ test.describe('$app/server', () => { test('can read a file', async ({ page }) => { await page.goto('/read-file'); - const auto = await page.textContent('[data-testid="auto"]'); - const url = await page.textContent('[data-testid="url"]'); - const styles = await page.textContent('[data-testid="styles"]'); - const local_glob = await page.textContent('[data-testid="local_glob"]'); - const external_glob = await page.textContent('[data-testid="external_glob"]'); - const svg = await page.innerHTML('[data-testid="svg"]'); - // the emoji is there to check that base64 decoding works correctly - expect(auto?.trim()).toBe('Imported without ?url 😎'); - expect(url?.trim()).toBe('Imported with ?url 😎'); - expect(local_glob?.trim()).toBe('Imported with ?url via glob 😎'); - expect(external_glob?.trim()).toBe( + await expect(page.locator('[data-testid="auto"]')).toHaveText('Imported without ?url 😎'); + await expect(page.locator('[data-testid="url"]')).toHaveText('Imported with ?url 😎'); + await expect(page.locator('[data-testid="local_glob"]')).toHaveText( + 'Imported with ?url via glob 😎' + ); + await expect(page.locator('[data-testid="external_glob"]')).toHaveText( 'Imported with url glob from the read-file test in basics. Placed here outside the app folder to force a /@fs prefix 😎' ); + + const svg = await page.innerHTML('[data-testid="svg"]'); expect(svg).toContain(''); // check that paths in .css files are relative - expect(styles).toContain('url(.'); + await expect(page.locator('[data-testid="styles"]')).toContainText('url(.'); }); }); diff --git a/packages/kit/test/apps/basics/test/server.test.js b/packages/kit/test/apps/basics/test/server.test.js index eea785051107..32eda66570be 100644 --- a/packages/kit/test/apps/basics/test/server.test.js +++ b/packages/kit/test/apps/basics/test/server.test.js @@ -465,13 +465,13 @@ test.describe('Errors', () => { test('stack traces are not fixed twice', async ({ page }) => { await page.goto('/errors/stack-trace'); - expect(await page.textContent('#message')).toBe( + await expect(page.locator('#message')).toHaveText( 'This is your custom error page saying: "Cannot read properties of undefined (reading \'toUpperCase\') (500 Internal Error)"' ); // check the stack wasn't mutated await page.goto('/errors/stack-trace'); - expect(await page.textContent('#message')).toBe( + await expect(page.locator('#message')).toHaveText( 'This is your custom error page saying: "Cannot read properties of undefined (reading \'toUpperCase\') (500 Internal Error)"' ); }); @@ -515,7 +515,7 @@ test.describe('Errors', () => { const error = read_errors('/errors/endpoint-throw-redirect'); expect(error).toBe(undefined); - expect(await page.textContent('h1')).toBe('the answer is 42'); + await expect(page.locator('h1')).toHaveText('the answer is 42'); }); test('POST to missing page endpoint', async ({ request }) => { @@ -636,7 +636,7 @@ test.describe('Load', () => { test('includes origin header on non-GET internal request', async ({ page, baseURL }) => { await page.goto('/load/fetch-origin-internal'); - expect(await page.textContent('h1')).toBe(`origin: ${new URL(baseURL).origin}`); + await expect(page.locator('h1')).toHaveText(`origin: ${new URL(baseURL).origin}`); }); test('includes origin header on external request', async ({ page, baseURL, start_server }) => { @@ -655,7 +655,7 @@ test.describe('Load', () => { }); await page.goto(`/load/fetch-origin-external?port=${port}`); - expect(await page.textContent('h1')).toBe(`origin: ${new URL(baseURL).origin}`); + await expect(page.locator('h1')).toHaveText(`origin: ${new URL(baseURL).origin}`); }); test('does not run when using invalid request methods', async ({ request }) => { @@ -682,7 +682,7 @@ test.describe('Load', () => { test('allows logging URL search params', async ({ page }) => { await page.goto('/load/server-log-search-param'); - expect(await page.textContent('p')).toBe('hello world'); + await expect(page.locator('p')).toHaveText('hello world'); }); }); @@ -822,7 +822,7 @@ test.describe('Miscellaneous', () => { test.describe('reroute', () => { test('Apply reroute when directly accessing a page', async ({ page }) => { await page.goto('/reroute/basic/a'); - expect(await page.textContent('h1')).toContain( + await expect(page.locator('h1')).toContainText( 'Successfully rewritten, URL should still show a: /reroute/basic/a' ); }); @@ -832,21 +832,21 @@ test.describe('reroute', () => { .context() .addCookies([{ name: 'reroute-cookie', value: 'yes', path: '/', domain: 'localhost' }]); await page.goto('/reroute/async/a'); - expect(await page.textContent('h1')).toContain( + await expect(page.locator('h1')).toContainText( 'Successfully rewritten, URL should still show a: /reroute/async/a' ); }); test('Apply async prerendered reroute when directly accessing a page', async ({ page }) => { await page.goto('/reroute/async/c'); - expect(await page.textContent('h1')).toContain( + await expect(page.locator('h1')).toContainText( 'Successfully rewritten, URL should still show a: /reroute/async/c' ); }); test('Apply reroute to prerendered page when directly accessing a page', async ({ page }) => { await page.goto('/reroute/prerendered/to-destination'); - expect(await page.textContent('h1')).toContain('reroute that points to prerendered page works'); + await expect(page.locator('h1')).toContainText('reroute that points to prerendered page works'); }); test('Returns a 500 response if reroute throws an error on the server', async ({ page }) => { diff --git a/packages/kit/test/apps/basics/test/test.js b/packages/kit/test/apps/basics/test/test.js index 554a4d8ba59d..20ccdffda73a 100644 --- a/packages/kit/test/apps/basics/test/test.js +++ b/packages/kit/test/apps/basics/test/test.js @@ -11,7 +11,7 @@ test.describe.configure({ mode: 'parallel' }); test.describe('adapter', () => { test('populates event.platform for dynamic SSR', async ({ page }) => { await page.goto('/adapter/dynamic'); - const json = JSON.parse((await page.textContent('pre')) ?? ''); + const json = JSON.parse((await page.locator('pre').textContent()) ?? ''); expect(json).toEqual({ config: { @@ -23,7 +23,7 @@ test.describe('adapter', () => { test('populates event.platform for prerendered page', async ({ page }) => { await page.goto('/adapter/prerendered'); - const json = JSON.parse((await page.textContent('pre')) ?? ''); + const json = JSON.parse((await page.locator('pre').textContent()) ?? ''); expect(json).toEqual({ config: { @@ -140,38 +140,38 @@ test.describe('Encoded paths', () => { test('allows non-ASCII character in parameterized route segment', async ({ page, clicknav }) => { await page.goto('/encoded'); await clicknav('[href="/encoded/@svelte"]'); - expect(await page.textContent('h1')).toBe('@svelte'); + await expect(page.locator('h1')).toHaveText('@svelte'); }); test('allows characters to be represented as escape sequences', async ({ page, clicknav }) => { await page.goto('/encoded/escape-sequences'); await clicknav('[href="/encoded/escape-sequences/:-)"]'); - expect(await page.textContent('h1')).toBe(':-)'); + await expect(page.locator('h1')).toHaveText(':-)'); await clicknav('[href="/encoded/escape-sequences/%23"]'); - expect(await page.textContent('h1')).toBe('#'); + await expect(page.locator('h1')).toHaveText('#'); await clicknav('[href="/encoded/escape-sequences/%2F"]'); - expect(await page.textContent('h1')).toBe('/'); + await expect(page.locator('h1')).toHaveText('/'); await clicknav('[href="/encoded/escape-sequences/%3f"]'); - expect(await page.textContent('h1')).toBe('?'); + await expect(page.locator('h1')).toHaveText('?'); await clicknav('[href="/encoded/escape-sequences/%25"]'); - expect(await page.textContent('h1')).toBe('%'); + await expect(page.locator('h1')).toHaveText('%'); await clicknav('[href="/encoded/escape-sequences/<"]'); - expect(await page.textContent('h1')).toBe('<'); + await expect(page.locator('h1')).toHaveText('<'); await clicknav('[href="/encoded/escape-sequences/1<2"]'); - expect(await page.textContent('h1')).toBe('1<2'); + await expect(page.locator('h1')).toHaveText('1<2'); await clicknav('[href="/encoded/escape-sequences/苗"]'); - expect(await page.textContent('h1')).toBe('苗'); + await expect(page.locator('h1')).toHaveText('苗'); await clicknav('[href="/encoded/escape-sequences/ðŸĪŠ"]'); - expect(await page.textContent('h1')).toBe('ðŸĪŠ'); + await expect(page.locator('h1')).toHaveText('ðŸĪŠ'); }); }); @@ -179,34 +179,34 @@ test.describe('$env', () => { test('includes environment variables', async ({ page, clicknav }) => { await page.goto('/env/includes'); - expect(await page.textContent('#static-private')).toBe( + await expect(page.locator('#static-private')).toHaveText( 'PRIVATE_STATIC: accessible to server-side code/replaced at build time' ); - expect(await page.textContent('#dynamic-private')).toBe( + await expect(page.locator('#dynamic-private')).toHaveText( 'PRIVATE_DYNAMIC: accessible to server-side code/evaluated at run time' ); - expect(await page.textContent('#static-public')).toBe( + await expect(page.locator('#static-public')).toHaveText( 'PUBLIC_STATIC: accessible anywhere/replaced at build time' ); - expect(await page.textContent('#dynamic-public')).toBe( + await expect(page.locator('#dynamic-public')).toHaveText( 'PUBLIC_DYNAMIC: accessible anywhere/evaluated at run time' ); await page.goto('/env'); await clicknav('[href="/env/includes"]'); - expect(await page.textContent('#static-private')).toBe( + await expect(page.locator('#static-private')).toHaveText( 'PRIVATE_STATIC: accessible to server-side code/replaced at build time' ); - expect(await page.textContent('#dynamic-private')).toBe( + await expect(page.locator('#dynamic-private')).toHaveText( 'PRIVATE_DYNAMIC: accessible to server-side code/evaluated at run time' ); - expect(await page.textContent('#static-public')).toBe( + await expect(page.locator('#static-public')).toHaveText( 'PUBLIC_STATIC: accessible anywhere/replaced at build time' ); - expect(await page.textContent('#dynamic-public')).toBe( + await expect(page.locator('#dynamic-public')).toHaveText( 'PUBLIC_DYNAMIC: accessible anywhere/evaluated at run time' ); }); @@ -215,12 +215,12 @@ test.describe('$env', () => { test.describe('Load', () => { test('fetch in root index.svelte works', async ({ page }) => { await page.goto('/'); - expect(await page.textContent('h1')).toBe('the answer is 42'); + await expect(page.locator('h1')).toHaveText('the answer is 42'); }); test('loads', async ({ page }) => { await page.goto('/load'); - expect(await page.textContent('h1')).toBe('bar == bar?'); + await expect(page.locator('h1')).toHaveText('bar == bar?'); }); test('GET fetches are serialized', async ({ page, javaScriptEnabled }) => { @@ -248,7 +248,7 @@ test.describe('Load', () => { test('Server data serialization removes empty nodes', async ({ page }) => { await page.goto('/load/serialization-empty-node'); - expect(await page.textContent('h1')).toBe('42'); + await expect(page.locator('h1')).toHaveText('42'); }); test('POST fetches are serialized', async ({ page, javaScriptEnabled }) => { @@ -258,8 +258,8 @@ test.describe('Load', () => { await page.goto('/load/serialization-post'); - expect(await page.textContent('h1')).toBe('a: X'); - expect(await page.textContent('h2')).toBe('b: Y'); + await expect(page.locator('h1')).toHaveText('a: X'); + await expect(page.locator('h2')).toHaveText('b: Y'); if (!javaScriptEnabled) { const payload_a = '{"status":200,"statusText":"","headers":{},"body":"X"}'; @@ -282,8 +282,8 @@ test.describe('Load', () => { test('POST fetches with Request init are serialized', async ({ page, javaScriptEnabled }) => { await page.goto('/load/serialization-post-request'); - expect(await page.textContent('h1')).toBe('a: X'); - expect(await page.textContent('h2')).toBe('b: Y'); + await expect(page.locator('h1')).toHaveText('a: X'); + await expect(page.locator('h2')).toHaveText('b: Y'); if (!javaScriptEnabled) { const payload_a = '{"status":200,"statusText":"","headers":{},"body":"X"}'; @@ -304,7 +304,7 @@ test.describe('Load', () => { test('fetches using an arraybuffer serialized with b64', async ({ page, javaScriptEnabled }) => { await page.goto('/load/fetch-arraybuffer-b64'); - expect(await page.textContent('.test-content')).toBe('[1,2,3,4]'); + await expect(page.locator('.test-content')).toHaveText('[1,2,3,4]'); if (!javaScriptEnabled) { const payload = '{"status":200,"statusText":"","headers":{},"body":"AQIDBA=="}'; @@ -326,7 +326,7 @@ test.describe('Load', () => { test('fetches using a body stream serialized with b64', async ({ page, javaScriptEnabled }) => { await page.goto('/load/fetch-body-stream-b64'); - expect(await page.textContent('.test-content')).toBe('[1,2,3,4]'); + await expect(page.locator('.test-content')).toHaveText('[1,2,3,4]'); if (!javaScriptEnabled) { const payload = '{"status":200,"statusText":"","headers":{},"body":"AQIDBA=="}'; @@ -347,19 +347,19 @@ test.describe('Load', () => { test('json string is returned', async ({ page }) => { await page.goto('/load/relay'); - expect(await page.textContent('h1')).toBe('42'); + await expect(page.locator('h1')).toHaveText('42'); }); test('prefers static data over endpoint', async ({ page }) => { await page.goto('/load/foo'); - expect(await page.textContent('h1')).toBe('static file'); + await expect(page.locator('h1')).toHaveText('static file'); }); test('data is inherited', async ({ page, javaScriptEnabled, app }) => { for (const kind of ['shared', 'server']) { await page.goto(`/load/parent/${kind}/a/b/c`); - expect(await page.textContent('h1')).toBe('message: original + new'); - expect(await page.textContent('pre')).toBe( + await expect(page.locator('h1')).toHaveText('message: original + new'); + await expect(page.locator('pre')).toHaveText( JSON.stringify({ foo: { bar: 'Custom layout' }, message: 'original + new', @@ -372,8 +372,8 @@ test.describe('Load', () => { if (javaScriptEnabled) { await app.goto(`/load/parent/${kind}/d/e/f`); - expect(await page.textContent('h1')).toBe('message: original + new'); - expect(await page.textContent('pre')).toBe( + await expect(page.locator('h1')).toHaveText('message: original + new'); + await expect(page.locator('pre')).toHaveText( JSON.stringify({ foo: { bar: 'Custom layout' }, message: 'original + new', @@ -389,21 +389,21 @@ test.describe('Load', () => { test('fetch accepts a Request object', async ({ page, clicknav }) => { await page.goto('/load'); await clicknav('[href="/load/fetch-request"]'); - expect(await page.textContent('h1')).toBe('the answer is 42'); + await expect(page.locator('h1')).toHaveText('the answer is 42'); }); test('fetch resolves urls relatively to the target page', async ({ page, clicknav }) => { await page.goto('/load'); await clicknav('[href="/load/fetch-relative"]'); - expect(await page.textContent('h1')).toBe('the answer is 42'); - expect(await page.textContent('h2')).toBe('the question was ?'); + await expect(page.locator('h1')).toHaveText('the answer is 42'); + await expect(page.locator('h2')).toHaveText('the question was ?'); }); test('handles large responses', async ({ page }) => { await page.goto('/load'); await page.goto('/load/large-response'); - expect(await page.textContent('h1')).toBe('text.length is 5000000'); + await expect(page.locator('h1')).toHaveText('text.length is 5000000'); }); test('handles external api', async ({ page, start_server }) => { @@ -429,7 +429,7 @@ test.describe('Load', () => { await page.goto(`/load/server-fetch-request?port=${port}`); expect(requested_urls).toEqual(['/server-fetch-request-modified.json']); - expect(await page.textContent('h1')).toBe('the answer is 42'); + await expect(page.locator('h1')).toHaveText('the answer is 42'); }); test('makes credentialed fetches to endpoints by default', async ({ @@ -440,7 +440,7 @@ test.describe('Load', () => { if (javaScriptEnabled) return; await page.goto('/load'); await clicknav('[href="/load/fetch-credentialed"]'); - expect(await page.textContent('h1')).toBe('Hello SvelteKit!'); + await expect(page.locator('h1')).toHaveText('Hello SvelteKit!'); }); test('includes correct page request headers', async ({ @@ -452,7 +452,7 @@ test.describe('Load', () => { await page.goto('/load'); await clicknav('[href="/load/fetch-request-headers"]'); - const json = /** @type {string} */ (await page.textContent('pre')); + const json = /** @type {string} */ (await page.locator('pre').textContent()); const headers = JSON.parse(json); if (javaScriptEnabled) { @@ -504,7 +504,7 @@ test.describe('Load', () => { await context.clearCookies(); await page.goto('/load/set-cookie-fetch'); - expect(await page.textContent('h1')).toBe('the answer is 42'); + await expect(page.locator('h1')).toHaveText('the answer is 42'); /** @type {Record} */ const cookies = {}; @@ -529,22 +529,22 @@ test.describe('Load', () => { await page.goto('/load/accumulated'); await clicknav('[href="/load/accumulated/without-page-data"]'); - expect(await page.textContent('h1')).toBe('foo.bar: Custom layout'); + await expect(page.locator('h1')).toHaveText('foo.bar: Custom layout'); }); test('page with load has access to layout data', async ({ page, clicknav }) => { await page.goto('/load/accumulated'); await clicknav('[href="/load/accumulated/with-page-data"]'); - expect(await page.textContent('h1')).toBe('foo.bar: Custom layout'); - expect(await page.textContent('h2')).toBe('pagedata: pagedata'); + await expect(page.locator('h1')).toHaveText('foo.bar: Custom layout'); + await expect(page.locator('h2')).toHaveText('pagedata: pagedata'); }); test('Serializes non-JSON data', async ({ page, clicknav }) => { await page.goto('/load/devalue'); await clicknav('[href="/load/devalue/regex"]'); - expect(await page.textContent('h1')).toBe('true'); + await expect(page.locator('h1')).toHaveText('true'); }); test('Prerendered +server.js called from a non-prerendered +page.server.js works', async ({ @@ -559,7 +559,7 @@ test.describe('Load', () => { await page.goto('/prerendering/prerendered-endpoint/page'); } - expect(await page.textContent('h1')).toBe( + await expect(page.locator('h1')).toHaveText( 'Im prerendered and called from a non-prerendered +page.server.js' ); }); @@ -576,7 +576,7 @@ test.describe('Load', () => { await page.goto('/prerendering/prerendered-endpoint/from-handle-hook'); } - expect(await page.textContent('html')).toBe( + await expect(page.locator('html')).toHaveText( '{"message":"Im prerendered and called from a non-prerendered +page.server.js"}' ); }); @@ -584,30 +584,32 @@ test.describe('Load', () => { test('Logging page.url during prerendering works', async ({ page }) => { await page.goto('/prerendering/log-url'); - expect(await page.textContent('p')).toBe('error: false'); + await expect(page.locator('p')).toHaveText('error: false'); }); test('404 and root layout load fetch to prerendered endpoint works', async ({ page }) => { await page.goto('/non-existent-route'); - expect(await page.textContent('h1')).toBe('404'); + await expect(page.locator('h1')).toHaveText('404'); await page.goto('/non-existent-route-loop'); - expect(await page.textContent('h1')).toBe('404'); + await expect(page.locator('h1')).toHaveText('404'); }); test('AbortSignal works with internal fetch optimization', async ({ page }) => { await page.goto('/load/fetch-abort-signal'); - expect(await page.textContent('.aborted-immediately')).toBe('Aborted immediately: true'); - expect(await page.textContent('.aborted-during-request')).toBe('Aborted during request: true'); - expect(await page.textContent('.successful-data')).toContain('"message":"success"'); + await expect(page.locator('.aborted-immediately')).toHaveText('Aborted immediately: true'); + await expect(page.locator('.aborted-during-request')).toHaveText( + 'Aborted during request: true' + ); + await expect(page.locator('.successful-data')).toContainText('"message":"success"'); }); test('event.fetch handles response without body', async ({ page }) => { await page.goto('/load/fetch-no-body'); - expect(await page.textContent('h1')).toBe('ok: true'); + await expect(page.locator('h1')).toHaveText('ok: true'); }); }); @@ -615,40 +617,40 @@ test.describe('Nested layouts', () => { test('renders a nested layout', async ({ page }) => { await page.goto('/nested-layout'); - expect(await page.textContent('footer')).toBe('Custom layout'); - expect(await page.textContent('p')).toBe('This is a nested layout component'); - expect(await page.textContent('h1')).toBe('Hello from inside the nested layout component'); + await expect(page.locator('footer')).toHaveText('Custom layout'); + await expect(page.locator('p')).toHaveText('This is a nested layout component'); + await expect(page.locator('h1')).toHaveText('Hello from inside the nested layout component'); }); test('renders errors in the right layout', async ({ page }) => { await page.goto('/nested-layout/error'); - expect(await page.textContent('footer')).toBe('Custom layout'); + await expect(page.locator('footer')).toHaveText('Custom layout'); expect(await page.$('p#nested')).toBeNull(); - expect(await page.textContent('#message')).toBe( + await expect(page.locator('#message')).toHaveText( 'This is your custom error page saying: "Error"' ); - expect(await page.textContent('h1')).toBe('500'); + await expect(page.locator('h1')).toHaveText('500'); }); test('renders errors in the right layout after client navigation', async ({ page, clicknav }) => { await page.goto('/nested-layout/'); await clicknav('[href="/nested-layout/error"]'); - expect(await page.textContent('footer')).toBe('Custom layout'); + await expect(page.locator('footer')).toHaveText('Custom layout'); expect(await page.$('p#nested')).toBe(null); - expect(await page.textContent('#message')).toBe( + await expect(page.locator('#message')).toHaveText( 'This is your custom error page saying: "Error"' ); - expect(await page.textContent('h1')).toBe('500'); + await expect(page.locator('h1')).toHaveText('500'); }); test('renders deeply-nested errors in the right layout', async ({ page }) => { await page.goto('/nested-layout/foo/bar/nope'); - expect(await page.textContent('footer')).toBe('Custom layout'); + await expect(page.locator('footer')).toHaveText('Custom layout'); expect(await page.$('p#nested')).not.toBeNull(); expect(await page.$('p#nested-foo')).not.toBeNull(); expect(await page.$('p#nested-bar')).not.toBeNull(); - expect(await page.textContent('#nested-error-message')).toBe( + await expect(page.locator('#nested-error-message')).toHaveText( 'error.message: nope (500 Internal Error)' ); }); @@ -656,8 +658,8 @@ test.describe('Nested layouts', () => { test('resets layout', async ({ page }) => { await page.goto('/nested-layout/reset'); - expect(await page.textContent('h1')).toBe('Layout reset'); - expect(await page.textContent('h2')).toBe('Hello'); + await expect(page.locator('h1')).toHaveText('Layout reset'); + await expect(page.locator('h2')).toHaveText('Hello'); expect(await page.$('#nested')).toBeNull(); }); @@ -666,9 +668,9 @@ test.describe('Nested layouts', () => { await clicknav('[href="/errors/nested-error-page/nope"]'); - expect(await page.textContent('h1')).toBe('Nested error page'); - expect(await page.textContent('#nested-error-status')).toBe('status: 500'); - expect(await page.textContent('#nested-error-message')).toBe( + await expect(page.locator('h1')).toHaveText('Nested error page'); + await expect(page.locator('#nested-error-status')).toHaveText('status: 500'); + await expect(page.locator('#nested-error-message')).toHaveText( 'error.message: nope (500 Internal Error)' ); }); @@ -681,7 +683,7 @@ test.describe('Page options', () => { }) => { if (!javaScriptEnabled) { await page.goto('/no-csr'); - expect(await page.textContent('h1')).toBe('look ma no javascript'); + await expect(page.locator('h1')).toHaveText('look ma no javascript'); expect(await page.$$('link[rel="modulepreload"]')).toHaveLength(0); // ensure data wasn't inlined @@ -693,7 +695,7 @@ test.describe('Page options', () => { await page.goto('/no-ssr'); if (javaScriptEnabled) { - expect(await page.textContent('h1')).toBe('content was rendered'); + await expect(page.locator('h1')).toHaveText('content was rendered'); } else { expect(await page.$('h1')).toBeNull(); expect(await page.$('style[data-sveltekit]')).toBeNull(); @@ -725,7 +727,7 @@ test.describe('Page options', () => { test.describe('$app/environment', () => { test('includes version', async ({ page }) => { await page.goto('/app-environment'); - expect(await page.textContent('h1')).toBe('TEST_VERSION'); + await expect(page.locator('h1')).toHaveText('TEST_VERSION'); }); }); @@ -772,7 +774,7 @@ test.describe('$app/paths', () => { test.describe('$app/stores', () => { test('can access page.url', async ({ baseURL, page }) => { await page.goto('/origin'); - expect(await page.textContent('h1')).toBe(baseURL); + await expect(page.locator('h1')).toHaveText(baseURL); }); test('page store contains data', async ({ page, clicknav }) => { @@ -780,26 +782,26 @@ test.describe('$app/stores', () => { const foo = { bar: 'Custom layout' }; - expect(await page.textContent('#store-data')).toBe( + await expect(page.locator('#store-data')).toHaveText( JSON.stringify({ foo, name: 'SvelteKit', value: 456, page: 'www' }) ); await clicknav('a[href="/store/data/zzz"]'); - expect(await page.textContent('#store-data')).toBe( + await expect(page.locator('#store-data')).toHaveText( JSON.stringify({ foo, name: 'SvelteKit', value: 456, page: 'zzz' }) ); await clicknav('a[href="/store/data/xxx"]'); - expect(await page.textContent('#store-data')).toBe( + await expect(page.locator('#store-data')).toHaveText( JSON.stringify({ foo, name: 'SvelteKit', value: 123 }) ); - expect(await page.textContent('#store-error')).toBe('Params = xxx'); + await expect(page.locator('#store-error')).toHaveText('Params = xxx'); await clicknav('a[href="/store/data/yyy"]'); - expect(await page.textContent('#store-data')).toBe( + await expect(page.locator('#store-data')).toHaveText( JSON.stringify({ foo, name: 'SvelteKit', value: 123 }) ); - expect(await page.textContent('#store-error')).toBe('Params = yyy'); + await expect(page.locator('#store-error')).toHaveText('Params = yyy'); }); test('should load data after reloading by goto', async ({ @@ -814,35 +816,35 @@ test.describe('$app/stores', () => { await page.goto('/store/data/www'); await clicknav('a[href="/store/data/foo"]'); - expect(JSON.parse((await page.textContent('#store-data')) ?? '')).toEqual(stuff1); + expect(JSON.parse((await page.locator('#store-data').textContent()) ?? '')).toEqual(stuff1); await clicknav('#reload-button'); - expect(JSON.parse((await page.textContent('#store-data')) ?? '')).toEqual( + expect(JSON.parse((await page.locator('#store-data').textContent()) ?? '')).toEqual( javaScriptEnabled ? stuff2 : stuff1 ); await clicknav('a[href="/store/data/zzz"]'); await clicknav('a[href="/store/data/foo"]'); - expect(JSON.parse((await page.textContent('#store-data')) ?? '')).toEqual(stuff3); + expect(JSON.parse((await page.locator('#store-data').textContent()) ?? '')).toEqual(stuff3); }); test('navigating store contains from, to and type', async ({ app, page, javaScriptEnabled }) => { await page.goto('/store/navigating/a'); - expect(await page.textContent('#nav-status')).toBe('not currently navigating'); + await expect(page.locator('#nav-status')).toHaveText('not currently navigating'); if (javaScriptEnabled) { await app.preloadCode('/store/navigating/b'); const res = await Promise.all([ page.click('a[href="/store/navigating/b"]'), - page.textContent('#navigating') + page.locator('#navigating').textContent() ]); expect(res[1]).toBe('navigating from /store/navigating/a to /store/navigating/b (link)'); await page.waitForSelector('#not-navigating'); - expect(await page.textContent('#nav-status')).toBe('not currently navigating'); + await expect(page.locator('#nav-status')).toHaveText('not currently navigating'); await Promise.all([ expect(page.locator('#navigating')).toHaveText( @@ -856,7 +858,7 @@ test.describe('$app/stores', () => { test('navigating store clears after aborted navigation', async ({ page, javaScriptEnabled }) => { await page.goto('/store/navigating/a'); - expect(await page.textContent('#nav-status')).toBe('not currently navigating'); + await expect(page.locator('#nav-status')).toHaveText('not currently navigating'); if (javaScriptEnabled) { await page.click('a[href="/store/navigating/c"]'); @@ -864,7 +866,7 @@ test.describe('$app/stores', () => { await page.click('a[href="/store/navigating/a"]'); await page.waitForSelector('#not-navigating', { timeout: 5000 }); - expect(await page.textContent('#nav-status')).toBe('not currently navigating'); + await expect(page.locator('#nav-status')).toHaveText('not currently navigating'); } }); @@ -876,7 +878,7 @@ test.describe('$app/stores', () => { const href = `${baseURL}/store/data/zzz`; await page.goto(href); - expect(await page.textContent('#url-hash')).toBe(''); + await expect(page.locator('#url-hash')).toHaveText(''); if (javaScriptEnabled) { for (const urlHash of ['#1', '#2', '#5', '#8']) { @@ -887,7 +889,7 @@ test.describe('$app/stores', () => { { href, urlHash } ); - expect(await page.textContent('#url-hash')).toBe(urlHash); + await expect(page.locator('#url-hash')).toHaveText(urlHash); } } }); @@ -896,7 +898,7 @@ test.describe('$app/stores', () => { test.describe('$app/state', () => { test('can access page.url', async ({ baseURL, page }) => { await page.goto('/origin'); - expect(await page.textContent('h1')).toBe(baseURL); + await expect(page.locator('h1')).toHaveText(baseURL); }); test('page state contains data', async ({ page, clicknav }) => { @@ -904,26 +906,26 @@ test.describe('$app/state', () => { const foo = { bar: 'Custom layout' }; - expect(await page.textContent('#state-data')).toBe( + await expect(page.locator('#state-data')).toHaveText( JSON.stringify({ foo, name: 'SvelteKit', value: 456, page: 'www' }) ); await clicknav('a[href="/state/data/zzz"]'); - expect(await page.textContent('#state-data')).toBe( + await expect(page.locator('#state-data')).toHaveText( JSON.stringify({ foo, name: 'SvelteKit', value: 456, page: 'zzz' }) ); await clicknav('a[href="/state/data/xxx"]'); - expect(await page.textContent('#state-data')).toBe( + await expect(page.locator('#state-data')).toHaveText( JSON.stringify({ foo, name: 'SvelteKit', value: 123 }) ); - expect(await page.textContent('#state-error')).toBe('Params = xxx'); + await expect(page.locator('#state-error')).toHaveText('Params = xxx'); await clicknav('a[href="/state/data/yyy"]'); - expect(await page.textContent('#state-data')).toBe( + await expect(page.locator('#state-data')).toHaveText( JSON.stringify({ foo, name: 'SvelteKit', value: 123 }) ); - expect(await page.textContent('#state-error')).toBe('Params = yyy'); + await expect(page.locator('#state-error')).toHaveText('Params = yyy'); }); test('should load data after reloading by goto', async ({ @@ -938,35 +940,35 @@ test.describe('$app/state', () => { await page.goto('/state/data/www'); await clicknav('a[href="/state/data/foo"]'); - expect(JSON.parse((await page.textContent('#state-data')) ?? '')).toEqual(stuff1); + expect(JSON.parse((await page.locator('#state-data').textContent()) ?? '')).toEqual(stuff1); await clicknav('#reload-button'); - expect(JSON.parse((await page.textContent('#state-data')) ?? '')).toEqual( + expect(JSON.parse((await page.locator('#state-data').textContent()) ?? '')).toEqual( javaScriptEnabled ? stuff2 : stuff1 ); await clicknav('a[href="/state/data/zzz"]'); await clicknav('a[href="/state/data/foo"]'); - expect(JSON.parse((await page.textContent('#state-data')) ?? '')).toEqual(stuff3); + expect(JSON.parse((await page.locator('#state-data').textContent()) ?? '')).toEqual(stuff3); }); test('navigating state contains from, to and type', async ({ app, page, javaScriptEnabled }) => { await page.goto('/state/navigating/a'); - expect(await page.textContent('#nav-status')).toBe('not currently navigating'); + await expect(page.locator('#nav-status')).toHaveText('not currently navigating'); if (javaScriptEnabled) { await app.preloadCode('/state/navigating/b'); const res = await Promise.all([ page.click('a[href="/state/navigating/b"]'), - page.textContent('#navigating') + page.locator('#navigating').textContent() ]); expect(res[1]).toBe('navigating from /state/navigating/a to /state/navigating/b (link)'); await page.waitForSelector('#not-navigating'); - expect(await page.textContent('#nav-status')).toBe('not currently navigating'); + await expect(page.locator('#nav-status')).toHaveText('not currently navigating'); await Promise.all([ expect(page.locator('#navigating')).toHaveText( @@ -980,7 +982,7 @@ test.describe('$app/state', () => { test('navigating state clears after aborted navigation', async ({ page, javaScriptEnabled }) => { await page.goto('/state/navigating/a'); - expect(await page.textContent('#nav-status')).toBe('not currently navigating'); + await expect(page.locator('#nav-status')).toHaveText('not currently navigating'); if (javaScriptEnabled) { await page.click('a[href="/state/navigating/c"]'); @@ -988,7 +990,7 @@ test.describe('$app/state', () => { await page.click('a[href="/state/navigating/a"]'); await page.waitForSelector('#not-navigating', { timeout: 5000 }); - expect(await page.textContent('#nav-status')).toBe('not currently navigating'); + await expect(page.locator('#nav-status')).toHaveText('not currently navigating'); } }); @@ -1000,7 +1002,7 @@ test.describe('$app/state', () => { const href = `${baseURL}/state/data/zzz`; await page.goto(href); - expect(await page.textContent('#url-hash')).toBe(''); + await expect(page.locator('#url-hash')).toHaveText(''); if (javaScriptEnabled) { for (const urlHash of ['#1', '#2', '#5', '#8']) { @@ -1011,7 +1013,7 @@ test.describe('$app/state', () => { { href, urlHash } ); - expect(await page.textContent('#url-hash')).toBe(urlHash); + await expect(page.locator('#url-hash')).toHaveText(urlHash); } } }); @@ -1047,8 +1049,8 @@ test.describe('searchParams', () => { const json = JSON.stringify(expected); - expect(await page.textContent('#one')).toBe(json); - expect(await page.textContent('#two')).toBe(json); + await expect(page.locator('#one')).toHaveText(json); + await expect(page.locator('#two')).toHaveText(json); }); }); @@ -1059,8 +1061,8 @@ test.describe('searchParams', () => { const json = JSON.stringify({ bar: ['2'] }); - expect(await page.textContent('#one')).toBe(json); - expect(await page.textContent('#two')).toBe(json); + await expect(page.locator('#one')).toHaveText(json); + await expect(page.locator('#two')).toHaveText(json); }); }); @@ -1069,16 +1071,16 @@ test.describe('Matchers', () => { await page.goto('/routing/matched'); await clicknav('[href="/routing/matched/a"]'); - expect(await page.textContent('h1')).toBe('lowercase: a'); + await expect(page.locator('h1')).toHaveText('lowercase: a'); await clicknav('[href="/routing/matched/B"]'); - expect(await page.textContent('h1')).toBe('uppercase: B'); + await expect(page.locator('h1')).toHaveText('uppercase: B'); await clicknav('[href="/routing/matched/1"]'); - expect(await page.textContent('h1')).toBe('number: 1'); + await expect(page.locator('h1')).toHaveText('number: 1'); await clicknav('[href="/routing/matched/everything-else"]'); - expect(await page.textContent('h1')).toBe('fallback: everything-else'); + await expect(page.locator('h1')).toHaveText('fallback: everything-else'); }); }); @@ -1127,9 +1129,9 @@ test.describe('Actions', () => { test('Error props are returned', async ({ page, javaScriptEnabled }) => { await page.goto('/actions/form-errors'); await page.click('button'); - expect(await page.textContent('p.server-prop')).toBe('an error occurred'); + await expect(page.locator('p.server-prop')).toHaveText('an error occurred'); if (javaScriptEnabled) { - expect(await page.textContent('p.client-prop')).toBe('hydrated: an error occurred'); + await expect(page.locator('p.client-prop')).toHaveText('hydrated: an error occurred'); } }); @@ -1146,7 +1148,7 @@ test.describe('Actions', () => { expect(await page.inputValue('input[name="username"]')).toBe('foo'); if (javaScriptEnabled) { expect(await page.inputValue('input[name="password"]')).toBe('bar'); - expect(await page.textContent('pre')).toBe(JSON.stringify({ username: 'foo' })); + await expect(page.locator('pre')).toHaveText(JSON.stringify({ username: 'foo' })); } else { expect(await page.inputValue('input[name="password"]')).toBe(''); } @@ -1155,7 +1157,7 @@ test.describe('Actions', () => { test('Success data as form-data is returned', async ({ page }) => { await page.goto('/actions/success-data'); - expect(await page.textContent('pre')).toBe(JSON.stringify(null)); + await expect(page.locator('pre')).toHaveText(JSON.stringify(null)); await page.locator('input[name="username"]').fill('foo'); await page.locator('button[formenctype="multipart/form-data"]').click(); @@ -1166,7 +1168,7 @@ test.describe('Actions', () => { test('Success data as form-urlencoded is returned', async ({ page }) => { await page.goto('/actions/success-data'); - expect(await page.textContent('pre')).toBe(JSON.stringify(null)); + await expect(page.locator('pre')).toHaveText(JSON.stringify(null)); await page.locator('input[name="username"]').fill('bar'); await page.locator('button[formenctype="application/x-www-form-urlencoded"]').click(); @@ -1176,7 +1178,7 @@ test.describe('Actions', () => { test('applyAction updates form prop', async ({ page, javaScriptEnabled }) => { await page.goto('/actions/update-form'); - expect(await page.textContent('pre')).toBe(JSON.stringify(null)); + await expect(page.locator('pre')).toHaveText(JSON.stringify(null)); if (javaScriptEnabled) { await page.locator('button.increment-success').click(); @@ -1193,7 +1195,7 @@ test.describe('Actions', () => { javaScriptEnabled }) => { await page.goto('/actions/update-form'); - expect(await page.textContent('pre')).toBe(JSON.stringify(null)); + await expect(page.locator('pre')).toHaveText(JSON.stringify(null)); if (javaScriptEnabled) { await page.locator('button.increment-success').click(); @@ -1207,12 +1209,12 @@ test.describe('Actions', () => { await page.goto('/actions/enhance'); } - expect(await page.textContent('pre.formdata1')).toBe(JSON.stringify(null)); + await expect(page.locator('pre.formdata1')).toHaveText(JSON.stringify(null)); }); test('applyAction redirects', async ({ page, javaScriptEnabled }) => { await page.goto('/actions/update-form'); - expect(await page.textContent('pre')).toBe(JSON.stringify(null)); + await expect(page.locator('pre')).toHaveText(JSON.stringify(null)); if (javaScriptEnabled) { await page.locator('button.redirect').click(); @@ -1222,7 +1224,7 @@ test.describe('Actions', () => { test('applyAction errors', async ({ page, javaScriptEnabled }) => { await page.goto('/actions/update-form'); - expect(await page.textContent('pre')).toBe(JSON.stringify(null)); + await expect(page.locator('pre')).toHaveText(JSON.stringify(null)); if (javaScriptEnabled) { await page.locator('button.error').click(); @@ -1235,8 +1237,8 @@ test.describe('Actions', () => { test('use:enhance', async ({ page }) => { await page.goto('/actions/enhance'); - expect(await page.textContent('pre.formdata1')).toBe(JSON.stringify(null)); - expect(await page.textContent('pre.formdata2')).toBe(JSON.stringify(null)); + await expect(page.locator('pre.formdata1')).toHaveText(JSON.stringify(null)); + await expect(page.locator('pre.formdata2')).toHaveText(JSON.stringify(null)); await page.locator('input[name="username"]').fill('foo'); await page.locator('button.form1').click(); @@ -1249,7 +1251,7 @@ test.describe('Actions', () => { test('use:enhance abort controller', async ({ page, javaScriptEnabled }) => { await page.goto('/actions/enhance'); - expect(await page.textContent('span.count')).toBe('0'); + await expect(page.locator('span.count')).toHaveText('0'); if (javaScriptEnabled) { await Promise.all([ @@ -1266,7 +1268,7 @@ test.describe('Actions', () => { test('use:enhance button with formAction', async ({ page }) => { await page.goto('/actions/enhance'); - expect(await page.textContent('pre.formdata1')).toBe(JSON.stringify(null)); + await expect(page.locator('pre.formdata1')).toHaveText(JSON.stringify(null)); await page.locator('input[name="username"]').fill('foo'); await page.locator('button.form1-register').click(); @@ -1287,7 +1289,7 @@ test.describe('Actions', () => { test('use:enhance button with name', async ({ page }) => { await page.goto('/actions/enhance'); - expect(await page.textContent('pre.formdata1')).toBe(JSON.stringify(null)); + await expect(page.locator('pre.formdata1')).toHaveText(JSON.stringify(null)); await Promise.all([ page.waitForRequest((request) => request.url().includes('/actions/enhance')), @@ -1302,8 +1304,8 @@ test.describe('Actions', () => { test('use:enhance button with formenctype', async ({ page }) => { await page.goto('/actions/enhance'); - expect(await page.textContent('pre.formdata1')).toBe(JSON.stringify(null)); - expect(await page.textContent('pre.formdata2')).toBe(JSON.stringify(null)); + await expect(page.locator('pre.formdata1')).toHaveText(JSON.stringify(null)); + await expect(page.locator('pre.formdata2')).toHaveText(JSON.stringify(null)); const fileInput = page.locator('input[type="file"].form-file-input'); @@ -1331,8 +1333,8 @@ test.describe('Actions', () => { await page.goto('/actions/enhance'); - expect(await page.textContent('pre.formdata1')).toBe(JSON.stringify(null)); - expect(await page.textContent('pre.formdata2')).toBe(JSON.stringify(null)); + await expect(page.locator('pre.formdata1')).toHaveText(JSON.stringify(null)); + await expect(page.locator('pre.formdata2')).toHaveText(JSON.stringify(null)); await page.locator('input[name="username"]').fill('foo'); @@ -1588,15 +1590,15 @@ test.describe('getRequestEvent', () => { await page.goto('/get-request-event'); await clicknav('[href="/get-request-event/with-message"]'); - expect(await page.textContent('h1')).toBe('hello from hooks.server.js'); + await expect(page.locator('h1')).toHaveText('hello from hooks.server.js'); await page.locator('input[name="message"]').fill('hello'); await page.click('button'); - expect(await page.textContent('h1')).toBe('from form: hello'); + await expect(page.locator('h1')).toHaveText('from form: hello'); await page.goto('/get-request-event/with-error'); - expect(await page.textContent('h1')).toBe('Crashing now (500 hello from hooks.server.js)'); + await expect(page.locator('h1')).toHaveText('Crashing now (500 hello from hooks.server.js)'); }); }); diff --git a/packages/kit/test/apps/dev-only/test/test.js b/packages/kit/test/apps/dev-only/test/test.js index 1b9099a923f1..39afeec31d45 100644 --- a/packages/kit/test/apps/dev-only/test/test.js +++ b/packages/kit/test/apps/dev-only/test/test.js @@ -16,8 +16,8 @@ test.describe.serial('Illegal imports', () => { await page.goto('/illegal-imports/env/dynamic-private', { wait_for_started: false }); - expect(await page.textContent('.message-body')) - .toBe(`Cannot import $env/dynamic/private into code that runs in the browser, as this could leak sensitive information. + await expect(page.locator('.message-body')) + .toHaveText(`Cannot import $env/dynamic/private into code that runs in the browser, as this could leak sensitive information. src/routes/illegal-imports/env/dynamic-private/+page.svelte imports $env/dynamic/private @@ -29,8 +29,8 @@ If you're only using the import as a type, change it to \`import type\`.`); await page.goto('/illegal-imports/env/static-private', { wait_for_started: false }); - expect(await page.textContent('.message-body')) - .toBe(`Cannot import $env/static/private into code that runs in the browser, as this could leak sensitive information. + await expect(page.locator('.message-body')) + .toHaveText(`Cannot import $env/static/private into code that runs in the browser, as this could leak sensitive information. src/routes/illegal-imports/env/static-private/+page.svelte imports $env/static/private @@ -42,8 +42,8 @@ If you're only using the import as a type, change it to \`import type\`.`); await page.goto('/illegal-imports/server-only-modules/static-import', { wait_for_started: false }); - expect(await page.textContent('.message-body')) - .toBe(`Cannot import src/routes/illegal-imports/server-only-modules/illegal.server.js into code that runs in the browser, as this could leak sensitive information. + await expect(page.locator('.message-body')) + .toHaveText(`Cannot import src/routes/illegal-imports/server-only-modules/illegal.server.js into code that runs in the browser, as this could leak sensitive information. src/routes/illegal-imports/server-only-modules/static-import/+page.svelte imports src/routes/illegal-imports/server-only-modules/static-import/foo.js imports @@ -56,8 +56,8 @@ If you're only using the import as a type, change it to \`import type\`.`); await page.goto('/illegal-imports/server-only-modules/static-import-2', { wait_for_started: false }); - expect(await page.textContent('.message-body')) - .toBe(`Cannot import $app/server into code that runs in the browser, as this could leak sensitive information. + await expect(page.locator('.message-body')) + .toHaveText(`Cannot import $app/server into code that runs in the browser, as this could leak sensitive information. src/routes/illegal-imports/server-only-modules/static-import-2/+page.svelte imports $app/server @@ -69,8 +69,8 @@ If you're only using the import as a type, change it to \`import type\`.`); await page.goto('/illegal-imports/server-only-folder/static-import', { wait_for_started: false }); - expect(await page.textContent('.message-body')) - .toBe(`Cannot import $lib/server/blah/private.js into code that runs in the browser, as this could leak sensitive information. + await expect(page.locator('.message-body')) + .toHaveText(`Cannot import $lib/server/blah/private.js into code that runs in the browser, as this could leak sensitive information. src/routes/illegal-imports/server-only-folder/static-import/+page.svelte imports $lib/server/blah/private.js diff --git a/packages/kit/test/apps/embed/test/test.js b/packages/kit/test/apps/embed/test/test.js index c697a71a8f63..d9a5b4292aed 100644 --- a/packages/kit/test/apps/embed/test/test.js +++ b/packages/kit/test/apps/embed/test/test.js @@ -13,8 +13,8 @@ test.describe('embed', () => { await expect(page.getByTestId('a')).toHaveText('a (browser)'); await expect(page.getByTestId('b')).toHaveText('b (browser)'); } else { - expect(await page.textContent('[data-testid="a"]')).toBe('a (server)'); - expect(await page.textContent('[data-testid="b"]')).toBe('b (server)'); + await expect(page.locator('[data-testid="a"]')).toHaveText('a (server)'); + await expect(page.locator('[data-testid="b"]')).toHaveText('b (server)'); } }); }); diff --git a/packages/kit/test/apps/no-ssr/test/test.js b/packages/kit/test/apps/no-ssr/test/test.js index 7b8c859a9e37..8aa72093a633 100644 --- a/packages/kit/test/apps/no-ssr/test/test.js +++ b/packages/kit/test/apps/no-ssr/test/test.js @@ -7,14 +7,14 @@ test.describe.configure({ mode: 'parallel' }); test('navigating to a non-existent route renders the default error page', async ({ page }) => { await page.goto('/non-existent-route'); - expect(await page.textContent('h1')).toBe('404'); + await expect(page.locator('h1')).toHaveText('404'); }); test('navigating to a non-existent route redirects if redirect in the root layout', async ({ page }) => { await page.goto('/redirect'); - expect(await page.textContent('h1')).toBe('home'); + await expect(page.locator('h1')).toHaveText('home'); }); test('universal pages/layouts are not executed on the server', async ({ page }) => { diff --git a/packages/kit/test/apps/options-2/test/test.js b/packages/kit/test/apps/options-2/test/test.js index f3df40146a8d..a3459406bf09 100644 --- a/packages/kit/test/apps/options-2/test/test.js +++ b/packages/kit/test/apps/options-2/test/test.js @@ -11,15 +11,15 @@ test.describe.configure({ mode: 'parallel' }); test.describe('env', () => { test('resolves upwards', async ({ page }) => { await page.goto('/basepath/env'); - expect(await page.textContent('[data-testid="static"]')).toBe('static: resolves upwards!'); - expect(await page.textContent('[data-testid="dynamic"]')).toBe('dynamic: resolves upwards!'); + await expect(page.locator('[data-testid="static"]')).toHaveText('static: resolves upwards!'); + await expect(page.locator('[data-testid="dynamic"]')).toHaveText('dynamic: resolves upwards!'); }); }); test.describe('paths', () => { test('serves /basepath', async ({ page }) => { await page.goto('/basepath'); - expect(await page.textContent('h1')).toBe('Hello'); + await expect(page.locator('h1')).toHaveText('Hello'); }); test('serves assets from /basepath', async ({ request }) => { @@ -31,14 +31,14 @@ test.describe('paths', () => { await page.goto('/basepath'); let base = javaScriptEnabled ? '/basepath' : '.'; - expect(await page.textContent('[data-testid="base"]')).toBe(`base: ${base}`); - expect(await page.textContent('[data-testid="assets"]')).toBe(`assets: ${base}`); + await expect(page.locator('[data-testid="base"]')).toHaveText(`base: ${base}`); + await expect(page.locator('[data-testid="assets"]')).toHaveText(`assets: ${base}`); await page.goto('/basepath/deeply/nested/page'); base = javaScriptEnabled ? '/basepath' : '../..'; - expect(await page.textContent('[data-testid="base"]')).toBe(`base: ${base}`); - expect(await page.textContent('[data-testid="assets"]')).toBe(`assets: ${base}`); + await expect(page.locator('[data-testid="base"]')).toHaveText(`base: ${base}`); + await expect(page.locator('[data-testid="assets"]')).toHaveText(`assets: ${base}`); }); test('serves /basepath with trailing slash always', async ({ page }) => { @@ -118,7 +118,7 @@ test.describe('trailing slash', () => { await page.goto('/basepath/trailing-slash-server'); await clicknav('a[href="/basepath/trailing-slash-server/prerender"]'); - expect(await page.textContent('h2')).toBe('/basepath/trailing-slash-server/prerender/'); + await expect(page.locator('h2')).toHaveText('/basepath/trailing-slash-server/prerender/'); }); } }); diff --git a/packages/kit/test/apps/options/test/test.js b/packages/kit/test/apps/options/test/test.js index 8148bf7ed8f0..bfeaf1a457fa 100644 --- a/packages/kit/test/apps/options/test/test.js +++ b/packages/kit/test/apps/options/test/test.js @@ -25,11 +25,11 @@ test.describe('base path', () => { test('serves /', async ({ page, javaScriptEnabled }) => { await page.goto('/path-base/'); - expect(await page.textContent('h1')).toBe('I am in the template'); - expect(await page.textContent('h2')).toBe("We're on index.svelte"); + await expect(page.locator('h1')).toHaveText('I am in the template'); + await expect(page.locator('h2')).toHaveText("We're on index.svelte"); const mode = process.env.DEV ? 'dev' : 'prod'; - expect(await page.textContent('p')).toBe( + await expect(page.locator('p')).toHaveText( `Hello from the ${javaScriptEnabled ? 'client' : 'server'} in ${mode} mode!` ); }); @@ -46,13 +46,13 @@ test.describe('base path', () => { test('paths available on server side', async ({ page }) => { await page.goto('/path-base/base/'); - expect(await page.textContent('[data-source="base"]')).toBe('/path-base'); - expect(await page.textContent('[data-source="assets"]')).toBe('/_svelte_kit_assets'); + await expect(page.locator('[data-source="base"]')).toHaveText('/path-base'); + await expect(page.locator('[data-source="assets"]')).toHaveText('/_svelte_kit_assets'); }); test('loads javascript', async ({ page, javaScriptEnabled }) => { await page.goto('/path-base/base/'); - expect(await page.textContent('button')).toBe('clicks: 0'); + await expect(page.locator('button')).toHaveText('clicks: 0'); if (javaScriptEnabled) { await page.click('button'); @@ -88,17 +88,17 @@ test.describe('base path', () => { test('sets params correctly', async ({ page, clicknav }) => { await page.goto('/path-base/base/one'); - expect(await page.textContent('h2')).toBe('one'); + await expect(page.locator('h2')).toHaveText('one'); await clicknav('[href="/path-base/base/two"]'); - expect(await page.textContent('h2')).toBe('two'); + await expect(page.locator('h2')).toHaveText('two'); }); test('resolveRoute accounts for base path', async ({ baseURL, page, clicknav }) => { await page.goto('/path-base/resolve-route'); await clicknav('[data-id=target]'); expect(page.url()).toBe(`${baseURL}/path-base/resolve-route/resolved/`); - expect(await page.textContent('h2')).toBe('resolved'); + await expect(page.locator('h2')).toHaveText('resolved'); }); }); @@ -136,7 +136,7 @@ test.describe('CSP', () => { expect(response?.headers()['content-security-policy']).toMatch( /require-trusted-types-for 'script'/ ); - expect(await page.textContent('h2')).toBe('Moo Deng!'); + await expect(page.locator('h2')).toHaveText('Moo Deng!'); }); test("quotes 'script'", async ({ page }) => { @@ -150,36 +150,36 @@ test.describe('CSP', () => { test.describe('Custom extensions', () => { test('works with arbitrary extensions', async ({ page }) => { await page.goto('/path-base/custom-extensions/'); - expect(await page.textContent('h2')).toBe('Great success!'); + await expect(page.locator('h2')).toHaveText('Great success!'); }); test('works with other arbitrary extensions', async ({ page }) => { await page.goto('/path-base/custom-extensions/const'); - expect(await page.textContent('h2')).toBe('Tremendous!'); + await expect(page.locator('h2')).toHaveText('Tremendous!'); await page.goto('/path-base/custom-extensions/a'); - expect(await page.textContent('h2')).toBe('a'); + await expect(page.locator('h2')).toHaveText('a'); await page.goto('/path-base/custom-extensions/test-slug'); - expect(await page.textContent('h2')).toBe('TEST-SLUG'); + await expect(page.locator('h2')).toHaveText('TEST-SLUG'); await page.goto('/path-base/custom-extensions/unsafe-replacement'); - expect(await page.textContent('h2')).toBe('Bazooom!'); + await expect(page.locator('h2')).toHaveText('Bazooom!'); }); }); test.describe('env', () => { test('resolves downwards', async ({ page }) => { await page.goto('/path-base/env'); - expect(await page.textContent('#public')).toBe('and thank you'); + await expect(page.locator('#public')).toHaveText('and thank you'); }); test('respects private prefix', async ({ page }) => { await page.goto('/path-base/env'); - expect(await page.textContent('#private')).toBe('shhhh'); - expect(await page.textContent('#neither')).toBe(''); + await expect(page.locator('#private')).toHaveText('shhhh'); + await expect(page.locator('#neither')).toHaveText(''); }); }); @@ -198,11 +198,11 @@ test.describe('trailingSlash', () => { await page.goto('/path-base/slash'); expect(page.url()).toBe(`${baseURL}/path-base/slash/`); - expect(await page.textContent('h2')).toBe('/path-base/slash/'); + await expect(page.locator('h2')).toHaveText('/path-base/slash/'); await clicknav('[data-testid="child"]'); expect(page.url()).toBe(`${baseURL}/path-base/slash/child/`); - expect(await page.textContent('h2')).toBe('/path-base/slash/child/'); + await expect(page.locator('h2')).toHaveText('/path-base/slash/child/'); }); test('removes trailing slash on endpoint', async ({ baseURL, request }) => { @@ -339,7 +339,7 @@ test.describe('Vite options', () => { await page.goto('/path-base/mode'); const mode = process.env.DEV ? 'development' : 'custom'; - expect(await page.textContent('h2')).toBe(`${mode} === ${mode} === ${mode}`); + await expect(page.locator('h2')).toHaveText(`${mode} === ${mode} === ${mode}`); }); }); diff --git a/packages/kit/test/apps/prerendered-app-error-pages/test/test.js b/packages/kit/test/apps/prerendered-app-error-pages/test/test.js index c1328e6aa556..c40d309ae9b7 100644 --- a/packages/kit/test/apps/prerendered-app-error-pages/test/test.js +++ b/packages/kit/test/apps/prerendered-app-error-pages/test/test.js @@ -5,5 +5,5 @@ test.describe.configure({ mode: 'parallel' }); test('renders error page on nonexistent route', async ({ page }) => { await page.goto('/nonexistent', { wait_for_started: false }); - expect(await page.textContent('p')).toBe('This is your custom error page.'); + await expect(page.locator('p')).toHaveText('This is your custom error page.'); }); diff --git a/packages/kit/test/apps/writes/test/test.js b/packages/kit/test/apps/writes/test/test.js index e513c647f37d..d6a38f641374 100644 --- a/packages/kit/test/apps/writes/test/test.js +++ b/packages/kit/test/apps/writes/test/test.js @@ -28,7 +28,7 @@ test.describe('Filesystem updates', () => { await page.waitForTimeout(500); // this is the rare time we actually need waitForTimeout; we have no visibility into whether the module graph has been invalidated await page.goto(`/new-route/${route}`); - expect(await page.textContent('h1')).toBe(content); + await expect(page.locator('h1')).toHaveText(content); } finally { fs.rmSync(dir, { recursive: true }); } @@ -45,10 +45,10 @@ test.describe('Filesystem updates', () => { // we write to the file, to trigger HMR invalidation fs.writeFileSync(file, contents.replace(/PLACEHOLDER:\d+/, `PLACEHOLDER:${Date.now()}`)); await page.goto('/double-mount'); - expect(await page.textContent('h1')).toBe(`mounted: ${mounted}`); + await expect(page.locator('h1')).toHaveText(`mounted: ${mounted}`); await page.click('button'); await page.waitForTimeout(100); - expect(await page.textContent('h1')).toBe(`mounted: ${mounted}`); + await expect(page.locator('h1')).toHaveText(`mounted: ${mounted}`); } finally { fs.writeFileSync(file, contents.replace(/PLACEHOLDER:\d+/, 'PLACEHOLDER:0')); }