Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions apps/desktop/e2e/accessibility-coverage.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,19 +91,17 @@ test('module pages and global overlays expose named actionable controls', async
await assertAxHealth(cdp, 'extensions/mcp');

await navigation.getByRole('button', { name: /定时任务/ }).click();
const automationsNavigation = page.getByRole('navigation', { name: /定时任务内容/ });
await expect(
automationsNavigation.getByRole('button', { name: '定时任务', exact: true }),
).toHaveAttribute('aria-current', 'true');
await expect(page.locator('[data-module="scheduled-tasks"]')).toBeVisible();
await assertAxHealth(cdp, 'automations/scheduled-tasks');
const automationsNavigation = page.getByRole('navigation', { name: /定时任务内容/ });
const dailyReviewButton = automationsNavigation.getByRole('button', {
name: '每日回顾',
exact: true,
});
await dailyReviewButton.click();
await expect(page.locator('[data-module="daily-review"]')).toBeVisible();
await expect(dailyReviewButton).toHaveAttribute('aria-current', 'true');
await assertAxHealth(cdp, 'automations/daily-review');

await page.keyboard.press('Shift+Slash');
const keyboardHelpDialog = page.getByRole('dialog', { name: '键盘快捷键' });
await expect(keyboardHelpDialog).toBeVisible();
Expand Down
9 changes: 9 additions & 0 deletions apps/desktop/e2e/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -486,11 +486,20 @@ export const test = base.extend<{
promptRailMotionWindow: Page;
requestHeaderRowWindow: Page;
newTaskTargetWindow: Page;
dailyReviewWindow: Page;
}>({
// Seeded: a pre-staged connection clears onboarding so the composer is ready.
window: async ({}, use) => {
await withE2eWindow({ seed: true, readinessSelector: COMPOSER_INPUT, locale: 'zh' }, use);
},
dailyReviewWindow: async ({}, use) => {
await withE2eWindow({
seed: false,
readinessSelector: '[data-module="daily-review"]',
e2eFixtureScenario: 'module-daily-review',
locale: 'zh',
}, use);
},
onboardingWindow: async ({}, use) => {
await withE2eWindow({
seed: false,
Expand Down
25 changes: 23 additions & 2 deletions apps/desktop/e2e/module-hub.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

import { expect, test } from './fixtures';

test('Module Hub switches all four leaves and opens scheduled creation once', async ({
test('Module Hub switches its four leaves and opens scheduled creation once', async ({
window: page,
}) => {
const expand = page.getByRole('button', { name: '展开侧边栏' });
Expand All @@ -39,7 +39,18 @@ test('Module Hub switches all four leaves and opens scheduled creation once', as
const automations = page.getByRole('navigation', { name: /定时任务内容/ });
await automations.getByRole('button', { name: '每日回顾', exact: true }).click();
await expect(page.locator('[data-module="daily-review"]')).toBeVisible();

await expect(
automations.getByRole('button', { name: '每日回顾', exact: true }),
).toHaveAttribute('aria-current', 'true');
await page.getByRole('button', { name: '设置每日回顾', exact: true }).click();
const presetDialog = page.getByRole('dialog', { name: '新建定时任务' });
await expect(presetDialog).toBeVisible();
await expect(presetDialog.getByRole('textbox', { name: '标题' })).toHaveValue('每日回顾');
await expect(presetDialog.getByRole('textbox', { name: '备注' })).toHaveValue(/普通任务历史/);
await page.keyboard.press('Escape');
await expect(presetDialog).toBeHidden();
await automations.getByRole('button', { name: '定时任务', exact: true }).click();
await expect(page.locator('[data-module="scheduled-tasks"]')).toBeVisible();
await page.keyboard.press(process.platform === 'darwin' ? 'Meta+k' : 'Control+k');
const palette = page.getByRole('dialog', { name: '命令面板' });
await expect(palette).toBeVisible();
Expand All @@ -50,3 +61,13 @@ test('Module Hub switches all four leaves and opens scheduled creation once', as
await expect(createDialog).toHaveCount(1);
await expect(page.locator('[data-module="scheduled-tasks"]')).toBeVisible();
});

test('Daily Review manages its backing task through the Scheduled Tasks inspector', async ({
dailyReviewWindow: page,
}) => {
await page.getByRole('button', { name: '管理日程', exact: true }).click();
await expect(page.locator('[data-module="scheduled-tasks"]')).toBeVisible();
await expect(page.getByRole('heading', { name: 'Daily Review', exact: true })).toBeVisible();
await page.getByRole('button', { name: '编辑', exact: true }).click();
await expect(page.getByRole('dialog', { name: '编辑定时任务' })).toBeVisible();
});
52 changes: 36 additions & 16 deletions apps/desktop/src/main/__tests__/daily-review-fixture.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,38 +22,58 @@ import { mkdtemp, rm } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { test } from 'node:test';
import { openInteractiveDailyReviewAuthorityForWrite } from '@maka/storage/daily-review-authority';
import {
scheduledTaskPresetSessionLabel,
scheduledTaskSessionLabel,
} from '@maka/core/scheduled-task';
import { openInteractiveScheduledTaskStoreForWrite } from '@maka/storage/scheduled-task-store';
import {
resolveStorageRoot,
tryAcquireInteractiveRootOwner,
} from '@maka/storage/root-authority';
import { writeDailyReviewArchives } from '../e2e-fixture/scenarios-settings.js';
import { dailyReviewSessions } from '../e2e-fixture/scenarios-sessions.js';
import {
writeConnections,
writeScheduledTasks,
} from '../e2e-fixture/scenarios-settings.js';

test('Daily Review fixture seeds archives through the storage authority', async () => {
test('Daily Review fixture uses the ScheduledTask and ordinary Session shapes', async () => {
const workspaceRoot = await mkdtemp(join(tmpdir(), 'maka-daily-review-fixture-'));
const now = Date.UTC(2026, 4, 22, 11, 0, 0);
try {
await writeDailyReviewArchives(workspaceRoot, Date.UTC(2026, 4, 21, 12, 0, 0));
await writeConnections(workspaceRoot, now, 'module-daily-review');
await writeScheduledTasks(workspaceRoot, now, 'module-daily-review');

const capability = await resolveStorageRoot({ path: workspaceRoot, kind: 'interactive' });
const owner = await tryAcquireInteractiveRootOwner(capability);
assert.ok(owner);
if (!owner) return;
const store = await openInteractiveScheduledTaskStoreForWrite(owner.lease);
try {
const writer = await openInteractiveDailyReviewAuthorityForWrite(owner.lease);
try {
const page = await writer.listArchivePage(null, 180);
assert.deepEqual(
page.archives.map((archive) => archive.id),
['2026-05-21-1d', '2026-05-15-7d'],
);
assert.ok(await writer.getArchive('2026-05-21-1d'));
assert.ok(await writer.getArchive('2026-05-15-7d'));
} finally {
writer.close();
}
const task = await store.get('system-daily-review');
assert.equal(task?.presetId, 'daily-review');
assert.equal(task?.createdBy.kind, 'system');
assert.equal(task?.schedule.kind, 'calendar');
assert.equal(task?.effect.kind, 'agent_run');
assert.ok(task?.effect.kind === 'agent_run' && task.effect.execution.llmConnectionId);
} finally {
store.close();
await owner.close();
}

const sessions = dailyReviewSessions(now);
assert.deepEqual(sessions.map(({ header }) => header.labels), [
[
'scheduled-task',
scheduledTaskSessionLabel('system-daily-review'),
scheduledTaskPresetSessionLabel('daily-review'),
],
['migrated:daily-review'],
]);
assert.deepEqual(sessions.map(({ messages }) => messages[0]?.type), [
'assistant',
'assistant',
]);
} finally {
await rm(workspaceRoot, { recursive: true, force: true });
}
Expand Down
6 changes: 3 additions & 3 deletions apps/desktop/src/main/__tests__/module-hub-boundary.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,8 @@ describe('Module Hub feature boundary', () => {
);
assert.equal(commands.includes('dailyReviewBridge'), false);
assert.equal(commands.includes('saveDailyReviewMarkdown'), false);
assert.equal(commands.includes('copyTodayDailyReview()'), true);
assert.equal(commands.includes('pasteTodayDailyReview()'), true);
assert.equal(commands.includes('saveTodayDailyReview()'), true);
assert.equal(commands.includes('copyTodayDailyReview()'), false);
assert.equal(commands.includes('pasteTodayDailyReview()'), false);
assert.equal(commands.includes('saveTodayDailyReview()'), false);
});
});
Loading
Loading