@@ -178,23 +178,20 @@ test.describe('desktop shell smoke', () => {
178178 const window = await app.firstWindow()
179179 await window.waitForSelector('#retry', { timeout: 30_000 })
180180 expect(window.url()).toMatch(/^sim-shell:\/\/pages\/offline\.html\?/)
181- await expect(window.getByRole('img', { name: 'Sim', exact: true })).toBeVisible()
182- await expect(window.getByRole('img', { name: 'Sim', exact: true })).toHaveAttribute(
183- 'aria-label',
184- 'Sim'
185- )
181+ const home = window.getByRole('link', { name: 'Home', exact: true })
182+ await expect(home).toBeVisible()
183+ await expect(home).toHaveAttribute('href', 'https://sim.ai')
186184 await expect(window.locator('#title')).toHaveText('Can’t connect to Sim')
187- // The recovery path for a self-hosted shell pointed at a server it cannot
188- // reach. Exercised end to end here because it is the only coverage of the
189- // `server:` local-page IPC gate: the bundled page reads the configuration
190- // over the real preload bridge, and status.sim.ai is withheld because this
191- // origin is not one of Sim's own. `toBeHidden` is load-bearing — the page's
192- // own `button { display: inline-flex }` outranks the UA `[hidden]` rule, so
193- // the attribute alone does not hide it.
185+ // The real preload bridge must retain server recovery while hiding cloud-only status.
194186 await expect(window.locator('#server')).toBeVisible()
195187 await expect(window.locator('#status')).toBeHidden()
196188 await expect
197- .poll(() => window.evaluate(() => document.fonts.check('16px "Season Sans"')))
189+ .poll(() =>
190+ window.evaluate(async () => {
191+ const fonts = await document.fonts.load('14px "Sim Auth Geist"')
192+ return fonts.length > 0 && fonts.every((font) => font.status === 'loaded')
193+ })
194+ )
198195 .toBe(true)
199196 await expect(window.locator('#detail')).toHaveAttribute('role', 'status')
200197 })
@@ -205,18 +202,25 @@ test.describe('desktop shell smoke', () => {
205202 const window = await app.firstWindow()
206203 await expect(window.locator('#server')).toBeVisible()
207204 await expect(window.locator('html')).toHaveAttribute('data-sim-desktop-title-bar', 'inset')
205+ const titlebar = window.locator('[data-auth-titlebar]')
206+ await expect
207+ .poll(() => titlebar.evaluate((element) => element.getBoundingClientRect().height))
208+ .toBeGreaterThanOrEqual(38)
208209 await app.evaluate(({ BrowserWindow }) => {
209210 BrowserWindow.getAllWindows()[0].setFullScreen(true)
210211 })
211212 await expect(window.locator('html')).toHaveAttribute('data-sim-desktop-title-bar', 'fullscreen')
212213 await window.reload()
213214 await expect(window.locator('#server')).toBeVisible()
214215 await expect(window.locator('html')).toHaveAttribute('data-sim-desktop-title-bar', 'fullscreen')
215- await expect(window.locator('.desktop-title-bar-page')) .toHaveCSS('padding-top ', '0px')
216+ await expect(titlebar) .toHaveCSS('height ', '0px')
216217 await app.evaluate(({ BrowserWindow }) => {
217218 BrowserWindow.getAllWindows()[0].setFullScreen(false)
218219 })
219220 await expect(window.locator('html')).toHaveAttribute('data-sim-desktop-title-bar', 'inset')
221+ await expect
222+ .poll(() => titlebar.evaluate((element) => element.getBoundingClientRect().height))
223+ .toBeGreaterThanOrEqual(38)
220224 })
221225
222226 test('bundled dialogs follow the app theme independently of the system theme', async () => {
@@ -310,7 +314,7 @@ test.describe('desktop shell smoke', () => {
310314 // Its page, the pre-filled value (which crosses the local-page IPC gate) and
311315 // Escape are asserted together because the packaged build once opened it as
312316 // a blank sheet with no way out.
313- test('the offline server picker renders EMCN controls and handles validation and dismissal', async () => {
317+ test('the offline server picker handles validation and dismissal', async () => {
314318 const testInfo = test.info()
315319 app = await launchApp('http://127.0.0.1:1')
316320 const window = await app.firstWindow()
@@ -333,17 +337,21 @@ test.describe('desktop shell smoke', () => {
333337 .toBe(true)
334338 await picker.getByLabel('Server URL').fill('http://example.com')
335339 await picker.getByLabel('Server URL').press('Enter')
336- await expect(picker.getByRole('alert')).toBeVisible()
340+ await expect(picker.locator('#server-origin-errors')).toBeVisible()
341+ await expect(picker.getByLabel('Server URL')).toHaveAccessibleDescription(
342+ /Server URL must use HTTPS/
343+ )
337344 await expect(picker.getByLabel('Server URL')).toHaveAttribute('aria-invalid', 'true')
338345 await picker.getByLabel('Server URL').fill('http://127.0.0.1:1')
339- await expect(picker.getByRole('alert')).toHaveCount(0)
346+ await expect(picker.locator('#server-origin-errors')).toHaveCount(0)
347+ await expect(picker.getByLabel('Server URL')).not.toHaveAttribute('aria-invalid', 'true')
340348 await picker.getByRole('button', { name: 'Connect', exact: true }).click()
341349 await expect(picker.getByRole('status')).toHaveText('Already connected to this server.')
342350 await expect
343351 .poll(() =>
344352 picker
345- .locator('[data-chip-modal-body] ')
346- .evaluate((element) => element.scrollHeight <= element.clientHeight )
353+ .getByRole('dialog ')
354+ .evaluate((element) => element.scrollHeight <= globalThis.innerHeight )
347355 )
348356 .toBe(true)
349357 await picker.emulateMedia({ colorScheme: 'light' })
@@ -352,7 +360,7 @@ test.describe('desktop shell smoke', () => {
352360 animations: 'disabled',
353361 })
354362 await picker.emulateMedia({ colorScheme: 'dark' })
355- await expect(picker.locator('html ')).toHaveClass('dark ')
363+ await expect(picker.locator('[data-auth-root] ')).toHaveCSS('color-scheme', 'light ')
356364 await picker.screenshot({
357365 path: testInfo.outputPath('server-modal-dark.png'),
358366 animations: 'disabled',
0 commit comments