cloud-drive-renamer/tests/unit/config-panel-undo.test.ts
Zain 3d2ad5539c feat(uc): 新增 UC 网盘适配器并迁移包管理器至 pnpm
新增 UC 网盘适配器,包括页面脚本注入、API 调用、错误处理和完整的重命名工作流。同时将包管理器从 npm 迁移至 pnpm,更新
CI/CD 工作流、文档和锁文件,并扩展权限范围以支持 UC 网盘域名。
2026-08-06 11:36:01 +08:00

102 行
3.9 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import { ConfigPanel } from '../../src/content/components/config-panel';
describe('ConfigPanel undo action', () => {
it('uses balanced footer styles so execute button is compact and disabled undo stays visible', () => {
const cssText = ConfigPanel.styles.cssText;
const actionGroupRule = cssText.slice(cssText.indexOf('.execution-actions-main'), cssText.indexOf('.rule-selector'));
const footerButtonRule = cssText.slice(cssText.indexOf('.execution-actions .button'), cssText.indexOf('.button-icon:disabled'));
const disabledUndoRule = cssText.slice(cssText.indexOf('.button-icon:disabled'), cssText.indexOf('@keyframes cdr-undo-spin'));
expect(actionGroupRule).toContain('flex: 0 1 auto;');
expect(actionGroupRule).toContain('max-width: 100%;');
expect(footerButtonRule).toContain('flex: 0 0 auto;');
expect(footerButtonRule).toContain('min-width: 96px;');
expect(footerButtonRule).not.toContain('flex: 1;');
expect(cssText).toContain('.button-execute');
expect(cssText).toContain('min-width: 136px;');
expect(cssText).toContain('padding: 10px 14px;');
expect(disabledUndoRule).toContain('background: var(--cdr-surface-muted, #fafafa);');
expect(disabledUndoRule).toContain('border-color: var(--cdr-border, #f0f0f0);');
expect(disabledUndoRule).toContain('opacity: 0.72;');
expect(disabledUndoRule).not.toContain('background: transparent;');
});
it('renders undo button in finished view and dispatches undo event on click', async () => {
const panel = new ConfigPanel();
panel.finished = true;
panel.canUndo = true;
panel.undoBusy = false;
panel.progress = {
completed: 1,
total: 1,
currentFile: '',
success: 1,
failed: 0,
};
document.body.appendChild(panel);
await panel.updateComplete;
const events: Event[] = [];
panel.addEventListener('undo', (event) => events.push(event));
const undoButton = panel.shadowRoot?.querySelector<HTMLButtonElement>('[data-role="undo-icon-button"]');
expect(undoButton).toBeTruthy();
expect(undoButton?.hasAttribute('disabled')).toBe(false);
expect(undoButton?.getAttribute('aria-label')).toBeTruthy();
expect((undoButton?.textContent || '').trim()).toBe('');
undoButton?.dispatchEvent(new MouseEvent('click', { bubbles: true, composed: true }));
expect(events).toHaveLength(1);
panel.remove();
});
it('keeps the execute button disabled without showing cancel before progress starts', async () => {
const panel = new ConfigPanel();
panel.finished = false;
panel.executing = true;
panel.progress = null;
panel.selectedCount = 2;
panel.renameCount = 2;
document.body.appendChild(panel);
await panel.updateComplete;
const executeButton = panel.shadowRoot?.querySelector<HTMLButtonElement>('.button-execute');
const executionView = panel.shadowRoot?.querySelector('.execution-view');
const cancelButton = panel.shadowRoot?.querySelector('.button-danger');
expect(executeButton).toBeTruthy();
expect(executeButton?.hasAttribute('disabled')).toBe(true);
expect(executionView).toBeNull();
expect(cancelButton).toBeNull();
panel.remove();
});
it('renders undo button in normal config view when a valid undo record exists', async () => {
const panel = new ConfigPanel();
panel.finished = false;
panel.executing = false;
panel.canUndo = true;
panel.undoBusy = false;
panel.selectedCount = 2;
panel.renameCount = 2;
document.body.appendChild(panel);
await panel.updateComplete;
const undoButton = panel.shadowRoot?.querySelector<HTMLButtonElement>('[data-role="undo-icon-button"]');
expect(undoButton).toBeTruthy();
expect(undoButton?.getAttribute('aria-label')).toBeTruthy();
expect((undoButton?.textContent || '').trim()).toBe('');
panel.remove();
});
});