| @@ -236,7 +236,10 @@ function createBaseServerConfig(): ServerConfig { · 235 unmodified lines |
| 236 | }; | 236 | }; |
| 237 | } | 237 | } |
| 238 | | 238 | |
| 239 | function createOutdatedProvider(driver: string): ServerProvider { | 239 | function createOutdatedProvider( |
| | 240 | driver: string, |
| | 241 | updateCommand = "npm install -g openai/codex@latest", |
| | 242 | ): ServerProvider { |
| 240 | return { | 243 | return { |
| 241 | instanceId: ProviderInstanceId.make(driver), | 244 | instanceId: ProviderInstanceId.make(driver), |
| 242 | driver: ProviderDriverKind.make(driver), | 245 | driver: ProviderDriverKind.make(driver), |
| @@ -255,7 +258,7 @@ function createOutdatedProvider(driver: string): ServerProvider { · 12 unmodified lines |
| 255 | latestVersion: "1.1.0", | 258 | latestVersion: "1.1.0", |
| 256 | message: "Update available.", | 259 | message: "Update available.", |
| 257 | checkedAt: "2026-05-04T10:00:00.000Z", | 260 | checkedAt: "2026-05-04T10:00:00.000Z", |
| 258 | updateCommand: "npm install -g openai/codex@latest", | 261 | updateCommand, |
| 259 | canUpdate: true, | 262 | canUpdate: true, |
| 260 | }, | 263 | }, |
| 261 | }; | 264 | }; |
| @@ -1155,6 +1158,47 @@ describe("GeneralSettingsPanel observability", () => { · 893 unmodified lines |
| 1155 | instanceId: ProviderInstanceId.make("codex"), | 1158 | instanceId: ProviderInstanceId.make("codex"), |
| 1156 | }); | 1159 | }); |
| 1157 | }); | 1160 | }); |
| | 1161 | |
| | 1162 | it("keeps long provider update commands inside the fixed-width popover", async () => { |
| | 1163 | const longUpdateCommand = |
| | 1164 | "npm install -g @anthropic-ai/claude-code@latest --registry=https://registry.npmjs.org --cache=/tmp/t3code-provider-update-cache"; |
| | 1165 | |
| | 1166 | setServerConfigSnapshot({ |
| | 1167 | ...createBaseServerConfig(), |
| | 1168 | providers: [createOutdatedProvider("codex", longUpdateCommand)], |
| | 1169 | }); |
| | 1170 | |
| | 1171 | mounted = await render( |
| | 1172 | <AppAtomRegistryProvider> |
| | 1173 | <ProviderSettingsPanel /> |
| | 1174 | </AppAtomRegistryProvider>, |
| | 1175 | ); |
| | 1176 | |
| | 1177 | await page.getByRole("button", { name: "Update available — view details" }).click(); |
| | 1178 | await expect.element(page.getByText(longUpdateCommand)).toBeInTheDocument(); |
| | 1179 | |
| | 1180 | await vi.waitFor(() => { |
| | 1181 | const popup = document.querySelector<HTMLElement>('[data-slot="popover-popup"]'); |
| | 1182 | const commandCode = Array.from(document.querySelectorAll<HTMLElement>("code")).find( |
| | 1183 | (element) => element.textContent === longUpdateCommand, |
| | 1184 | ); |
| | 1185 | const scrollViewport = commandCode?.closest<HTMLElement>( |
| | 1186 | '[data-slot="scroll-area-viewport"]', |
| | 1187 | ); |
| | 1188 | |
| | 1189 | expect(popup).toBeTruthy(); |
| | 1190 | expect(commandCode).toBeTruthy(); |
| | 1191 | expect(scrollViewport).toBeTruthy(); |
| | 1192 | |
| | 1193 | const popupRect = popup!.getBoundingClientRect(); |
| | 1194 | const viewportRect = scrollViewport!.getBoundingClientRect(); |
| | 1195 | |
| | 1196 | expect(popupRect.width).toBeGreaterThan(300); |
| | 1197 | expect(popupRect.width).toBeLessThanOrEqual(337); |
| | 1198 | expect(viewportRect.right).toBeLessThanOrEqual(popupRect.right + 0.5); |
| | 1199 | expect(scrollViewport!.scrollWidth).toBeGreaterThan(scrollViewport!.clientWidth); |
| | 1200 | }); |
| | 1201 | }); |
| 1158 | }); | 1202 | }); |
| 1159 | | 1203 | |
| 1160 | describe("SourceControlSettingsPanel discovery states", () => { | 1204 | describe("SourceControlSettingsPanel discovery states", () => { |