import {StaticResponse} from 'cypress/types/net-stubbing'; /** 点击select具体项 */ export function selectClick(testid: string, eq = 0) { cy.getTestId(testid).click(); cy.getTestId(testid) .find('.rc-virtual-list-holder-inner') .children() .eq(eq) .click(); } /** 进入具体菜单 */ export function intoMenu(parent: string, child: string) { cy.getTestId('menu') .children() .each(function (el) { const titleElement = el.find('.ant-menu-submenu-title'); if (titleElement.text() === parent) { titleElement.trigger('click'); el.find(`ul>li[title="${child}"]`).trigger('click'); } }); } /** 校验select */ export function validateSelect(testid: string, value: string) { cy.getTestId(testid) .find('.ant-select-selection-item') .should('have.attr', 'title', value) .and('have.text', value); } /** 校验table内容 */ export function validateTableList(tableName: string) { cy.getTestId(tableName) .find('table') .find('.ant-table-tbody') .children('.ant-table-row') .first() .find('td') .eq(1) .should('include.text', 'page-1'); cy.getTestId(tableName) .siblings('.ant-pagination') .find('li[title="2"]') .click(); cy.getTestId(tableName) .find('table') .find('.ant-table-tbody') .children('.ant-table-row') .first() .find('td') .eq(1) .should('include.text', 'page-2'); } /** 校验table search */ export function validateTableSearch( tableName: string, keys: ({id: string; type: 'select' | 'date'; value?: string} | string)[], options: { toolId: string; url: string; }, ) { const {toolId, url} = options; cy.getTestId(tableName) .siblings('.ant-pagination') .find('li[title="2"]') .click(); function clear(data?: (typeof keys)[0]) { function clearData(key: (typeof keys)[0]) { if (typeof key === 'string') { cy.getTestId(toolId).find(`[data-testid="filter_${key}"]`).clear(); } else { const {id, type} = key; if (type === 'select') { cy.getTestId(toolId) .getTestId(`filter_${id}`) .trigger('mouseover') .find('.ant-select-clear') .click(); } } } if (data) { return clearData(data); } keys.forEach(clearData); } function validate(text: string, reset?: boolean) { !reset && cy.getTestId(toolId).find('[data-testid="search_btn"]').click(); cy.getTestId(toolId) .find('[data-testid="search_btn"]') .should('have.class', 'ant-btn-loading'); cy.getTestId(tableName) .find('table') .find('.ant-table-tbody') .children('.ant-table-row') .first() .find('td') .eq(1) .should('include.text', text); cy.getTestId(tableName) .siblings('.ant-pagination') .find('li[title="1"]') .should('have.class', 'ant-pagination-item-active'); cy.getTestId(toolId) .getTestId('search_btn') .should('not.have.class', 'ant-btn-loading'); } keys.forEach(function (key, idx) { if (idx > 0) { clear(keys[idx - 1]); } if (typeof key === 'string') { cy.getTestId(toolId).find(`[data-testid="filter_${key}"]`).type(key); validate(key); } else { const {id, type, value} = key; if (type === 'select') { selectClick(`filter_${id}`, 0); validate(value); } } }); // 校验重置功能 cy.getTestId(toolId).find('[data-testid="reset_btn"]').click(); validate('page-1', true); // 校验刷新功能 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}`); cy.getTestId(tableName) .closest('.ant-card-body') .find('[data-testid="refresh_btn"]') .should('not.have.class', 'ant-btn-loading'); } /** 表格内按钮点击 */ export function tableBtnClick(tableName: string, index: number) { function getBtn() { return cy .getTestId(tableName) .find('table') .find('.ant-table-tbody') .children('.ant-table-row') .first() .find('td') .last() .children() .eq(index); } getBtn().click(); return getBtn; } /** 弹窗按钮校验 */ export function validateModalBtnGroup(modalName: string) { cy.getTestId(modalName) .getTestId('modal_btn_group') .find('.ant-btn') .should('have.class', 'ant-btn-loading'); } // 校验antd message内容 export function validateMessageContent(msg: string) { cy.get('.ant-message-notice-content').should('include.text', msg); } // 校验modal的操作结果 export function validateModalOperation(modalName: string, text: string) { cy.getTestId(modalName).find('form').submit(); validateModalBtnGroup(modalName); validateMessageContent(text); cy.getTestId(modalName).should('not.exist'); } /** 校验新增或修改事件 */ export function validatePut( modalName: string, tableName: string, options: {label: string}, ) { const {label} = options; function validateAdd(keys: (string | {id: string; type: 'select'})[]) { cy.getTestId(tableName) .closest('.ant-card-body') .find('[data-testid="add_btn"]') .click(); cy.getTestId(modalName).should('exist').and('be.visible'); cy.getTestId(modalName).find('h3').should('include.text', `新增${label}`); keys.forEach(function (key) { if (typeof key === 'string') { cy.getTestId(`field_${key}`).type(key); } else { const {type, id} = key; switch (type) { case 'select': selectClick(`field_${id}`, 0); break; } } }); validateModalOperation(modalName, '新增成功'); } function validateEdit( keys: {id: string; type: 'field' | 'select'; value: string}[], eq = 0, ) { tableBtnClick(tableName, eq); cy.getTestId(modalName).should('exist').and('be.visible'); cy.getTestId(modalName).find('h3').should('include.text', `修改${label}`); keys.forEach(function ({id, type, value}) { switch (type) { case 'field': cy.getTestId(`field_${id}`).should('have.value', value); break; case 'select': validateSelect(`field_${id}`, value); break; } }); validateModalOperation(modalName, '修改成功'); } return {validateAdd, validateEdit}; } /** 校验antd dialog信息 */ export function validateDialog( title: string, content: string, options?: {confirm?: boolean}, ) { const {confirm = true} = options ?? {}; cy.get('.ant-modal-confirm-title').should('include.text', title); cy.get('.ant-modal-confirm-content').should('include.text', content); cy.get('.ant-modal-confirm-btns') .children() .eq(confirm ? 1 : 0) .click(); } /** 校验删除 */ export function validateDelete( tableName: string, label: 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}吗?`); // 删除按钮在加载 cy.getTestId(tableName) .find('table') .find('.ant-table-tbody') .children('.ant-table-row') .first() .find('td') .last() .children() .eq(eq) .should('have.class', 'ant-btn-loading'); // 其他按钮禁用 cy.getTestId(tableName) .find('table') .find('.ant-table-tbody') .children('.ant-table-row') .first() .find('td') .last() .children() .each(function (el, idx) { if (idx !== eq) { expect(el).to.have.attr('disabled'); } }); validateMessageContent('删除成功'); } /** 校验导出 */ export function validateExport(tableName: string) { const card = cy.getTestId(tableName).closest('.ant-card-body'); card.getTestId('export_btn').click(); card.getTestId('export_btn').should('have.class', 'ant-btn-loading'); card.getTestId('export_btn').should('not.have.class', 'ant-btn-loading'); } /** 关闭modal */ export function closeModal() { cy.get('.ReactModal__Overlay').trigger('click', 'topRight'); } /** 选择时间组件 */ export function clickDatePicker(id: string) { cy.getTestId(id).click(); cy.get('.ant-picker-panels') .children() .eq(0) .find('.ant-picker-content') .find('tbody') .find('td') .eq(0) .click(); cy.get('.ant-picker-panels') .children() .eq(1) .find('.ant-picker-content') .find('tbody') .find('td') .eq(0) .click(); } /** 选择所有的筛选框 */ export function selectAllFilters(toolId: string, count: number) { indexedDB.deleteDatabase('filterGroup'); cy.getTestId(toolId).getTestId('filter_btn').click(); cy.get('.ant-transfer') .find('.ant-transfer-list') .first() .find('.ant-transfer-list-header') .find('input[type="checkbox"]') .check(); cy.get('.ant-transfer') .find('.ant-transfer-operation') .find('button') .first() .click(); cy.getTestId('filter_select_modal').find('form').submit(); cy.getTestId(toolId) .children('.ant-space') .first() .children() .should('have.length', count + 1); } /** 生成返回内容 */ export function generateResult>( data: T, length: number, options: { limit: string; key?: string; isList?: boolean; title?: keyof T; value?: string; }, ) { const {key = 'id', isList = false, title, value, limit} = options; const result = Array.from({length: Number(limit)}, function (_, idx) { const temp = {...data, [key]: idx + 1}; return title ? {...temp, [title]: value ?? ''} : temp; }); return {msg: '200', data: isList ? {total: length, list: result} : result}; } /** 生成请求结果 */ export function generateNetworkResult< T extends Record, >(options: { search: URLSearchParams; basicData: T; reply: (params: StaticResponse) => void; title: keyof T; skipCondition?: (name: string) => boolean; }) { 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' || skipCondition(name) ) continue; if (searchValue) { return reply({ body: generateResult(basicData, Number(limit) * 3, { limit, isList: true, title, value: searchValue, }), }); } } if (search.has('id') && search.get('id').length > 0) { return reply({ body: generateResult(basicData, 1, {limit: '1', isList: true}), }); } reply({ body: generateResult(basicData, Number(limit) * 3, { limit, isList: true, title, value: `page-${page}`, }), }); }