@@ -19,9 +19,11 @@ import { test, expect } from '@playwright/test';
1919 * semantic-zoo fixtures are objects but not seeded records — each run
2020 * creates its own rows via the REST API.
2121 *
22- * NOTE: assertions are scoped to what the *pinned* console build supports
23- * (.objectui-sha). Group icon/description chrome ships with a later objectui
24- * bump — extend the grouped case then.
22+ * Assertions are scoped to what the *pinned* console build supports
23+ * (.objectui-sha). The fb35e48 bump brought in objectui#2577, so the grouped
24+ * case also pins the follow-up UX contract: highlight strip drops the record
25+ * title, group icon/description render, and currencyConfig money shows its
26+ * symbol.
2527 */
2628
2729const APP = process . env . SHOWCASE_APP || 'com.example.showcase' ;
@@ -85,17 +87,37 @@ test('grouped: fieldGroup sections render and Money starts collapsed', async ({
8587 // record:path renders a desktop + a mobile variant — assert the visible one.
8688 await expect ( page . locator ( PATH_STEPPER ) . first ( ) ) . toBeVisible ( ) ;
8789
90+ // objectui#2577: the record title is the page H1 — it must NOT repeat as a
91+ // (truncated) chip in the highlight strip; status/amount still do.
92+ const strip = page . locator ( 'section[aria-label="Record highlights"]' ) ;
93+ await expect ( strip ) . toBeVisible ( ) ;
94+ const stripText = ( await strip . innerText ( ) ) . replace ( / \s + / g, ' ' ) ;
95+ expect ( stripText , 'strip repeats the record title' ) . not . toContain ( 'E2E Zoo' ) ;
96+ expect ( stripText ) . toContain ( '4,200' ) ;
97+
8898 // Declared groups render as titled sections. Their highlighted members
8999 // (status/amount) are hoisted to the strip; the non-highlighted members
90100 // (code/budget) keep the groups visible in the body.
91101 await expect ( page . getByText ( 'Basics' , { exact : true } ) ) . toBeVisible ( ) ;
92102 await expect ( page . getByText ( 'Money' , { exact : true } ) ) . toBeVisible ( ) ;
93103 await expect ( page . getByText ( 'ZG-1' ) ) . toBeVisible ( ) ;
94104
105+ // objectui#2577: fieldGroups[].icon renders as a real (Lucide svg) icon in
106+ // the section header — not as literal icon-name text.
107+ await expect (
108+ page . locator ( 'div:has(> span:text-is("Money")) svg' ) . first ( ) ,
109+ 'Money header icon svg' ,
110+ ) . toBeVisible ( ) ;
111+ await expect ( page . getByText ( 'banknote' , { exact : true } ) ) . toHaveCount ( 0 ) ;
112+
95113 // collapse: 'collapsed' — Budget stays hidden until the header is opened.
96114 await expect ( page . getByText ( 'Budget' , { exact : true } ) ) . toHaveCount ( 0 ) ;
97115 await page . getByText ( 'Money' , { exact : true } ) . click ( ) ;
98116 await expect ( page . getByText ( 'Budget' , { exact : true } ) ) . toBeVisible ( ) ;
117+ // objectui#2577: fieldGroups[].description renders under the expanded
118+ // header, and currencyConfig.defaultCurrency drives a real $ symbol.
119+ await expect ( page . getByText ( 'Financial fields — collapsed by default.' ) ) . toBeVisible ( ) ;
120+ await expect ( page . getByText ( '$100,000' , { exact : false } ) . first ( ) ) . toBeVisible ( ) ;
99121
100122 expect ( errors , 'uncaught page errors on grouped detail' ) . toEqual ( [ ] ) ;
101123} ) ;
@@ -134,6 +156,16 @@ test('ungrouped + related-heavy: flat details and related-list tabs on Contoso',
134156 // (Contoso declares no fieldGroups; spot-check a body field label.)
135157 await expect ( page . getByText ( 'Basics' , { exact : true } ) ) . toHaveCount ( 0 ) ;
136158
159+ // objectui#2577 + currencyConfig: annual revenue renders with its symbol
160+ // in the strip, and the meta footer doesn't dangle "Created by" on the
161+ // actor-less seeded row.
162+ await expect ( page . getByText ( '$25,000,000' , { exact : false } ) . first ( ) ) . toBeVisible ( ) ;
163+ const footer = page . locator ( '[data-testid="record-meta-footer"]' ) ;
164+ await expect ( footer ) . toBeVisible ( ) ;
165+ const footerText = ( await footer . innerText ( ) ) . replace ( / \s + / g, ' ' ) ;
166+ expect ( footerText , 'footer dangles "Created by" without an actor' ) . not . toMatch ( / C r e a t e d b y / ) ;
167+ expect ( footerText ) . toMatch ( / C r e a t e d / ) ;
168+
137169 // Related lists self-fetch lazily when their tab is shown.
138170 await invoicesTab . click ( ) ;
139171 const panel = page . getByRole ( 'tabpanel' ) ;
0 commit comments