xyh 2 лет назад
Родитель
Сommit
8053aac209

+ 110 - 0
cypress/e2e/menu.cy.ts

@@ -0,0 +1,110 @@
+import {
+  beforeSetup,
+  generateNetworkResult,
+  intercept,
+  intoMenu,
+  successIntercept,
+  tableBtnClick,
+  validateDelete,
+  validatePut,
+  validateTableList,
+  validateTableSearch,
+} from './utils';
+
+const basicData = {
+  id: '7',
+  name: '系统设置',
+  url: '.',
+  pId: '0',
+  idCode: null,
+  type: 'PC',
+  page: 0,
+  limit: 0,
+  orderBy: '0',
+  menu: null,
+  img: 'xitongguanli',
+  modifyUser: 'admin',
+  modifyTime: '2023-03-29 13:42:47',
+  pid: '0',
+};
+
+const TABLE_NAME = 'menu_table',
+  TABLE_NAME2 = 'child_menu_table';
+
+describe('菜单管理', function () {
+  beforeEach(function () {
+    beforeSetup(true);
+    intoMenu('系统设置', '菜单管理');
+  });
+
+  beforeEach(function () {
+    intercept('/menu/getPage', function ({search, reply}) {
+      generateNetworkResult({
+        search,
+        reply,
+        basicData,
+        title: 'name',
+        skipCondition(name) {
+          return name === 'pId' || name === 'type';
+        },
+      });
+    });
+
+    successIntercept(['/menu/addMenu', '/menu/updateMenu', '/menu/delMenu']);
+  });
+
+  it('table', function () {
+    validateTableList(TABLE_NAME);
+
+    validateTableSearch(TABLE_NAME, ['menuName', 'modifyUser'], {
+      toolId: 'menu_filter',
+      url: '/menu/getPage',
+    });
+  });
+
+  it('operation', function () {
+    const {validateAdd, validateEdit} = validatePut('menu_modal', TABLE_NAME, {
+      label: '菜单',
+    });
+
+    validateAdd(['menuName', 'menuIcon', 'menuOrderBy']);
+    validateEdit([
+      {id: 'menuName', type: 'field', value: basicData.name},
+      {id: 'menuIcon', type: 'field', value: basicData.img},
+      {id: 'menuOrderBy', type: 'field', value: basicData.orderBy},
+    ]);
+
+    validateDelete(TABLE_NAME, '菜单', {eq: 2, title: 'page-1'});
+  });
+
+  it('子菜单表格', function () {
+    tableBtnClick(TABLE_NAME, 1);
+    validateTableList(TABLE_NAME2);
+
+    validateTableSearch(TABLE_NAME2, ['childMenuName', 'modifyUser'], {
+      toolId: 'child_menu_filter',
+      url: '/menu/getPage',
+    });
+  });
+
+  it.only('子菜单操作', function () {
+    tableBtnClick(TABLE_NAME, 1);
+
+    const {validateAdd, validateEdit} = validatePut(
+      'child_menu_modal',
+      TABLE_NAME2,
+      {
+        label: '菜单',
+      },
+    );
+
+    validateAdd(['menuName', 'menuUrl', 'menuOrderBy']);
+    validateEdit([
+      {id: 'menuName', type: 'field', value: basicData.name},
+      {id: 'menuUrl', type: 'field', value: basicData.url},
+      {id: 'menuOrderBy', type: 'field', value: basicData.orderBy},
+    ]);
+
+    validateDelete(TABLE_NAME2, '菜单', {title: 'page-1'});
+  });
+});

+ 44 - 22
cypress/e2e/utils/utils.ts

