Verify combined navigation, drafts and workspace delivery contracts
Electron E2E / Electron E2E (macos-latest) (push) Waiting to run
Electron E2E / Electron E2E (ubuntu-latest) (push) Waiting to run
Electron E2E / Electron E2E (windows-latest) (push) Waiting to run

This commit is contained in:
鲨鱼辣椒 committed 2026-10-14 00:29:58 +08:00
1 parent a106dc16f5
commit 592ff38f00
3 files changed
+26 -12

No files matched your search

@@ -25,7 +25,7 @@
## Outcome ## Outcome
- Canvas implementation complete: Agents-style navigation/composer/Markdown, 64px identity header, resizable 42/58 workspace, current output preview and historical selection, one persistent editable production card, <=899px compact panel switching. Hidden videos pause; modal Escape does not change split focus; compact creation no longer opens two dialogs. - Canvas implementation complete: Agents-style navigation/composer/Markdown, 64px identity header, resizable 42/58 workspace, current output preview and historical selection, one persistent editable production card, <=899px compact panel switching. Hidden videos pause; modal Escape does not change split focus; compact creation no longer opens two dialogs.
- Coordinated integration, normal main push, live temporary-application update and worktree retirement remain pending. Canvas source2ca6e31; Code-navigation chat completed product source d287d5ac (handoff15848cd). The committed effective Renderer non-project-doc delta from baseline70166d2 was applied through Git three-way merge, preserving Canvas and all current Sidebar/TOOL/SKILL/knowledge-upload fixes; its live verification is blocked by Mac lock. Channel-adapter chat completed source979596f. Its non-project-doc product/test/README delta was also three-way merged cleanly. Combined typecheck/scoped ESLint and all443 selected units passed. The accepted non-project-doc code deltas were three-way merged before recording source ancestry with a metadata-only merge of Code15848cd and channel979596f. This preserves source commit history without changing their read-only task records or importing canonical-memory changes into feature mode; no Yuxi files were changed. Required unlock question is pending; no app mutation has occurred in this task. - Coordinated source integration complete. The final product tree includes Canvas2ca6e31, effective Code/sidebar/advanced source d287d5ac / handoff15848cd and channel979596f; ancestry mergea106dc1 preserves both delivered histories. Normal main push and immutable packaging follow final evidence commit. Live temporary-application activation and worktree retirement still await native saved/quit/UI verification. Canvas source2ca6e31; Code-navigation chat completed product source d287d5ac (handoff15848cd). The committed effective Renderer non-project-doc delta from baseline70166d2 was applied through Git three-way merge, preserving Canvas and all current Sidebar/TOOL/SKILL/knowledge-upload fixes; its live verification is blocked by Mac lock. Channel-adapter chat completed source979596f. Its non-project-doc product/test/README delta was also three-way merged cleanly. Combined typecheck/scoped ESLint and all443 selected units passed. The accepted non-project-doc code deltas were three-way merged before recording source ancestry with a metadata-only merge of Code15848cd and channel979596f. This preserves source commit history without changing their read-only task records or importing canonical-memory changes into feature mode; no Yuxi files were changed. Required unlock question is pending; no app mutation has occurred in this task.
## Verification ## Verification
@@ -36,6 +36,9 @@
## Follow-ups ## Follow-ups
- Combined actual Electron/browser fixtures: 18 unique cases passed (Canvas/channels4, community9, Code/navigation5). Three-way integration exposed inherited assertions for the replaced community entry, current attachment thumbnails, the existing filter query and the new toolbar/record-dialog layout; test-only fixes retain behavior/geometry/first-send/draft/attachment/navigation checks. Type/scoped lint and whitespace checks passed. Controlled screenshots and complete passed logs are preserved outside the source worktree.
- Native CUA independently confirmed Mac locked on 2026-10-14; the user unlock question remains unanswered. Do not activate files, quit/launch the app, finalize a false UI receipt or retire the owned source tree until the required native confirmation is possible. Other selected chats are idle/completed.
- Finish both user-selected chat dependencies before staging combined runtime. Inspect fresh pointer, actual compatibility symlink and Main source; never reuse the rejected broad Code visual variant. Preserve unrelated primary checkout task record and stable profile/runtime/dependency links during cleanup. - Finish both user-selected chat dependencies before staging combined runtime. Inspect fresh pointer, actual compatibility symlink and Main source; never reuse the rejected broad Code visual variant. Preserve unrelated primary checkout task record and stable profile/runtime/dependency links during cleanup.
## Promotion Candidates ## Promotion Candidates
+7 -4
View File
@@ -330,10 +330,11 @@ test.describe('Makelore module navigation without setup flow', () => {
expect(returnBox!.y + returnBox!.height).toBeLessThanOrEqual(brandBox!.y); expect(returnBox!.y + returnBox!.height).toBeLessThanOrEqual(brandBox!.y);
const headerBox = await page.getByTestId('coding-conversation-header').boundingBox(); const headerBox = await page.getByTestId('coding-conversation-header').boundingBox();
const tabsBox = await page.getByRole('tablist', { name: '当前工作' }).boundingBox(); const tabsBox = await page.getByRole('tablist', { name: '当前工作' }).boundingBox();
const toolbarBox = await page.locator('.classroom-workspace-toolbar').boundingBox();
expect(Math.abs(returnBox!.y + returnBox!.height / 2 - headerBox!.y - headerBox!.height / 2)).toBeLessThan(1); expect(Math.abs(returnBox!.y + returnBox!.height / 2 - headerBox!.y - headerBox!.height / 2)).toBeLessThan(1);
expect(Math.abs(brandBox!.y + brandBox!.height / 2 - tabsBox!.y - tabsBox!.height / 2)).toBeLessThan(1); expect(Math.abs(brandBox!.y + brandBox!.height / 2 - tabsBox!.y - tabsBox!.height / 2)).toBeLessThan(1);
expect(brandBox!.y - sidebarBox!.y).toBe(0); expect(brandBox!.y - sidebarBox!.y).toBe(0);
expect(brandBox!.height).toBe(tabsBox!.height); expect(brandBox!.height).toBe(toolbarBox!.height);
expect(returnBox!.width).toBe(32); expect(returnBox!.width).toBe(32);
expect(Math.abs(returnBox!.y + returnBox!.height / 2 - collapseBox!.y - collapseBox!.height / 2)).toBeLessThan(1); expect(Math.abs(returnBox!.y + returnBox!.height / 2 - collapseBox!.y - collapseBox!.height / 2)).toBeLessThan(1);
expect(returnBox!.x + returnBox!.width).toBeLessThanOrEqual(collapseBox!.x); expect(returnBox!.x + returnBox!.width).toBeLessThanOrEqual(collapseBox!.x);
@@ -347,9 +348,9 @@ test.describe('Makelore module navigation without setup flow', () => {
expect(communityBox!.y).toBeGreaterThanOrEqual(brandBox!.y + brandBox!.height); expect(communityBox!.y).toBeGreaterThanOrEqual(brandBox!.y + brandBox!.height);
expect(communityBox!.y - brandBox!.y - brandBox!.height).toBe(10); expect(communityBox!.y - brandBox!.y - brandBox!.height).toBe(10);
expect(createBox!.y - communityBox!.y - communityBox!.height).toBe(10); expect(createBox!.y - communityBox!.y - communityBox!.height).toBe(10);
expect(createBox!.y - brandBox!.y - brandBox!.height).toBe(61); expect(createBox!.y - brandBox!.y - brandBox!.height).toBe(communityBox!.height + 20);
expect(communityBox!.height).toBe(createBox!.height); expect(communityBox!.height).toBe(createBox!.height);
await expect(community).toHaveCSS('background-color', 'rgb(248, 250, 245)'); await expect(community).toHaveCSS('background-color', 'rgba(0, 0, 0, 0)');
const buttonStyles = await page.evaluate(() => { const buttonStyles = await page.evaluate(() => {
const styles = (selector: string) => { const styles = (selector: string) => {
const s = getComputedStyle(document.querySelector(selector)!); const s = getComputedStyle(document.querySelector(selector)!);
@@ -414,7 +415,9 @@ test.describe('Makelore module navigation without setup flow', () => {
await expect(sidebar.getByTestId('sidebar-module-switcher')).toHaveCount(0); await expect(sidebar.getByTestId('sidebar-module-switcher')).toHaveCount(0);
await page.screenshot({ path: test.info().outputPath('project-config-plugins-without-module-return.png') }); await page.screenshot({ path: test.info().outputPath('project-config-plugins-without-module-return.png') });
await plugins.getByRole('button', { name: '关闭', exact: true }).click(); await plugins.getByRole('button', { name: '关闭', exact: true }).click();
await expect(page).toHaveURL(/\/project-config$/); await expect(page).toHaveURL(/\/project-config(?:\?|$)/);
await expect(plugins).toHaveCount(0);
await expect(page.getByTestId('project-configuration-page')).toBeVisible();
await expect(projectBack).toBeVisible(); await expect(projectBack).toBeVisible();
await sidebar.getByTestId('sidebar-course-project-project-storybook').click(); await sidebar.getByTestId('sidebar-course-project-project-storybook').click();
await expect(page).toHaveURL(/\/chat$/); await expect(page).toHaveURL(/\/chat$/);
+15 -7
View File
@@ -1261,16 +1261,23 @@ test('first PI Conversation is editable under 500 ms and submits before runtime
await expect(page.getByTestId('coding-message-composer')).toBeInViewport({ ratio: 1 }); await expect(page.getByTestId('coding-message-composer')).toBeInViewport({ ratio: 1 });
expect(await page.getByTestId('coding-message-composer').evaluate(el => innerHeight - el.getBoundingClientRect().bottom)).toBeLessThan(40); expect(await page.getByTestId('coding-message-composer').evaluate(el => innerHeight - el.getBoundingClientRect().bottom)).toBeLessThan(40);
await expect(page.getByTestId('community-invitation')).toBeVisible(); const welcomeCommunity = page.getByTestId('community-welcome-link');
await expect(welcomeCommunity).toBeVisible();
await expect(page.getByTestId('community-invitation')).toHaveCount(0);
expect(await page.getByTestId('coding-message-composer').evaluate(el => { expect(await page.getByTestId('coding-message-composer').evaluate(el => {
const body = document.querySelector('.coding-chat-body')!.getBoundingClientRect(); const body = document.querySelector('.coding-chat-body')!.getBoundingClientRect();
const input = el.getBoundingClientRect(); const input = el.getBoundingClientRect();
return Math.abs(input.left + input.width / 2 - body.left - body.width / 2); return Math.abs(input.left + input.width / 2 - body.left - body.width / 2);
})).toBeLessThan(2); })).toBeLessThan(2);
expect(await page.getByTestId('community-invitation').evaluate(el => { expect(await welcomeCommunity.evaluate(el => {
const body = document.querySelector('.coding-chat-body')!.getBoundingClientRect();
const welcome = el.getBoundingClientRect();
return Math.abs(welcome.left + welcome.width / 2 - body.left - body.width / 2);
})).toBeLessThan(2);
expect(await welcomeCommunity.evaluate(el => {
const composer = document.querySelector('[data-testid="coding-message-composer"]')!; const composer = document.querySelector('[data-testid="coding-message-composer"]')!;
return composer.getBoundingClientRect().top - el.getBoundingClientRect().bottom; return composer.getBoundingClientRect().top - el.getBoundingClientRect().bottom;
})).toBeCloseTo(12, 0); })).toBeGreaterThan(12);
const pixelPng = Buffer.from( const pixelPng = Buffer.from(
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=', 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=',
@@ -1288,20 +1295,21 @@ test('first PI Conversation is editable under 500 ms and submits before runtime
scope.__communityOpened = []; scope.__communityOpened = [];
shell.openExternal = async url => { scope.__communityOpened!.push(url); }; shell.openExternal = async url => { scope.__communityOpened!.push(url); };
}); });
await page.getByRole('button', { name: '作品广场', exact: true }).click(); await page.getByTestId('sidebar').getByRole('button', { name: '作品广场', exact: true }).click();
await page.getByRole('button', { name: '去作品广场逛逛' }).click(); await welcomeCommunity.click();
await expect.poll(() => electronApp.evaluate(() => ( await expect.poll(() => electronApp.evaluate(() => (
(globalThis as typeof globalThis & { __communityOpened?: string[] }).__communityOpened (globalThis as typeof globalThis & { __communityOpened?: string[] }).__communityOpened
))).toEqual(['https://square.nianxx.cn/#explore', 'https://square.nianxx.cn/#explore']); ))).toEqual(['https://square.nianxx.cn/#explore', 'https://square.nianxx.cn/#explore']);
await expect(composer).toHaveValue('Build the first PI scene'); await expect(composer).toHaveValue('Build the first PI scene');
await expect(page.getByText('large.png', { exact: true })).toBeVisible(); await expect(page.getByRole('img', { name: 'large.png', exact: true })).toBeVisible();
await expect(page.getByRole('button', { name: '移除图片 large.png', exact: true })).toBeEnabled();
await expect(page.getByRole('dialog')).toHaveCount(0); await expect(page.getByRole('dialog')).toHaveCount(0);
expect((await readState(electronApp)).captured.filter(item => item.path.endsWith('/prompt') && item.method === 'POST')).toHaveLength(0); expect((await readState(electronApp)).captured.filter(item => item.path.endsWith('/prompt') && item.method === 'POST')).toHaveLength(0);
await expect(page.getByRole('button', { name: '发送' })).toBeEnabled(); await expect(page.getByRole('button', { name: '发送' })).toBeEnabled();
await page.getByTestId('coding-message-composer').evaluate( await page.getByTestId('coding-message-composer').evaluate(
(form: HTMLFormElement) => form.requestSubmit(), (form: HTMLFormElement) => form.requestSubmit(),
); );
await expect(page.getByTestId('community-invitation')).toHaveCount(0); await expect(welcomeCommunity).toHaveCount(0);
await expect.poll(async () => { await expect.poll(async () => {
const state = await readState(electronApp); const state = await readState(electronApp);