Skip to content

Commit

Permalink
Announce page changes (#311)
Browse files Browse the repository at this point in the history
* rename tests

* announce page changes (#307)

* try to reduce flakiness
  • Loading branch information
Rich Harris authored Jan 7, 2021
1 parent 72da270 commit c29b61e
Show file tree
Hide file tree
Showing 11 changed files with 80 additions and 10 deletions.
5 changes: 5 additions & 0 deletions .changeset/selfish-avocados-develop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/kit': patch
---

Announce page changes
38 changes: 37 additions & 1 deletion packages/kit/src/core/create_app.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ function generate_app(manifest_data) {
return trim(`
<!-- This file is generated by @sveltejs/kit — do not edit it! -->
<script>
import { setContext, afterUpdate } from 'svelte';
import { setContext, afterUpdate, onMount } from 'svelte';
import ErrorComponent from ${JSON.stringify(manifest_data.error.url)};
// error handling
Expand All @@ -153,6 +153,22 @@ function generate_app(manifest_data) {
$: stores.page.set(page);
afterUpdate(stores.page.notify);
let mounted = false;
let navigated = false;
let title = null;
onMount(() => {
const unsubscribe = stores.page.subscribe(() => {
if (mounted) {
navigated = true;
title = document.title;
}
});
mounted = true;
return unsubscribe;
});
</script>
<Layout {...(props_0 || {})}>
Expand All @@ -162,5 +178,25 @@ function generate_app(manifest_data) {
${pyramid.replace(/\n/g, '\n\t\t\t\t')}
{/if}
</Layout>
{#if mounted}
<div id="svelte-announcer" aria-live="assertive" aria-atomic="true">
{#if navigated}
Navigated to {title}
{/if}
</div>
{/if}
<style>
#svelte-announcer {
clip: rect(0 0 0 0);
clip-path: inset(50%);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
</style>
`);
}
3 changes: 3 additions & 0 deletions test/apps/basics/src/routes/accessibility/$layout.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<nav><a href="/accessibility/a">a</a> <a href="/accessibility/b">b</a></nav>

<slot />
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,39 @@ import * as assert from 'uvu/assert';

export default function (test) {
test('resets focus', async ({ visit, click, keyboard, evaluate, contains }) => {
await visit('/focus/a');
await visit('/accessibility/a');

await click('[href="/focus/b"]');
await click('[href="/accessibility/b"]');
assert.ok(await contains('b'));
assert.equal(await evaluate(() => document.activeElement.nodeName), 'BODY');
await keyboard.press('Tab');
assert.equal(await evaluate(() => document.activeElement.nodeName), 'A');
assert.equal(await evaluate(() => document.activeElement.textContent), 'a');

await click('[href="/focus/a"]');
await click('[href="/accessibility/a"]');
assert.ok(await contains('a'));
assert.equal(await evaluate(() => document.activeElement.nodeName), 'BODY');
await keyboard.press('Tab');
assert.equal(await evaluate(() => document.activeElement.nodeName), 'A');
assert.equal(await evaluate(() => document.activeElement.textContent), 'a');
});

test('announces client-side navigation', async ({ visit, click, contains, html, sleep, js }) => {
await visit('/accessibility/a');

const has_live_region = await contains('aria-live');

if (js) {
assert.ok(has_live_region);

// live region should exist, but be empty
assert.equal(await html('[aria-live]'), '');

await click('[href="/accessibility/b"]');
await sleep(50);
assert.equal(await html('[aria-live]'), 'Navigated to b'); // TODO i18n
} else {
assert.ok(!has_live_region);
}
});
}
5 changes: 5 additions & 0 deletions test/apps/basics/src/routes/accessibility/a.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<svelte:head>
<title>a</title>
</svelte:head>

<p>a</p>
5 changes: 5 additions & 0 deletions test/apps/basics/src/routes/accessibility/b.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<svelte:head>
<title>b</title>
</svelte:head>

<p>b</p>
3 changes: 0 additions & 3 deletions test/apps/basics/src/routes/focus/$layout.svelte

This file was deleted.

1 change: 0 additions & 1 deletion test/apps/basics/src/routes/focus/a.svelte

This file was deleted.

1 change: 0 additions & 1 deletion test/apps/basics/src/routes/focus/b.svelte

This file was deleted.

3 changes: 2 additions & 1 deletion test/apps/basics/src/routes/routing/__tests__.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ export default function (test) {
capture_requests,
click,
wait_for_function,
sleep,
js
}) => {
if (js) {
Expand All @@ -114,7 +115,7 @@ export default function (test) {

// weird flakiness — without this, some requests are
// reported after prefetch_routes has finished
await new Promise((f) => setTimeout(f, 200));
await sleep(200);

const requests = await capture_requests(async () => {
await click('a[href="/routing/a"]');
Expand Down
1 change: 1 addition & 0 deletions test/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ async function setup({ port }) {
set_extra_http_headers: (headers) => page.setExtraHTTPHeaders(headers),
pathname: () => page.url().replace(base, ''),
keyboard: page.keyboard,
sleep: (ms) => new Promise((f) => setTimeout(f, ms)),
$: (selector) => page.$(selector)
};
}
Expand Down

0 comments on commit c29b61e

Please sign in to comment.