Develop (#55)
feat: optimize dashboard/search UX and simplify extension architecture Redesign Dashboard with compact tool grid and recently used tools Improve TopBar search UX with Cmd/Ctrl+K shortcut and better history navigation Reorganize project structure into src/ Migrate i18n from react-i18next to chrome.i18n Remove runtime language switch and settings page Remove HTML/Markdown conversion tools Clean up unused code, dead animations, redundant comments, and imports Improve component consistency with shadcn/ui patterns Replace hardcoded strings/colors with i18n tokens and theme tokens Add comprehensive project documentation and coding standards Fix CI artifact upload workflow and multiple TypeScript/test issues Includes various refactors, UI polish, i18n cleanup, CI improvements, and maintenance updates across the codebase.
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import { render } from '@testing-library/react';
|
||||
import RouterContainer from '@/components/RouterContainer';
|
||||
import { RouterProvider } from '@/providers/RouterProvider';
|
||||
import { SnackbarProvider } from '@/components/GlobalSnackbar';
|
||||
import type { PageType } from '@/types/storage';
|
||||
import React from 'react';
|
||||
|
||||
const mockRouterValue = {
|
||||
currentPage: 'dashboard' as PageType,
|
||||
visiblePages: ['dashboard', 'timestamp'] as PageType[],
|
||||
pageOrder: ['timestamp'] as PageType[],
|
||||
isLoaded: true,
|
||||
navigateTo: vi.fn(),
|
||||
syncNavigation: vi.fn(),
|
||||
goBack: vi.fn(),
|
||||
setVisiblePages: vi.fn(),
|
||||
setPageOrder: vi.fn(),
|
||||
};
|
||||
|
||||
vi.mock('@/providers/RouterProvider', () => ({
|
||||
useRouter: () => mockRouterValue,
|
||||
RouterProvider: ({ children }: { children: React.ReactNode }) => children,
|
||||
}));
|
||||
|
||||
describe('RouterContainer 组件', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
const renderWithProvider = (ui: React.ReactElement) => {
|
||||
return render(
|
||||
<SnackbarProvider>
|
||||
<RouterProvider>{ui}</RouterProvider>
|
||||
</SnackbarProvider>,
|
||||
);
|
||||
};
|
||||
|
||||
describe('渲染测试', () => {
|
||||
it('isLoaded 为 false 时应渲染骨架屏', () => {
|
||||
mockRouterValue.isLoaded = false;
|
||||
const { container } = renderWithProvider(<RouterContainer />);
|
||||
// 骨架屏使用 animate-pulse 类
|
||||
const skeletons = container.querySelectorAll('.animate-pulse');
|
||||
expect(skeletons.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('isLoaded 为 true 时应渲染页面内容', () => {
|
||||
mockRouterValue.isLoaded = true;
|
||||
mockRouterValue.currentPage = 'dashboard';
|
||||
const { container } = renderWithProvider(<RouterContainer />);
|
||||
expect(container.querySelector('.page-transition-dashboard')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('动画类测试', () => {
|
||||
it('在 dashboard 页面应应用 dashboard 动画类', () => {
|
||||
mockRouterValue.currentPage = 'dashboard';
|
||||
renderWithProvider(<RouterContainer />);
|
||||
const box = document.querySelector('.page-transition-dashboard');
|
||||
expect(box).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('在非 dashboard 页面应应用 enter 动画类', () => {
|
||||
mockRouterValue.currentPage = 'timestamp';
|
||||
renderWithProvider(<RouterContainer />);
|
||||
const box = document.querySelector('.page-transition-enter');
|
||||
expect(box).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('路由处理测试', () => {
|
||||
it('currentPage 变化时应更新', () => {
|
||||
const { rerender } = renderWithProvider(<RouterContainer />);
|
||||
|
||||
mockRouterValue.currentPage = 'timestamp';
|
||||
rerender(
|
||||
<SnackbarProvider>
|
||||
<RouterProvider>{<RouterContainer />}</RouterProvider>
|
||||
</SnackbarProvider>,
|
||||
);
|
||||
|
||||
const box = document.querySelector('.page-transition-enter');
|
||||
expect(box).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('页面级错误隔离', () => {
|
||||
it('PageErrorBoundary 应包裹在 Suspense 内层', () => {
|
||||
mockRouterValue.isLoaded = true;
|
||||
mockRouterValue.currentPage = 'dashboard';
|
||||
const { container } = renderWithProvider(<RouterContainer />);
|
||||
|
||||
// 验证 RouterContainer 的 Box 结构存在
|
||||
const routerBox = container.querySelector('.page-transition-dashboard');
|
||||
expect(routerBox).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user