新增受保护路由组件以增强认证逻辑,更新知识库管理页面的测试用例以集成用户事件,提升测试的准确性和稳定性。同时,优化相关依赖项配置,确保与最新库版本兼容,提升代码可维护性和用户体验。
This commit is contained in:
36
client/admin/components_protected_route.tsx
Normal file
36
client/admin/components_protected_route.tsx
Normal file
@@ -0,0 +1,36 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import {
|
||||
useNavigate,
|
||||
} from 'react-router';
|
||||
|
||||
|
||||
import { useAuth } from './hooks_sys.tsx';
|
||||
|
||||
|
||||
export const ProtectedRoute = ({ children }: { children: React.ReactNode }) => {
|
||||
const { isAuthenticated, isLoading } = useAuth();
|
||||
const navigate = useNavigate();
|
||||
|
||||
useEffect(() => {
|
||||
// 只有在加载完成且未认证时才重定向
|
||||
if (!isLoading && !isAuthenticated) {
|
||||
navigate('/admin/login', { replace: true });
|
||||
}
|
||||
}, [isAuthenticated, isLoading, navigate]);
|
||||
|
||||
// 显示加载状态,直到认证检查完成
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="flex justify-center items-center h-screen">
|
||||
<div className="loader ease-linear rounded-full border-4 border-t-4 border-gray-200 h-12 w-12"></div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// 如果未认证且不再加载中,不显示任何内容(等待重定向)
|
||||
if (!isAuthenticated) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return children;
|
||||
};
|
||||
@@ -1,7 +1,9 @@
|
||||
import { JSDOM } from 'jsdom'
|
||||
import React from 'react'
|
||||
import {render, fireEvent, within, screen, waitFor} from '@testing-library/react'
|
||||
import {render, fireEvent, within, screen, waitFor, configure} from '@testing-library/react'
|
||||
import {userEvent} from '@testing-library/user-event'
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
||||
import { createBrowserRouter, RouterProvider, Navigate } from 'react-router'
|
||||
import {
|
||||
assertEquals,
|
||||
assertExists,
|
||||
@@ -12,25 +14,72 @@ import {
|
||||
import axios from 'axios';
|
||||
import { KnowInfoPage } from "./pages_know_info.tsx"
|
||||
import { AuthProvider } from './hooks_sys.tsx'
|
||||
import { ProtectedRoute } from './components_protected_route.tsx'
|
||||
|
||||
// 拦截React DOM中的attachEvent和detachEvent错误
|
||||
const originalError = console.error;
|
||||
console.error = (...args) => {
|
||||
// 过滤掉attachEvent和detachEvent相关的错误
|
||||
if (args[0] instanceof Error) {
|
||||
if (args[0].message?.includes('attachEvent is not a function') ||
|
||||
args[0].message?.includes('detachEvent is not a function')) {
|
||||
return; // 不输出这些错误
|
||||
}
|
||||
} else if (typeof args[0] === 'string') {
|
||||
if (args[0].includes('attachEvent is not a function') ||
|
||||
args[0].includes('detachEvent is not a function')) {
|
||||
return; // 不输出这些错误
|
||||
}
|
||||
}
|
||||
originalError(...args);
|
||||
};
|
||||
|
||||
// // 配置Testing Library的eventWrapper来处理这个问题
|
||||
// configure({
|
||||
// eventWrapper: (cb) => {
|
||||
// try {
|
||||
// return cb();
|
||||
// } catch (error) {
|
||||
// console.log('eventWrapper', cb)
|
||||
// // 忽略attachEvent和detachEvent相关的错误
|
||||
// if (error instanceof Error &&
|
||||
// (error.message?.includes('attachEvent is not a function') ||
|
||||
// error.message?.includes('detachEvent is not a function'))) {
|
||||
// // 忽略这个错误并返回一个默认值
|
||||
// return undefined;
|
||||
// }
|
||||
// // 其他错误正常抛出
|
||||
// throw error;
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
|
||||
const queryClient = new QueryClient()
|
||||
|
||||
const dom = new JSDOM(`<body></body>`, {
|
||||
runScripts: "dangerously",
|
||||
pretendToBeVisual: true,
|
||||
url: "http://localhost"
|
||||
url: "http://localhost",
|
||||
});
|
||||
|
||||
// 模拟浏览器环境
|
||||
globalThis.window = dom.window;
|
||||
globalThis.document = dom.window.document;
|
||||
|
||||
// 添加必要的 DOM 配置
|
||||
globalThis.Node = dom.window.Node;
|
||||
globalThis.Document = dom.window.Document;
|
||||
globalThis.HTMLInputElement = dom.window.HTMLInputElement;
|
||||
globalThis.HTMLButtonElement = dom.window.HTMLButtonElement;
|
||||
|
||||
// 定义浏览器环境所需的类
|
||||
globalThis.Element = dom.window.Element;
|
||||
globalThis.HTMLElement = dom.window.HTMLElement;
|
||||
globalThis.ShadowRoot = dom.window.ShadowRoot;
|
||||
globalThis.SVGElement = dom.window.SVGElement;
|
||||
|
||||
|
||||
|
||||
// 模拟 getComputedStyle
|
||||
globalThis.getComputedStyle = (elt) => {
|
||||
const style = new dom.window.CSSStyleDeclaration();
|
||||
@@ -72,6 +121,22 @@ axios.defaults.baseURL = 'https://23957.dev.d8dcloud.com'
|
||||
|
||||
const customScreen = within(document.body);
|
||||
|
||||
// 应用入口组件
|
||||
const App = () => {
|
||||
// 路由配置
|
||||
const router = createBrowserRouter([
|
||||
{
|
||||
path: '/',
|
||||
element: (
|
||||
<ProtectedRoute>
|
||||
<KnowInfoPage />
|
||||
</ProtectedRoute>
|
||||
)
|
||||
},
|
||||
]);
|
||||
return <RouterProvider router={router} />
|
||||
};
|
||||
|
||||
// 使用异步测试处理组件渲染
|
||||
Deno.test({
|
||||
name: '知识库管理页面测试',
|
||||
@@ -105,6 +170,8 @@ Deno.test({
|
||||
globalThis.setInterval = originalSetInterval;
|
||||
};
|
||||
|
||||
|
||||
|
||||
try {
|
||||
// 渲染组件
|
||||
const {
|
||||
@@ -113,79 +180,116 @@ Deno.test({
|
||||
} = render(
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<AuthProvider>
|
||||
<KnowInfoPage />
|
||||
<App />
|
||||
</AuthProvider>
|
||||
</QueryClientProvider>
|
||||
);
|
||||
|
||||
// 测试1: 基本渲染
|
||||
await t.step('应正确渲染页面元素', async () => {
|
||||
const title = await findByText(/知识库管理/i);
|
||||
assertExists(title, '未找到知识库管理标题');
|
||||
await waitFor(async () => {
|
||||
const title = await findByText(/知识库管理/i);
|
||||
assertExists(title, '未找到知识库管理标题');
|
||||
}, {
|
||||
timeout: 1000 * 5,
|
||||
});
|
||||
});
|
||||
|
||||
let i = 0
|
||||
|
||||
// 初始加载表格数据
|
||||
await waitFor(async () => {
|
||||
const table = await findByRole('table');
|
||||
const rows = await within(table).findAllByRole('row');
|
||||
|
||||
// debug(rows[1])
|
||||
i++
|
||||
console.log('i', i)
|
||||
console.log('rows', rows.length)
|
||||
|
||||
// 应该大于2行
|
||||
// assert(rows.length > 2, '表格没有数据'); // 1是表头行 2是数据行
|
||||
|
||||
if (rows.length <= 2) {
|
||||
throw new Error('表格没有数据');
|
||||
}
|
||||
}, {
|
||||
timeout: 1000 * 10,
|
||||
});
|
||||
|
||||
// 测试2: 搜索表单功能
|
||||
await t.step('搜索表单应正常工作', async () => {
|
||||
const searchInput = await findByPlaceholderText(/请输入文章标题/i) as HTMLInputElement;
|
||||
const searchButton = await findByText(/搜 索/i);
|
||||
|
||||
// 输入搜索内容
|
||||
fireEvent.change(searchInput, { target: { value: '数据分析' } });
|
||||
assertEquals(searchInput.value, '数据分析', '搜索输入框值未更新');
|
||||
|
||||
// 提交搜索
|
||||
fireEvent.click(searchButton);
|
||||
|
||||
// // 验证是否触发了搜索
|
||||
// await waitFor(() => {
|
||||
// const loading = queryByText(/正在加载数据/i);
|
||||
// assertNotEquals(loading, null, '搜索未触发加载状态');
|
||||
// });
|
||||
|
||||
// 等待搜索结果并验证
|
||||
await t.step('初始加载表格数据', async () => {
|
||||
await waitFor(async () => {
|
||||
const table = await findByRole('table');
|
||||
const rows = await within(table).findAllByRole('row');
|
||||
|
||||
debug(rows)
|
||||
|
||||
console.log('rows', rows.length);
|
||||
// 应该大于2行
|
||||
assert(rows.length > 2, '表格没有数据'); // 1是表头行 2是数据行
|
||||
|
||||
// 检查至少有一行包含"数据分析"
|
||||
const hasMatch = rows.some(async row => {
|
||||
const cells = await within(row).findAllByRole('cell');
|
||||
return cells.some(cell => cell.textContent?.includes('数据分析'));
|
||||
});
|
||||
|
||||
console.log('hasMatch', hasMatch);
|
||||
|
||||
assert(hasMatch, '搜索结果中没有找到包含"数据分析"的文章');
|
||||
}, {
|
||||
timeout: 5000,
|
||||
timeout: 1000 * 5,
|
||||
});
|
||||
});
|
||||
|
||||
// 测试2: 搜索表单功能
|
||||
await t.step('搜索表单应正常工作', async () => {
|
||||
// 确保在正确的测试环境中设置 userEvent
|
||||
const user = userEvent.setup({
|
||||
document: dom.window.document,
|
||||
delay: 0
|
||||
});
|
||||
|
||||
const searchInput = await findByPlaceholderText(/请输入文章标题/i) as HTMLInputElement;
|
||||
const searchButton = await findByText(/搜 索/i);
|
||||
|
||||
assertExists(searchInput, '未找到搜索输入框');
|
||||
assertExists(searchButton, '未找到搜索按钮');
|
||||
|
||||
// 输入搜索内容
|
||||
try {
|
||||
await user.type(searchInput, '数据分析')
|
||||
} catch (error: unknown) {
|
||||
// console.error('输入搜索内容失败', error)
|
||||
}
|
||||
assertEquals(searchInput.value, '数据分析', '搜索输入框值未更新');
|
||||
|
||||
console.log('searchInput', searchInput.value)
|
||||
|
||||
debug(searchInput)
|
||||
debug(searchButton)
|
||||
|
||||
// 提交搜索
|
||||
try {
|
||||
await user.click(searchButton);
|
||||
} catch (error: unknown) {
|
||||
// console.error('点击搜索按钮失败', error)
|
||||
}
|
||||
|
||||
|
||||
let rows: HTMLElement[] = [];
|
||||
|
||||
|
||||
const table = await findByRole('table');
|
||||
assertExists(table, '未找到数据表格');
|
||||
|
||||
// 等待表格刷新并验证
|
||||
await waitFor(async () => {
|
||||
rows = await within(table).findAllByRole('row');
|
||||
console.log('等待表格刷新并验证', rows.length)
|
||||
assert(rows.length === 2, '表格未刷新');
|
||||
}, {
|
||||
timeout: 1000 * 5,
|
||||
onTimeout: () => new Error('等待表格刷新超时')
|
||||
});
|
||||
|
||||
// 等待搜索结果并验证
|
||||
await waitFor(async () => {
|
||||
rows = await within(table).findAllByRole('row');
|
||||
console.log('等待搜索结果并验证', rows.length)
|
||||
assert(rows.length > 2, '表格没有数据');
|
||||
}, {
|
||||
timeout: 1000 * 5,
|
||||
onTimeout: () => new Error('等待搜索结果超时')
|
||||
});
|
||||
|
||||
|
||||
|
||||
// 检查至少有一行包含"数据分析"
|
||||
const matchResults = await Promise.all(rows.map(async row => {
|
||||
try{
|
||||
const cells = await within(row).findAllByRole('cell');
|
||||
return cells.some(cell => {
|
||||
return cell.textContent?.includes('数据分析')
|
||||
});
|
||||
} catch (error: unknown) {
|
||||
// console.error('搜索结果获取失败', error)
|
||||
return false
|
||||
}
|
||||
}))
|
||||
// console.log('matchResults', matchResults)
|
||||
const hasMatch = matchResults.some(result => result);
|
||||
|
||||
console.log('hasMatch', hasMatch)
|
||||
|
||||
assert(hasMatch, '搜索结果中没有找到包含"数据分析"的文章');
|
||||
});
|
||||
|
||||
// 测试3: 表格数据加载
|
||||
|
||||
@@ -148,6 +148,7 @@ export const KnowInfoPage = () => {
|
||||
// 处理搜索
|
||||
const handleSearch = async (values: any) => {
|
||||
try {
|
||||
console.log('handleSearch', values)
|
||||
queryClient.removeQueries({ queryKey: ['knowInfos'] });
|
||||
setSearchParams({
|
||||
title: values.title || '',
|
||||
@@ -286,7 +287,7 @@ export const KnowInfoPage = () => {
|
||||
<Button type="primary" htmlType="submit">
|
||||
搜索
|
||||
</Button>
|
||||
<Button onClick={() => {
|
||||
<Button htmlType="reset" onClick={() => {
|
||||
setSearchParams({
|
||||
title: '',
|
||||
category: '',
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect, createContext, useContext } from 'react';
|
||||
import React, { useState, useEffect} from 'react';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
import {
|
||||
createBrowserRouter,
|
||||
@@ -18,7 +18,6 @@ import {
|
||||
Switch, Badge, Image, Upload, Divider, Descriptions,
|
||||
Popconfirm, Tag, Statistic, DatePicker, Radio, Progress, Tabs, List, Alert, Collapse, Empty, Drawer
|
||||
} from 'antd';
|
||||
import zhCN from "antd/locale/zh_CN";
|
||||
import {
|
||||
MenuFoldOutlined,
|
||||
MenuUnfoldOutlined,
|
||||
@@ -31,8 +30,6 @@ import {
|
||||
BookOutlined,
|
||||
FileOutlined,
|
||||
PieChartOutlined,
|
||||
UploadOutlined,
|
||||
GlobalOutlined,
|
||||
VerticalAlignTopOutlined,
|
||||
CloseOutlined,
|
||||
SearchOutlined
|
||||
@@ -40,27 +37,15 @@ import {
|
||||
import {
|
||||
QueryClient,
|
||||
QueryClientProvider,
|
||||
useQuery,
|
||||
useMutation,
|
||||
useQueryClient
|
||||
} from '@tanstack/react-query';
|
||||
import axios from 'axios';
|
||||
import dayjs from 'dayjs';
|
||||
import weekday from 'dayjs/plugin/weekday';
|
||||
import localeData from 'dayjs/plugin/localeData';
|
||||
import { uploadMinIOWithPolicy } from '@d8d-appcontainer/api';
|
||||
import type { MinioUploadPolicy } from '@d8d-appcontainer/types';
|
||||
import { Line, Pie, Column } from "@ant-design/plots";
|
||||
import 'dayjs/locale/zh-cn';
|
||||
import type {
|
||||
GlobalConfig
|
||||
} from '../share/types.ts';
|
||||
|
||||
import {
|
||||
EnableStatus, DeleteStatus, ThemeMode, FontSize, CompactMode
|
||||
} from '../share/types.ts';
|
||||
|
||||
import { getEnumOptions } from './utils.ts';
|
||||
|
||||
import {
|
||||
AuthProvider,
|
||||
@@ -81,7 +66,7 @@ import {ThemeSettingsPage} from './pages_theme_settings.tsx'
|
||||
import { ChartDashboardPage } from './pages_chart.tsx';
|
||||
import { LoginMapPage } from './pages_map.tsx';
|
||||
import { LoginPage } from './pages_login_reg.tsx';
|
||||
|
||||
import { ProtectedRoute } from './components_protected_route.tsx';
|
||||
|
||||
// 配置 dayjs 插件
|
||||
dayjs.extend(weekday);
|
||||
@@ -440,34 +425,7 @@ const MainLayout = () => {
|
||||
);
|
||||
};
|
||||
|
||||
// 受保护的路由组件
|
||||
const ProtectedRoute = ({ children }: { children: React.ReactNode }) => {
|
||||
const { isAuthenticated, isLoading } = useAuth();
|
||||
const navigate = useNavigate();
|
||||
|
||||
useEffect(() => {
|
||||
// 只有在加载完成且未认证时才重定向
|
||||
if (!isLoading && !isAuthenticated) {
|
||||
navigate('/admin/login', { replace: true });
|
||||
}
|
||||
}, [isAuthenticated, isLoading, navigate]);
|
||||
|
||||
// 显示加载状态,直到认证检查完成
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="flex justify-center items-center h-screen">
|
||||
<div className="loader ease-linear rounded-full border-4 border-t-4 border-gray-200 h-12 w-12"></div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// 如果未认证且不再加载中,不显示任何内容(等待重定向)
|
||||
if (!isAuthenticated) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return children;
|
||||
};
|
||||
|
||||
|
||||
// 错误页面组件
|
||||
const ErrorPage = () => {
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
"@heroicons/react/24/outline": "https://esm.d8d.fun/@heroicons/react@2.1.1/24/outline?dev&deps=react@19.0.0,react-dom@19.0.0",
|
||||
"@heroicons/react/24/solid": "https://esm.d8d.fun/@heroicons/react@2.1.1/24/solid?dev&deps=react@19.0.0,react-dom@19.0.0",
|
||||
"@testing-library/react": "https://esm.d8d.fun/@testing-library/react@16.3.0?dev&deps=react@19.0.0,react-dom@19.0.0",
|
||||
"@testing-library/user-event":"npm:@testing-library/user-event@14.6.1",
|
||||
"jsdom":"npm:jsdom@26.0.0"
|
||||
},
|
||||
"compilerOptions": {
|
||||
|
||||
13
deno.lock
generated
13
deno.lock
generated
@@ -6,6 +6,7 @@
|
||||
"npm:@testing-library/react@*": "16.3.0_@testing-library+dom@10.4.0_react@19.1.0_react-dom@19.1.0__react@19.1.0",
|
||||
"npm:@testing-library/react@16.3.0": "16.3.0_@testing-library+dom@10.4.0_react@19.1.0_react-dom@19.1.0__react@19.1.0",
|
||||
"npm:@testing-library/user-event@*": "14.6.1_@testing-library+dom@10.4.0",
|
||||
"npm:@testing-library/user-event@14.6.1": "14.6.1_@testing-library+dom@10.4.0",
|
||||
"npm:@types/node@*": "22.12.0",
|
||||
"npm:antd@*": "5.24.6_react@19.1.0_react-dom@19.1.0__react@19.1.0_dayjs@1.11.13",
|
||||
"npm:global-jsdom@*": "26.0.0_jsdom@26.0.0",
|
||||
@@ -1377,6 +1378,7 @@
|
||||
"https://esm.d8d.fun/@deno/shim-deno@~0.18.0?target=denonext": "https://esm.d8d.fun/@deno/shim-deno@0.18.2?target=denonext",
|
||||
"https://esm.d8d.fun/@socket.io/component-emitter@~3.1.0?target=denonext": "https://esm.d8d.fun/@socket.io/component-emitter@3.1.2?target=denonext",
|
||||
"https://esm.d8d.fun/@testing-library/dom": "https://esm.d8d.fun/@testing-library/dom@10.4.0",
|
||||
"https://esm.d8d.fun/@testing-library/dom@%3E=7.21.4?target=denonext": "https://esm.d8d.fun/@testing-library/dom@10.4.0?target=denonext",
|
||||
"https://esm.d8d.fun/@testing-library/dom@^10.0.0?target=denonext": "https://esm.d8d.fun/@testing-library/dom@10.4.0?target=denonext",
|
||||
"https://esm.d8d.fun/@testing-library/dom@^10.0.0?target=denonext&dev": "https://esm.d8d.fun/@testing-library/dom@10.4.0?target=denonext&dev",
|
||||
"https://esm.d8d.fun/@testing-library/react?deps=react@19.0.0,react-dom@19.0.0": "https://esm.d8d.fun/@testing-library/react@16.3.0?deps=react@19.0.0,react-dom@19.0.0",
|
||||
@@ -1427,6 +1429,7 @@
|
||||
"https://esm.d8d.fun/@types/react-dom@~19.0.4/client.d.ts": "https://esm.d8d.fun/@types/react-dom@19.0.6/client.d.ts",
|
||||
"https://esm.d8d.fun/@types/react-dom@~19.0.4/index.d.ts": "https://esm.d8d.fun/@types/react-dom@19.0.6/index.d.ts",
|
||||
"https://esm.d8d.fun/@types/react-dom@~19.0.6/client.d.ts": "https://esm.d8d.fun/@types/react-dom@19.0.6/client.d.ts",
|
||||
"https://esm.d8d.fun/@types/react-dom@~19.0.6/index.d.ts": "https://esm.d8d.fun/@types/react-dom@19.0.6/index.d.ts",
|
||||
"https://esm.d8d.fun/@types/react-dom@~19.1.2/client.d.ts": "https://esm.d8d.fun/@types/react-dom@19.1.2/client.d.ts",
|
||||
"https://esm.d8d.fun/@types/react-dom@~19.1.2/index.d.ts": "https://esm.d8d.fun/@types/react-dom@19.1.2/index.d.ts",
|
||||
"https://esm.d8d.fun/@types/react-dom@~19.1.2/test-utils/index.d.ts": "https://esm.d8d.fun/@types/react-dom@19.1.2/test-utils/index.d.ts",
|
||||
@@ -2777,8 +2780,12 @@
|
||||
"https://esm.d8d.fun/@deno/shim-deno@0.18.2/denonext/shim-deno.mjs": "819d8ac34fdaf60658cf03d137f14adaff3f13a279ffd79cd8797d84a6ac46ab",
|
||||
"https://esm.d8d.fun/@deno/shim-deno@0.18.2?target=denonext": "ffa3ca347bb6b6530720158f307a2e31b16728fbb52e6432254a07d52fcbc404",
|
||||
"https://esm.d8d.fun/@heroicons/react@2.1.1/24/outline?deps=react@19.0.0,react-dom@19.0.0": "5e99f4d40ce60c55b5cf421c3cf3f13df1707cf53152e447b2332570412cd77a",
|
||||
"https://esm.d8d.fun/@heroicons/react@2.1.1/24/outline?dev&deps=react@19.0.0,react-dom@19.0.0": "6b98b262ef98bf59857e12d089c9506e0a4f9982fb335ce22ff1f9f76ac4245a",
|
||||
"https://esm.d8d.fun/@heroicons/react@2.1.1/24/solid?deps=react@19.0.0,react-dom@19.0.0": "e3940182b574da537337b1e90a1b7f380e17050457423e13d5ac8c7bc88a3cc0",
|
||||
"https://esm.d8d.fun/@heroicons/react@2.1.1/24/solid?dev&deps=react@19.0.0,react-dom@19.0.0": "6c56d2e8d159ed0238518cd0dea1f1dfd3c05866a732e98f636bafa1b171153d",
|
||||
"https://esm.d8d.fun/@heroicons/react@2.1.1/X-ZHJlYWN0LWRvbUAxOS4wLjAscmVhY3RAMTkuMC4w/denonext/24/outline.development.mjs": "1045f8e5320626992f4a069bd24ae6c1f341d386d768bbf4904608bad876b0f3",
|
||||
"https://esm.d8d.fun/@heroicons/react@2.1.1/X-ZHJlYWN0LWRvbUAxOS4wLjAscmVhY3RAMTkuMC4w/denonext/24/outline.mjs": "640f934a0c987f682032049e5d4a455567db676de47bca0d44e76b72023661f7",
|
||||
"https://esm.d8d.fun/@heroicons/react@2.1.1/X-ZHJlYWN0LWRvbUAxOS4wLjAscmVhY3RAMTkuMC4w/denonext/24/solid.development.mjs": "00ca0e838f7d4df154ab86d24e36adbf88708606adf3ea2cc7cc56e59026540d",
|
||||
"https://esm.d8d.fun/@heroicons/react@2.1.1/X-ZHJlYWN0LWRvbUAxOS4wLjAscmVhY3RAMTkuMC4w/denonext/24/solid.mjs": "dcbd0c377d92857b6eb23c7dbb2ee6e650b12aa6ae1ef7fcc10dc1964df8ba47",
|
||||
"https://esm.d8d.fun/@socket.io/component-emitter@3.1.2/denonext/component-emitter.mjs": "3c6c5f2d64d4933b577a7117df1d8855c51ff01ab3dea8f42af1adcb1a5989e7",
|
||||
"https://esm.d8d.fun/@socket.io/component-emitter@3.1.2?target=denonext": "f6ff0f94ae3c9850a2c3a925cc2b236ec03a80fc2298d0ca48c2a90b10487db3",
|
||||
@@ -2803,6 +2810,8 @@
|
||||
"https://esm.d8d.fun/@testing-library/react@16.3.0?dev&deps=react@19.0.0,react-dom@19.0.0": "45f68d1334937328f1f41c9785e1beb85d912fff54fbb32eed597a4f262475a4",
|
||||
"https://esm.d8d.fun/@testing-library/react@16.3.0?dev&deps=react@19.0.0,react-dom@19.0.0&export=": "45f68d1334937328f1f41c9785e1beb85d912fff54fbb32eed597a4f262475a4",
|
||||
"https://esm.d8d.fun/@testing-library/react@16.3.0?dev&deps=react@19.0.0,react-dom@19.0.0&export=document": "45f68d1334937328f1f41c9785e1beb85d912fff54fbb32eed597a4f262475a4",
|
||||
"https://esm.d8d.fun/@testing-library/user-event@14.6.1": "3f7d71e48391de42ba52305286ecb9e6d3764e34867baec0a3575d24ed699dda",
|
||||
"https://esm.d8d.fun/@testing-library/user-event@14.6.1/denonext/user-event.mjs": "5c0a61f970c02d481dff4294bd64d739f049ea44e9b57f9c14450933a47252cb",
|
||||
"https://esm.d8d.fun/agent-base@7.1.3/denonext/agent-base.development.mjs": "0f740785213e5c410760457aa209a0f224da6d5cc65124626b7a1a344c0504f4",
|
||||
"https://esm.d8d.fun/agent-base@7.1.3/denonext/agent-base.mjs": "65d873bec0946614e2e33c0c3c1c958ee346695facfdeb51e2dda348e700bd57",
|
||||
"https://esm.d8d.fun/agent-base@7.1.3?target=denonext": "c76a77281d852899060a3ecf8bed33525c5f252f53dfac18e2f0ae5957b22910",
|
||||
@@ -3262,6 +3271,7 @@
|
||||
"https://esm.d8d.fun/react-dom@19.0.0/denonext/client.mjs": "af662fd134eea98f37fdcea6142accd0f8a7d2e13c1c3c9e98dc37a8c7aad46b",
|
||||
"https://esm.d8d.fun/react-dom@19.0.0/denonext/react-dom.development.mjs": "617b31a0b5be498d4ae231b7deee56d3efde81cd6a4cbec2da66291b08cac51c",
|
||||
"https://esm.d8d.fun/react-dom@19.0.0/denonext/react-dom.mjs": "a2f7bc344e1d5b7ca47e68665291e206ae4db17ee84f234f3d3e2533b9119f63",
|
||||
"https://esm.d8d.fun/react-dom@19.0.0?dev": "a80f467a0d1c4e36b15ff59a33c55646a33d35e761ea218b8354ea26980f34d2",
|
||||
"https://esm.d8d.fun/react-dom@19.1.0/client?target=denonext": "a84db2e3e86b71bf712d55f37603df8be4a624d7e93b63795524ec0554b1a6af",
|
||||
"https://esm.d8d.fun/react-dom@19.1.0/client?target=denonext&dev": "ac56773a1d6cde780e97c8337f3a66e5200d623fb90b93076f0fe6675f945306",
|
||||
"https://esm.d8d.fun/react-dom@19.1.0/denonext/client.development.mjs": "ae802423d440da19a3d9dec9e500e8c80f20f085f7ce6e8f06a26cf9e616ee3c",
|
||||
@@ -3274,8 +3284,10 @@
|
||||
"https://esm.d8d.fun/react-dom@19.1.0/test-utils?target=denonext&dev": "10082781244c8cce4b151b990b6475c52d5b83e422a09b66936da87cbdd8e35e",
|
||||
"https://esm.d8d.fun/react-dom@19.1.0?target=denonext": "0af10bc13bc7ef60cd74313dc427d357184e28c86cc878340add5cde7ba00120",
|
||||
"https://esm.d8d.fun/react-dom@19.1.0?target=denonext&dev": "cd750cefba42a1c5575f80e70fba6a2f1fdf3dac780cf380dbe5ffc005b04bd2",
|
||||
"https://esm.d8d.fun/react-hook-form@7.55.0/X-ZHJlYWN0LWRvbUAxOS4wLjAscmVhY3RAMTkuMC4w/denonext/react-hook-form.development.mjs": "b58c0d230f984a8dc8302b5dfddd173f03308faa92b432cd21edaa823fe43d8c",
|
||||
"https://esm.d8d.fun/react-hook-form@7.55.0/X-ZHJlYWN0LWRvbUAxOS4wLjAscmVhY3RAMTkuMC4w/denonext/react-hook-form.mjs": "788ec1a54e10051f539ba435aa513802c823bad03e11e2534b1b17df99189a87",
|
||||
"https://esm.d8d.fun/react-hook-form@7.55.0?deps=react@19.0.0,react-dom@19.0.0": "8ed376b3af6e11be43538b15e654692d5995232523a6dc16ce7f81263b1a3614",
|
||||
"https://esm.d8d.fun/react-hook-form@7.55.0?dev&deps=react@19.0.0,react-dom@19.0.0": "f4fc9cd4c769d32b703007cf3353ab2e0ddcd3de90a5536fc03fdcf7396fbcf4",
|
||||
"https://esm.d8d.fun/react-is@17.0.2/denonext/react-is.development.mjs": "4b640b0b829848a8150fcae01bc5c44894f71490a58e2de7b346b44e35c29af6",
|
||||
"https://esm.d8d.fun/react-is@17.0.2/denonext/react-is.mjs": "6b144222bce64ee266c22c6c06d7620f948997404e9bf285c48ee265446193d5",
|
||||
"https://esm.d8d.fun/react-is@17.0.2?target=denonext": "d8b7baf6cea6e132411aa2e4d69366fe0b7c911c7481d31f790b8f159311c7a3",
|
||||
@@ -3443,6 +3455,7 @@
|
||||
},
|
||||
"workspace": {
|
||||
"dependencies": [
|
||||
"npm:@testing-library/user-event@14.6.1",
|
||||
"npm:jsdom@26.0.0"
|
||||
]
|
||||
}
|
||||
|
||||
45
test.log
Normal file
45
test.log
Normal file
@@ -0,0 +1,45 @@
|
||||
[0m[38;5;245mrunning 1 test from ./client/admin/pages_know_info.test.tsx[0m
|
||||
知识库管理页面测试 ...
|
||||
应正确渲染页面元素 ... [0m[32mok[0m [0m[38;5;245m(1s)[0m
|
||||
初始加载表格数据 ... [0m[32mok[0m [0m[38;5;245m(940ms)[0m
|
||||
搜索表单应正常工作 ...
|
||||
[0m[38;5;245m------- output -------[0m
|
||||
searchInput 数据分析
|
||||
[36m<input[39m
|
||||
[33mclass[39m=[32m"ant-input css-dev-only-do-not-override-1a3rktk ant-input-outlined ant-input-status-success"[39m
|
||||
[33mid[39m=[32m"title"[39m
|
||||
[33mplaceholder[39m=[32m"请输入文章标题"[39m
|
||||
[33mtype[39m=[32m"text"[39m
|
||||
[33mvalue[39m=[32m"数据分析"[39m
|
||||
[36m/>[39m
|
||||
[36m<span>[39m
|
||||
[0m搜 索[0m
|
||||
[36m</span>[39m
|
||||
handleSearch { title: "数据分析", category: undefined }
|
||||
等待表格刷新并验证 2
|
||||
等待搜索结果并验证 2
|
||||
等待搜索结果并验证 2
|
||||
等待搜索结果并验证 2
|
||||
等待搜索结果并验证 2
|
||||
等待搜索结果并验证 2
|
||||
等待搜索结果并验证 2
|
||||
等待搜索结果并验证 2
|
||||
等待搜索结果并验证 2
|
||||
等待搜索结果并验证 2
|
||||
等待搜索结果并验证 2
|
||||
等待搜索结果并验证 2
|
||||
等待搜索结果并验证 2
|
||||
等待搜索结果并验证 2
|
||||
等待搜索结果并验证 2
|
||||
等待搜索结果并验证 2
|
||||
等待搜索结果并验证 3
|
||||
hasMatch true
|
||||
[0m[38;5;245m----- output end -----[0m
|
||||
搜索表单应正常工作 ... [0m[32mok[0m [0m[38;5;245m(2s)[0m
|
||||
表格应加载并显示数据 ... [0m[32mok[0m [0m[38;5;245m(28ms)[0m
|
||||
应能打开添加文章模态框 ... [0m[32mok[0m [0m[38;5;245m(241ms)[0m
|
||||
应能完整添加一篇文章 ... [0m[32mok[0m [0m[38;5;245m(153ms)[0m
|
||||
知识库管理页面测试 ... [0m[32mok[0m [0m[38;5;245m(4s)[0m
|
||||
|
||||
[0m[32mok[0m | 1 passed (6 steps) | 0 failed [0m[38;5;245m(4s)[0m
|
||||
|
||||
Reference in New Issue
Block a user