fix: reserve Windows titlebar chrome space for Code actions
This commit is contained in:
@@ -1119,6 +1119,78 @@ test('foreground focus rehydrates a terminal Snapshot after lifecycle sleep', as
|
||||
))).toBe(false);
|
||||
});
|
||||
|
||||
test('Windows Code titlebar keeps browser actions clear of the logo and window controls', async ({
|
||||
launchElectronApp,
|
||||
}) => {
|
||||
test.skip(process.platform !== 'win32', 'Windows custom titlebar only');
|
||||
const electronApp = await launchElectronApp({ skipSetup: true });
|
||||
const page = await getStableWindow(electronApp);
|
||||
const hostConnection = await page.evaluate(async () => ({
|
||||
token: await window.electron.ipcRenderer.invoke('hostapi:token') as string,
|
||||
baseUrl: await window.electron.ipcRenderer.invoke('hostapi:base-url') as string,
|
||||
}));
|
||||
await installCodingFirstChatHost(electronApp, hostConnection, true);
|
||||
await disableCodingEventSource(page);
|
||||
|
||||
try {
|
||||
await page.reload();
|
||||
await page.getByTestId('ai-module-option-programming').click();
|
||||
await expect(page.getByTestId('coding-conversation-header')).toBeVisible();
|
||||
const header = page.getByTestId('coding-conversation-header');
|
||||
const assertChromeClear = async () => {
|
||||
const logo = await page.getByTestId('titlebar-logo').boundingBox();
|
||||
expect(logo).not.toBeNull();
|
||||
for (const button of await header.getByRole('button').all()) {
|
||||
const bounds = await button.boundingBox();
|
||||
expect(bounds).not.toBeNull();
|
||||
expect(bounds!.x + bounds!.width).toBeLessThanOrEqual(logo!.x);
|
||||
}
|
||||
const minimize = page.getByTitle('Minimize');
|
||||
const minimizeBounds = await minimize.boundingBox();
|
||||
expect(minimizeBounds).not.toBeNull();
|
||||
expect(logo!.x + logo!.width).toBeLessThanOrEqual(minimizeBounds!.x);
|
||||
// The conversation header must not intercept clicks in the window controls.
|
||||
for (const title of ['Minimize', 'Maximize', 'Close']) {
|
||||
await page.getByTitle(title, { exact: true }).click({ trial: true });
|
||||
}
|
||||
};
|
||||
|
||||
for (const { width, zoom } of [
|
||||
{ width: 1280, zoom: 1 },
|
||||
{ width: 1024, zoom: 1 },
|
||||
{ width: 1280, zoom: 1.25 },
|
||||
]) {
|
||||
await electronApp.evaluate(({ BrowserWindow }, dimensions) => {
|
||||
const window = BrowserWindow.getAllWindows()[0];
|
||||
window.setSize(dimensions.width, 800);
|
||||
window.webContents.setZoomFactor(dimensions.zoom);
|
||||
}, { width, zoom });
|
||||
await expect.poll(async () => page.evaluate(() => window.innerWidth)).toBe(Math.round(width / zoom));
|
||||
await assertChromeClear();
|
||||
if (width === 1280 && zoom === 1) {
|
||||
await page.screenshot({ path: test.info().outputPath('windows-code-titlebar.png') });
|
||||
}
|
||||
await header.getByRole('button', { name: '打开开发浏览器' }).click();
|
||||
await expect(page.getByTestId('agent-browser-panel')).toBeVisible();
|
||||
await assertChromeClear();
|
||||
await header.getByRole('button', { name: '关闭开发浏览器' }).click();
|
||||
await expect(page.getByTestId('agent-browser-panel')).toHaveCount(0);
|
||||
}
|
||||
await page.getByTestId('titlebar-sidebar-toggle').click();
|
||||
await assertChromeClear();
|
||||
await settleSnapshot(electronApp);
|
||||
await page.evaluate(() => window.dispatchEvent(new FocusEvent('focus')));
|
||||
await expect(header.getByRole('button', { name: '中止', exact: true })).toHaveCount(0);
|
||||
await assertChromeClear();
|
||||
await page.getByTitle('Maximize', { exact: true }).click();
|
||||
await expect(page.getByTitle('Restore', { exact: true })).toBeVisible();
|
||||
await page.getByTitle('Restore', { exact: true }).click();
|
||||
await expect(page.getByTitle('Maximize', { exact: true })).toBeVisible();
|
||||
} finally {
|
||||
await releaseSnapshot(electronApp);
|
||||
}
|
||||
});
|
||||
|
||||
test('PI feature UI isolates Conversations and exposes queue, interaction, model, and subagent state', async ({
|
||||
launchElectronApp,
|
||||
}) => {
|
||||
@@ -1167,6 +1239,11 @@ test('PI feature UI isolates Conversations and exposes queue, interaction, model
|
||||
await expect(conversationHeader.getByRole('button', { name: '打开编程工具' })).toHaveCount(0);
|
||||
const browserToggle = conversationHeader.getByRole('button', { name: '打开开发浏览器' });
|
||||
await expect(browserToggle).toBeVisible();
|
||||
if (process.platform === 'win32') {
|
||||
const browserBounds = await browserToggle.boundingBox();
|
||||
expect(browserBounds).not.toBeNull();
|
||||
expect(browserBounds!.x + browserBounds!.width).toBeLessThanOrEqual(logoBounds!.x);
|
||||
}
|
||||
await browserToggle.click();
|
||||
await expect(page.getByTestId('agent-browser-panel')).toBeVisible();
|
||||
await expect(page.getByTestId('agent-browser-diagnostics')).toHaveAttribute('data-state', 'closed');
|
||||
|
||||
Reference in New Issue
Block a user