From dc77e9c80db123ab417ff6f86a90d25ac561ad19 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 27 Oct 2026 19:21:54 +0000 Subject: [PATCH 1/2] test(app-shell): PackageFormDialog validationTiming awaits the lazy studio zh catalogue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The zh-CN cases read `getByLabelText(/软件包 ID/)` right after the form renders; that label is `engine.packages.create.id`, a row of the lazy `studio` i18n namespace since the package/form/editor strings moved there. Load the zh catalogue at module scope, the shape the other studio-namespace zh tests in app-shell use. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01QsR2jVTqmjzhQU2Rqq79mu --- .../PackageFormDialog.validationTiming.test.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ui/packages/app-shell/src/views/metadata-admin/PackageFormDialog.validationTiming.test.tsx b/ui/packages/app-shell/src/views/metadata-admin/PackageFormDialog.validationTiming.test.tsx index d39b68984a7..55986f9f0f0 100644 --- a/ui/packages/app-shell/src/views/metadata-admin/PackageFormDialog.validationTiming.test.tsx +++ b/ui/packages/app-shell/src/views/metadata-admin/PackageFormDialog.validationTiming.test.tsx @@ -20,6 +20,12 @@ import * as React from 'react'; import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; import { render, screen, fireEvent, waitFor } from '@testing-library/react'; import { PackageFormDialog } from './PackageFormDialog'; +// The form's field labels (`engine.packages.create.*`) live in `@object-ui/i18n`'s +// `studio` namespace, whose `zh` catalogue is fetched on demand. Resident before +// any case, so `getByLabelText(/软件包 ID/)` reads the zh label, never the en +// fallback while the chunk is in flight (objectstack#26863). +import { loadStudioCatalogue } from '@object-ui/i18n/namespaces/studio'; +await loadStudioCatalogue('zh'); let localeFixture: 'en-US' | 'zh-CN' = 'zh-CN'; vi.mock('./i18n', async (importOriginal) => ({ From a51a0622d516a959ba993a6d052b5dbad368bfc1 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 27 Oct 2026 19:45:02 +0000 Subject: [PATCH 2/2] test(app-shell): two ResourceEditPage zh cases await the lazy studio zh catalogue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `discardDraftLabel-12690` finds the `丢弃草稿` button (`engine.edit.discardDraft`) and `environmentOverlay-12141` reads the read-only banner (`engine.edit.readOnlyTypeBanner`) in zh-CN. Both rows moved into the lazy `studio` namespace with the editor strings, so each case raced the zh chunk. Load the catalogue at module scope. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01QsR2jVTqmjzhQU2Rqq79mu --- .../ResourceEditPage.discardDraftLabel-12690.test.tsx | 6 ++++++ .../ResourceEditPage.environmentOverlay-12141.test.tsx | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/ui/packages/app-shell/src/views/metadata-admin/ResourceEditPage.discardDraftLabel-12690.test.tsx b/ui/packages/app-shell/src/views/metadata-admin/ResourceEditPage.discardDraftLabel-12690.test.tsx index 0b73f9f4ddb..6b71822341d 100644 --- a/ui/packages/app-shell/src/views/metadata-admin/ResourceEditPage.discardDraftLabel-12690.test.tsx +++ b/ui/packages/app-shell/src/views/metadata-admin/ResourceEditPage.discardDraftLabel-12690.test.tsx @@ -103,6 +103,12 @@ import { MetadataResourceEditPage } from './ResourceEditPage'; import { registerDefaultMetadataSchemas } from './default-schemas'; import { registerBuiltinPreviews } from './previews'; import { tFormat } from './i18n'; +// The `engine.edit.*` rows this suite reads in zh (the `丢弃草稿` button, the +// confirm and the toast) live in `@object-ui/i18n`'s `studio` namespace, whose +// `zh` catalogue is fetched on demand. Resident before any case, so the zh rows +// are read after the catalogue lands, never racing it (objectstack#26863). +import { loadStudioCatalogue } from '@object-ui/i18n/namespaces/studio'; +await loadStudioCatalogue('zh'); const DOC_JSON_SCHEMA = z.toJSONSchema(DocSchema as unknown as z.ZodType) as Record; client.current = new MetadataClient({ baseUrl: '', fetch: vi.fn(serve) as unknown as typeof fetch }); diff --git a/ui/packages/app-shell/src/views/metadata-admin/ResourceEditPage.environmentOverlay-12141.test.tsx b/ui/packages/app-shell/src/views/metadata-admin/ResourceEditPage.environmentOverlay-12141.test.tsx index 52fc5171b93..426c562d63c 100644 --- a/ui/packages/app-shell/src/views/metadata-admin/ResourceEditPage.environmentOverlay-12141.test.tsx +++ b/ui/packages/app-shell/src/views/metadata-admin/ResourceEditPage.environmentOverlay-12141.test.tsx @@ -74,6 +74,12 @@ vi.mock('./i18n', async (importOriginal) => ({ })); import { MetadataResourceEditPage } from './ResourceEditPage'; +// The read-only banner (`engine.edit.readOnlyTypeBanner`) lives in +// `@object-ui/i18n`'s `studio` namespace, whose `zh` catalogue is fetched on +// demand. Resident before any case, so the zh banner is read after the +// catalogue lands, never racing it (objectstack#26863). +import { loadStudioCatalogue } from '@object-ui/i18n/namespaces/studio'; +await loadStudioCatalogue('zh'); /** An item a code package ships, as the layered read serves it. */ function packagedItem() {