Skip to content

Commit b1d2d58

Browse files
test(webview): await the on-demand locale fetch instead of timing it
The windows-latest platform-unit-test lane failed in this PR's webview-ui step, with ubuntu cancelled as collateral (job 126169197675). The failing case is src/i18n/__tests__/TranslationContext.locale-loading.spec.tsx, which arrived with upstream f8aa881 ("load locales on demand instead of eager-globbing all 18", upstream #2267) and is byte-identical here to the copy in the vps2 f-series branches that hit the same red. The assertion is the problem, not the locale loading. Since #2267 a switch to a non-fallback language is an import() of that locale's namespace bundles, so its duration is a property of the machine and of the load on it; the spec asserted that it lands inside testing-library's fixed 1000 ms waitFor window. Ubuntu finished inside the window and windows did not, and the received DOM still showed the pre-switch language - the fetch had not resolved yet, which rules out path separators, a case-insensitive filesystem or CRLF as the cause. Each cold-locale assertion now awaits the memoized loadLanguage promise the provider itself waits on, so the assertion is a statement about ordering rather than about the clock. waitFor still covers the render that languageChanged triggers, which is microtask-bound; the unmount case in this file already awaited that promise. Controls, run in this worktree on Windows with a harness that delays every lazy locale module: - 1500 ms: the previous spec fails 4 of 6 at lines 51, 71, 88 and 127 - the four waitFor sites - with CI's texts ("Something went wrong" received for ko/ja/de, "Etwas ist schiefgelaufen" received for fr, which is the pair this PR's job reported); this spec passes 6 of 6. - 3000 ms with CI=true (maxWorkers 1, testTimeout 15000): 6 of 6. - harness reverted byte-identically: 6 of 6 in 1.66s, and webview-ui tsc --noEmit, eslint --max-warnings=0 --no-warn-ignored and prettier --check are all clean. Test-only change: +22 lines, no skip, no suppression. The flaky assertion is upstream's own, so the same patch should be ported upstream; recorded on easonLiangWorldedtech#35 for the maintainers.
1 parent 36b9e5b commit b1d2d58

1 file changed

Lines changed: 22 additions & 0 deletions

File tree

‎webview-ui/src/i18n/__tests__/TranslationContext.locale-loading.spec.tsx‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,15 @@ describe("TranslationProvider locale loading", () => {
4747
// through the English fallback and the switch lands after the fetch.
4848
expect(screen.getByTestId("error-title")).toHaveTextContent("Something went wrong")
4949

50+
// A locale outside the entry chunk is fetched on demand, so how long the switch
51+
// takes is a property of the machine and the load on it, not of the code under
52+
// test: on a contended runner the fetch can outlast any fixed wall-clock window,
53+
// which is what made this suite flake. Awaiting the memoized promise the provider
54+
// itself waits on - the idiom the unmount case at the end of this file uses - takes
55+
// the clock out of the assertion. What `waitFor` has left to catch is the render
56+
// that `languageChanged` triggers, which settles in the same task.
57+
await loadLanguage("ko")
58+
5059
await waitFor(() => {
5160
expect(screen.getByTestId("error-title")).toHaveTextContent("문제가 발생했습니다")
5261
})
@@ -67,6 +76,9 @@ describe("TranslationProvider locale loading", () => {
6776
)
6877
})
6978

79+
// Await the fetch instead of racing a fixed window (note in the first case).
80+
await loadLanguage("ja")
81+
7082
await waitFor(() => {
7183
expect(screen.getByTestId("error-title")).toHaveTextContent("問題が発生しました")
7284
})
@@ -84,6 +96,9 @@ describe("TranslationProvider locale loading", () => {
8496
it("keeps English available after switching away and back", async () => {
8597
const { rerender } = renderProbe("de")
8698

99+
// German is loaded on demand as well: await it rather than time it.
100+
await loadLanguage("de")
101+
87102
await waitFor(() => {
88103
expect(screen.getByTestId("error-title")).toHaveTextContent("Etwas ist schiefgelaufen")
89104
})
@@ -105,6 +120,9 @@ describe("TranslationProvider locale loading", () => {
105120
it("keeps the previous locale rendered while a warm switch is still loading", async () => {
106121
const { rerender } = renderProbe("de")
107122

123+
// The cold locale is awaited here too (see the note in the first case).
124+
await loadLanguage("de")
125+
108126
await waitFor(() => {
109127
expect(screen.getByTestId("error-title")).toHaveTextContent("Etwas ist schiefgelaufen")
110128
})
@@ -123,6 +141,10 @@ describe("TranslationProvider locale loading", () => {
123141
// resolves would paint the English fallback here instead of German.
124142
expect(screen.getByTestId("error-title")).toHaveTextContent("Etwas ist schiefgelaufen")
125143

144+
// Awaiting the fetch through the promise the provider waits on keeps the assertion
145+
// above a statement about ordering rather than about the clock.
146+
await loadLanguage("fr")
147+
126148
await waitFor(() => {
127149
expect(screen.getByTestId("error-title")).toHaveTextContent("Une erreur s'est produite")
128150
})

0 commit comments

Comments
 (0)