@@ -77,12 +77,13 @@ export function validateTableSearch(
   function clear(data?: (typeof keys)[0]) {
     function clearData(key: (typeof keys)[0]) {
       if (typeof key === 'string') {
-        cy.getTestId(`filter_${key}`).clear();
+        cy.getTestId(toolId).find(`[data-testid="filter_${key}"]`).clear();
       } else {
         const {id, type} = key;
 
         if (type === 'select') {
-          cy.getTestId(`filter_${id}`)
+          cy.getTestId(toolId)
+            .getTestId(`filter_${id}`)
             .trigger('mouseover')
             .find('.ant-select-clear')
             .click();
@@ -98,10 +99,10 @@ export function validateTableSearch(
   }
 
   function validate(text: string, reset?: boolean) {
-    !reset && cy.getTestId(toolId).getTestId('search_btn').click();
+    !reset && cy.getTestId(toolId).find('[data-testid="search_btn"]').click();
 
     cy.getTestId(toolId)
-      .getTestId('search_btn')
+      .find('[data-testid="search_btn"]')
       .should('have.class', 'ant-btn-loading');
 
     cy.getTestId(tableName)
@@ -129,7 +130,7 @@ export function validateTableSearch(
     }
 
     if (typeof key === 'string') {
-      cy.getTestId(`filter_${key}`).type(key);
+      cy.getTestId(toolId).find(`[data-testid="filter_${key}"]`).type(key);
       validate(key);
     } else {
       const {id, type, value} = key;
@@ -142,16 +143,22 @@ export function validateTableSearch(
   });
 
   // 校验重置功能
-  cy.getTestId(toolId).getTestId('reset_btn').click();
+  cy.getTestId(toolId).find('[data-testid="reset_btn"]').click();
   validate('page-1', true);
 
   // 校验刷新功能
-  const parentCard = cy.getTestId(tableName).closest('.ant-card-body');
-  parentCard.getTestId('refresh_btn').click();
-  parentCard.getTestId('refresh_btn').should('have.class', 'ant-btn-loading');
+  cy.getTestId(tableName)
+    .closest('.ant-card-body')
+    .find('[data-testid="refresh_btn"]')
+    .click();
+  cy.getTestId(tableName)
+    .closest('.ant-card-body')
+    .find('[data-testid="refresh_btn"]')
+    .should('have.class', 'ant-btn-loading');
   cy.wait(`@${url}`);
-  parentCard
-    .getTestId('refresh_btn')
+  cy.getTestId(tableName)
+    .closest('.ant-card-body')
+    .find('[data-testid="refresh_btn"]')
     .should('not.have.class', 'ant-btn-loading');
 }
 
@@ -208,7 +215,7 @@ export function validatePut(
   function validateAdd(keys: (string | {id: string; type: 'select'})[]) {
     cy.getTestId(tableName)
       .closest('.ant-card-body')
-      .getTestId('add_btn')
+      .find('[data-testid="add_btn"]')
       .click();
 
     cy.getTestId(modalName).should('exist').and('be.visible');
@@ -277,14 +284,14 @@ export function validateDialog(
 export function validateDelete(
   tableName: string,
   label: string,
-  options: {eq?: number; title?: string},
+  options: {eq?: number; title: string},
 ) {
   const {eq = 1, title} = options;
   tableBtnClick(tableName, eq);
 
   cy.get('.ant-modal-content').should('be.visible');
 
-  validateDialog(title ?? `删除${label}`, `你确定要删除当前${label}吗?`);
+  validateDialog(title, `你确定要删除当前${label}吗?`);
 
   // 删除按钮在加载
   cy.getTestId(tableName)
@@ -379,14 +386,14 @@ export function selectAllFilters(toolId: string, count: number) {
 }
 
 /** 生成返回内容 */
-export function generateResult(
-  data: Record<string, any>,
+export function generateResult<T extends Record<string, any>>(
+  data: T,
   length: number,
   options: {
     limit: string;
     key?: string;
     isList?: boolean;
-    title?: string;
+    title?: keyof T;
     value?: string;
   },
 ) {
@@ -402,19 +409,34 @@ export function generateResult(
 }
 
 /** 生成请求结果 */
-export function generateNetworkResult(options: {
+export function generateNetworkResult<
+  T extends Record<string, unknown>,
+>(options: {
   search: URLSearchParams;
-  basicData: Record<string, unknown>;
+  basicData: T;
   reply: (params: StaticResponse) => void;
-  title: string;
+  title: keyof T;
+  skipCondition?: (name: string) => boolean;
 }) {
-  const {search, basicData, reply, title} = options;
+  const {
+    search,
+    basicData,
+    reply,
+    title,
+    skipCondition = () => false,
+  } = options;
 
   const page = search.get('page'),
     limit = search.get('limit');
 
   for (const [name, searchValue] of search.entries()) {
-    if (name === 'page' || name === 'limit' || name === 'id') continue;
+    if (
+      name === 'page' ||
+      name === 'limit' ||
+      name === 'id' ||
+      skipCondition(name)
+    )
+      continue;
 
     if (searchValue) {
       return reply({

+ 1 - 1
packages/app/src/pages/menu-id/filter/index.tsx

@@ -21,7 +21,7 @@ const Filter: FC = function () {
 
   return (
     <Card>
-      <FilterFieldWrapper onSearch={onSearch}>
+      <FilterFieldWrapper onSearch={onSearch} testId='child_menu_filter'>
         <FilterField
           name='childMenuName'
           label='菜单名称'

+ 1 - 1
packages/app/src/pages/menu/filter/index.tsx

@@ -20,7 +20,7 @@ const Filter: FC = function () {
 
   return (
     <Card>
-      <FilterFieldWrapper onSearch={onSearch}>
+      <FilterFieldWrapper onSearch={onSearch} testId='menu_filter'>
         <FilterField
           name='menuName'
           label='菜单名称'