Skip to content

Commit 9d1c523

Browse files
chore: More flaky test fixes (#15020)
* fix fast-running test * fix: form remote function test contention
1 parent 6d5f0d5 commit 9d1c523

File tree

7 files changed

+111
-79
lines changed

7 files changed

+111
-79
lines changed

packages/kit/test/apps/basics/src/routes/remote/form/+page.svelte renamed to packages/kit/test/apps/basics/src/routes/remote/form/[test_name]/+page.svelte

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@
66
set_reverse_message
77
} from './form.remote.js';
88
9-
const message = get_message();
9+
const { params } = $props();
1010
11-
const scoped = set_message.for('scoped');
12-
const enhanced = set_message.for('enhanced');
11+
const message = get_message(params.test_name);
12+
13+
const scoped = set_message.for(`scoped:${params.test_name}`);
14+
const enhanced = set_message.for(`enhanced:${params.test_name}`);
1315
</script>
1416

1517
<p>message.current: {message.current}</p>
@@ -27,6 +29,12 @@
2729
{/if}
2830

2931
<input {...set_message.fields.message.as('text')} />
32+
<input {...set_message.fields.test_name.as('hidden', params.test_name)} />
33+
<!--
34+
NOTE: there really probably should be a `set_reverse_message' test_name hidden field here, but it collides with the one above.
35+
This kind of lines up with our discussions from earlier where we were talking about needing to include the RF hash in the field name.
36+
If we do that and this test starts failing, all we'll need to do is add the hidden field back in.
37+
-->
3038
<button>set message</button>
3139
<button {...set_reverse_message.buttonProps}>set reverse message</button>
3240
</form>
@@ -44,6 +52,7 @@
4452
{/if}
4553

4654
<input {...scoped.fields.message.as('text')} />
55+
<input {...scoped.fields.test_name.as('hidden', params.test_name)} />
4756
<button>set scoped message</button>
4857
</form>
4958

@@ -56,14 +65,17 @@
5665
<form
5766
data-enhanced
5867
{...enhanced.enhance(async ({ data, submit }) => {
59-
await submit().updates(get_message().withOverride(() => data.message + ' (override)'));
68+
await submit().updates(
69+
get_message(params.test_name).withOverride(() => data.message + ' (override)')
70+
);
6071
})}
6172
>
6273
{#if enhanced.fields.message.issues()}
6374
<p>{enhanced.fields.message.issues()[0].message}</p>
6475
{/if}
6576

6677
<input {...enhanced.fields.message.as('text')} />
78+
<input {...enhanced.fields.test_name.as('hidden', params.test_name)} />
6779
<button><span>set enhanced message</span></button>
6880
</form>
6981

@@ -75,4 +87,5 @@
7587

7688
<form {...resolve_deferreds}>
7789
<button>resolve deferreds</button>
90+
<input {...resolve_deferreds.fields.test_name.as('hidden', params.test_name)} />
7891
</form>
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import { form, getRequestEvent, query } from '$app/server';
2+
import { error, redirect } from '@sveltejs/kit';
3+
import * as v from 'valibot';
4+
5+
const instances = new Map<
6+
string,
7+
{ message: string; deferreds: Array<PromiseWithResolvers<void>> }
8+
>();
9+
10+
export const get_message = query(v.string(), (test_name) => {
11+
return instances.get(test_name)?.message || 'initial';
12+
});
13+
14+
export const set_message = form(
15+
v.object({
16+
test_name: v.string(),
17+
id: v.optional(v.string()),
18+
message: v.picklist(
19+
['hello', 'goodbye', 'unexpected error', 'expected error', 'redirect'],
20+
'message is invalid'
21+
),
22+
uppercase: v.optional(v.string())
23+
}),
24+
async (data) => {
25+
if (data.message === 'unexpected error') {
26+
throw new Error('oops');
27+
}
28+
29+
if (data.message === 'expected error') {
30+
error(500, 'oops');
31+
}
32+
33+
if (data.message === 'redirect') {
34+
redirect(303, '/remote');
35+
}
36+
37+
const instance = instances.get(data.test_name) ?? { message: 'initial', deferreds: [] };
38+
instances.set(data.test_name, instance);
39+
40+
instance.message = data.uppercase === 'true' ? data.message.toUpperCase() : data.message;
41+
42+
if (getRequestEvent().isRemoteRequest) {
43+
const deferred = Promise.withResolvers<void>();
44+
instance.deferreds.push(deferred);
45+
await deferred.promise;
46+
}
47+
48+
return instance.message + (data.id ? ` (from: ${data.id})` : '');
49+
}
50+
);
51+
52+
export const set_reverse_message = form(
53+
v.object({ test_name: v.string(), message: v.string() }),
54+
(data) => {
55+
const instance = instances.get(data.test_name) ?? { message: 'initial', deferreds: [] };
56+
instances.set(data.test_name, instance);
57+
instance.message = data.message.split('').reverse().join('');
58+
return instance.message;
59+
}
60+
);
61+
62+
export const resolve_deferreds = form(v.object({ test_name: v.string() }), async (data) => {
63+
const instance = instances.get(data.test_name);
64+
if (!instance) return;
65+
66+
const { deferreds } = instance;
67+
for (const deferred of deferreds) {
68+
deferred.resolve();
69+
}
70+
deferreds.length = 0;
71+
});

packages/kit/test/apps/basics/src/routes/remote/form/form.remote.ts

Lines changed: 0 additions & 56 deletions
This file was deleted.

packages/kit/test/apps/basics/src/routes/remote/form/imperative/+page.svelte

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
<script lang="ts">
2-
import { set_message } from '../form.remote.js';
2+
import { set_message } from '../[test_name]/form.remote.js';
33
import * as v from 'valibot';
44
55
const schema = v.object({
6+
test_name: v.string(),
67
message: v.picklist(
78
['hello', 'goodbye', 'unexpected error', 'expected error', 'redirect'],
89
'message is invalid'
@@ -14,6 +15,7 @@
1415
<label>
1516
<span>Message</span>
1617
<input {...set_message.fields.message.as('text')} />
18+
<input {...set_message.fields.test_name.as('hidden', 'imperative')} />
1719
</label>
1820

1921
<p id="issue">

packages/kit/test/apps/basics/src/routes/routing/hashes/target/+page.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
<li><a href="#p2">second paragraph</a></li>
44
</ol>
55

6-
<p id="p1">paragraph 1</p>
7-
<p id="p2">paragraph 2</p>
6+
<p tabindex="-1" id="p1">paragraph 1</p>
7+
<p tabindex="-1" id="p2">paragraph 2</p>
88

99
<li><button>next focus element</button></li>
1010

packages/kit/test/apps/basics/test/cross-platform/test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -787,8 +787,8 @@ test.describe('Routing', () => {
787787
test('focus works if page load has hash', async ({ page, browserName }) => {
788788
await page.goto('/routing/hashes/target#p2');
789789

790+
await page.waitForSelector('#p2:focus');
790791
await page.keyboard.press(browserName === 'webkit' ? 'Alt+Tab' : 'Tab');
791-
792792
await page.waitForSelector('button:focus');
793793
});
794794

packages/kit/test/apps/basics/test/test.js

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1659,7 +1659,7 @@ test.describe('remote functions', () => {
16591659
});
16601660

16611661
test('form works', async ({ page, javaScriptEnabled }) => {
1662-
await page.goto('/remote/form');
1662+
await page.goto('/remote/form/basic');
16631663

16641664
if (javaScriptEnabled) {
16651665
// TODO remove the `if` — once async SSR lands these assertions should always succeed
@@ -1682,7 +1682,7 @@ test.describe('remote functions', () => {
16821682
}
16831683

16841684
await expect(page.getByText('set_message.result')).toHaveText('set_message.result: hello');
1685-
await expect(page.locator('[data-unscoped] input')).toHaveValue('');
1685+
await expect(page.locator('[data-unscoped] input[name="message"]')).toHaveValue('');
16861686
});
16871687

16881688
test('form submitters work', async ({ page }) => {
@@ -1694,7 +1694,7 @@ test.describe('remote functions', () => {
16941694
});
16951695

16961696
test('form updates inputs live', async ({ page, javaScriptEnabled }) => {
1697-
await page.goto('/remote/form');
1697+
await page.goto('/remote/form/live-update');
16981698

16991699
await page.fill('input', 'hello');
17001700

@@ -1716,7 +1716,7 @@ test.describe('remote functions', () => {
17161716
});
17171717

17181718
test('form reports validation issues', async ({ page }) => {
1719-
await page.goto('/remote/form');
1719+
await page.goto('/remote/form/validation-issues');
17201720

17211721
await page.fill('input', 'invalid');
17221722
await page.getByText('set message').click();
@@ -1725,7 +1725,7 @@ test.describe('remote functions', () => {
17251725
});
17261726

17271727
test('form handles unexpected error', async ({ page }) => {
1728-
await page.goto('/remote/form');
1728+
await page.goto('/remote/form/unexpected-error');
17291729

17301730
await page.fill('input', 'unexpected error');
17311731
await page.getByText('set message').click();
@@ -1736,7 +1736,7 @@ test.describe('remote functions', () => {
17361736
});
17371737

17381738
test('form handles expected error', async ({ page }) => {
1739-
await page.goto('/remote/form');
1739+
await page.goto('/remote/form/expected-error');
17401740

17411741
await page.fill('input', 'expected error');
17421742
await page.getByText('set message').click();
@@ -1745,7 +1745,7 @@ test.describe('remote functions', () => {
17451745
});
17461746

17471747
test('form redirects', async ({ page }) => {
1748-
await page.goto('/remote/form');
1748+
await page.goto('/remote/form/redirect');
17491749

17501750
await page.fill('input', 'redirect');
17511751
await page.getByText('set message').click();
@@ -1754,7 +1754,7 @@ test.describe('remote functions', () => {
17541754
});
17551755

17561756
test('form.buttonProps works', async ({ page, javaScriptEnabled }) => {
1757-
await page.goto('/remote/form');
1757+
await page.goto('/remote/form/button-props');
17581758

17591759
await page.fill('[data-unscoped] input', 'backwards');
17601760
await page.getByText('set reverse message').click();
@@ -1772,7 +1772,7 @@ test.describe('remote functions', () => {
17721772
});
17731773

17741774
test('form scoping with for(...) works', async ({ page, javaScriptEnabled }) => {
1775-
await page.goto('/remote/form');
1775+
await page.goto('/remote/form/form-scoped');
17761776

17771777
await page.fill('[data-scoped] input', 'hello');
17781778
await page.getByText('set scoped message').click();
@@ -1786,12 +1786,14 @@ test.describe('remote functions', () => {
17861786
await expect(page.getByText('await get_message():')).toHaveText('await get_message(): hello');
17871787
}
17881788

1789-
await expect(page.getByText('scoped.result')).toHaveText('scoped.result: hello (from: scoped)');
1790-
await expect(page.locator('[data-scoped] input')).toHaveValue('');
1789+
await expect(page.getByText('scoped.result')).toHaveText(
1790+
'scoped.result: hello (from: scoped:form-scoped)'
1791+
);
1792+
await expect(page.locator('[data-scoped] input[name="message"]')).toHaveValue('');
17911793
});
17921794

17931795
test('form enhance(...) works', async ({ page, javaScriptEnabled }) => {
1794-
await page.goto('/remote/form');
1796+
await page.goto('/remote/form/enhanced');
17951797

17961798
await page.fill('[data-enhanced] input', 'hello');
17971799

@@ -1808,13 +1810,13 @@ test.describe('remote functions', () => {
18081810
await expect(page.getByText('await get_message():')).toHaveText('await get_message(): hello');
18091811

18101812
// enhanced submission should not clear the input; the developer must do that at the appropriate time
1811-
await expect(page.locator('[data-enhanced] input')).toHaveValue('hello');
1813+
await expect(page.locator('[data-enhanced] input[name="message"]')).toHaveValue('hello');
18121814
} else {
1813-
await expect(page.locator('[data-enhanced] input')).toHaveValue('');
1815+
await expect(page.locator('[data-enhanced] input[name="message"]')).toHaveValue('');
18141816
}
18151817

18161818
await expect(page.getByText('enhanced.result')).toHaveText(
1817-
'enhanced.result: hello (from: enhanced)'
1819+
'enhanced.result: hello (from: enhanced:enhanced)'
18181820
);
18191821
});
18201822

0 commit comments

Comments
 (0)