utils.ts 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. import {StaticResponse} from 'cypress/types/net-stubbing';
  2. /** 点击select具体项 */
  3. export function selectClick(testid: string, eq = 0) {
  4. cy.getTestId(testid).click();
  5. cy.getTestId(testid)
  6. .find('.rc-virtual-list-holder-inner')
  7. .children()
  8. .eq(eq)
  9. .click();
  10. }
  11. /** 进入具体菜单 */
  12. export function intoMenu(parent: string, child: string) {
  13. cy.getTestId('menu')
  14. .children()
  15. .each(function (el) {
  16. const titleElement = el.find('.ant-menu-submenu-title');
  17. if (titleElement.text() === parent) {
  18. titleElement.trigger('click');
  19. el.find(`ul>li[title="${child}"]`).trigger('click');
  20. }
  21. });
  22. }
  23. /** 校验select */
  24. export function validateSelect(testid: string, value: string) {
  25. cy.getTestId(testid)
  26. .find('.ant-select-selection-item')
  27. .should('have.attr', 'title', value)
  28. .and('have.text', value);
  29. }
  30. /** 校验table内容 */
  31. export function validateTableList(tableName: string) {
  32. cy.getTestId(tableName)
  33. .find('table')
  34. .find('.ant-table-tbody')
  35. .children('.ant-table-row')
  36. .first()
  37. .find('td')
  38. .eq(1)
  39. .should('include.text', 'page-1');
  40. cy.getTestId(tableName)
  41. .siblings('.ant-pagination')
  42. .find('li[title="2"]')
  43. .click();
  44. cy.getTestId(tableName)
  45. .find('table')
  46. .find('.ant-table-tbody')
  47. .children('.ant-table-row')
  48. .first()
  49. .find('td')
  50. .eq(1)
  51. .should('include.text', 'page-2');
  52. }
  53. /** 校验table search */
  54. export function validateTableSearch(
  55. tableName: string,
  56. keys: ({id: string; type: 'select' | 'date'; value?: string} | string)[],
  57. options: {
  58. toolId: string;
  59. url: string;
  60. },
  61. ) {
  62. const {toolId, url} = options;
  63. cy.getTestId(tableName)
  64. .siblings('.ant-pagination')
  65. .find('li[title="2"]')
  66. .click();
  67. function clear(data?: (typeof keys)[0]) {
  68. function clearData(key: (typeof keys)[0]) {
  69. if (typeof key === 'string') {
  70. cy.getTestId(`filter_${key}`).clear();
  71. } else {
  72. const {id, type} = key;
  73. if (type === 'select') {
  74. cy.getTestId(`filter_${id}`)
  75. .trigger('mouseover')
  76. .find('.ant-select-clear')
  77. .click();
  78. }
  79. }
  80. }
  81. if (data) {
  82. return clearData(data);
  83. }
  84. keys.forEach(clearData);
  85. }
  86. function validate(text: string, reset?: boolean) {
  87. !reset && cy.getTestId(toolId).getTestId('search_btn').click();
  88. cy.getTestId(toolId)
  89. .getTestId('search_btn')
  90. .should('have.class', 'ant-btn-loading');
  91. cy.getTestId(tableName)
  92. .find('table')
  93. .find('.ant-table-tbody')
  94. .children('.ant-table-row')
  95. .first()
  96. .find('td')
  97. .eq(1)
  98. .should('include.text', text);
  99. cy.getTestId(tableName)
  100. .siblings('.ant-pagination')
  101. .find('li[title="1"]')
  102. .should('have.class', 'ant-pagination-item-active');
  103. cy.getTestId(toolId)
  104. .getTestId('search_btn')
  105. .should('not.have.class', 'ant-btn-loading');
  106. }
  107. keys.forEach(function (key, idx) {
  108. if (idx > 0) {
  109. clear(keys[idx - 1]);
  110. }
  111. if (typeof key === 'string') {
  112. cy.getTestId(`filter_${key}`).type(key);
  113. validate(key);
  114. } else {
  115. const {id, type, value} = key;
  116. if (type === 'select') {
  117. selectClick(`filter_${id}`, 0);
  118. validate(value);
  119. }
  120. }
  121. });
  122. // 校验重置功能
  123. cy.getTestId(toolId).getTestId('reset_btn').click();
  124. validate('page-1', true);
  125. // 校验刷新功能
  126. const parentCard = cy.getTestId(tableName).closest('.ant-card-body');
  127. parentCard.getTestId('refresh_btn').click();
  128. parentCard.getTestId('refresh_btn').should('have.class', 'ant-btn-loading');
  129. cy.wait(`@${url}`);
  130. parentCard
  131. .getTestId('refresh_btn')
  132. .should('not.have.class', 'ant-btn-loading');
  133. }
  134. /** 表格内按钮点击 */
  135. export function tableBtnClick(tableName: string, index: number) {
  136. function getBtn() {
  137. return cy
  138. .getTestId(tableName)
  139. .find('table')
  140. .find('.ant-table-tbody')
  141. .children('.ant-table-row')
  142. .first()
  143. .find('td')
  144. .last()
  145. .children()
  146. .eq(index);
  147. }
  148. getBtn().click();
  149. return getBtn;
  150. }
  151. /** 弹窗按钮校验 */
  152. export function validateModalBtnGroup(modalName: string) {
  153. cy.getTestId(modalName)
  154. .getTestId('modal_btn_group')
  155. .find('.ant-btn')
  156. .should('have.class', 'ant-btn-loading');
  157. }
  158. // 校验antd message内容
  159. export function validateMessageContent(msg: string) {
  160. cy.get('.ant-message-notice-content').should('include.text', msg);
  161. }
  162. // 校验modal的操作结果
  163. export function validateModalOperation(modalName: string, text: string) {
  164. cy.getTestId(modalName).find('form').submit();
  165. validateModalBtnGroup(modalName);
  166. validateMessageContent(text);
  167. cy.getTestId(modalName).should('not.exist');
  168. }
  169. /** 校验新增或修改事件 */
  170. export function validatePut(
  171. modalName: string,
  172. tableName: string,
  173. options: {label: string},
  174. ) {
  175. const {label} = options;
  176. function validateAdd(keys: (string | {id: string; type: 'select'})[]) {
  177. cy.getTestId(tableName)
  178. .closest('.ant-card-body')
  179. .getTestId('add_btn')
  180. .click();
  181. cy.getTestId(modalName).should('exist').and('be.visible');
  182. cy.getTestId(modalName).find('h3').should('include.text', `新增${label}`);
  183. keys.forEach(function (key) {
  184. if (typeof key === 'string') {
  185. cy.getTestId(`field_${key}`).type(key);
  186. } else {
  187. const {type, id} = key;
  188. switch (type) {
  189. case 'select':
  190. selectClick(`field_${id}`, 0);
  191. break;
  192. }
  193. }
  194. });
  195. validateModalOperation(modalName, '新增成功');
  196. }
  197. function validateEdit(
  198. keys: {id: string; type: 'field' | 'select'; value: string}[],
  199. eq = 0,
  200. ) {
  201. tableBtnClick(tableName, eq);
  202. cy.getTestId(modalName).should('exist').and('be.visible');
  203. cy.getTestId(modalName).find('h3').should('include.text', `修改${label}`);
  204. keys.forEach(function ({id, type, value}) {
  205. switch (type) {
  206. case 'field':
  207. cy.getTestId(`field_${id}`).should('have.value', value);
  208. break;
  209. case 'select':
  210. validateSelect(`field_${id}`, value);
  211. break;
  212. }
  213. });
  214. validateModalOperation(modalName, '修改成功');
  215. }
  216. return {validateAdd, validateEdit};
  217. }
  218. /** 校验antd dialog信息 */
  219. export function validateDialog(
  220. title: string,
  221. content: string,
  222. options?: {confirm?: boolean},
  223. ) {
  224. const {confirm = true} = options ?? {};
  225. cy.get('.ant-modal-confirm-title').should('include.text', title);
  226. cy.get('.ant-modal-confirm-content').should('include.text', content);
  227. cy.get('.ant-modal-confirm-btns')
  228. .children()
  229. .eq(confirm ? 1 : 0)
  230. .click();
  231. }
  232. /** 校验删除 */
  233. export function validateDelete(
  234. tableName: string,
  235. label: string,
  236. options: {eq?: number; title?: string},
  237. ) {
  238. const {eq = 1, title} = options;
  239. tableBtnClick(tableName, eq);
  240. cy.get('.ant-modal-content').should('be.visible');
  241. validateDialog(title ?? `删除${label}`, `你确定要删除当前${label}吗?`);
  242. // 删除按钮在加载
  243. cy.getTestId(tableName)
  244. .find('table')
  245. .find('.ant-table-tbody')
  246. .children('.ant-table-row')
  247. .first()
  248. .find('td')
  249. .last()
  250. .children()
  251. .eq(eq)
  252. .should('have.class', 'ant-btn-loading');
  253. // 其他按钮禁用
  254. cy.getTestId(tableName)
  255. .find('table')
  256. .find('.ant-table-tbody')
  257. .children('.ant-table-row')
  258. .first()
  259. .find('td')
  260. .last()
  261. .children()
  262. .each(function (el, idx) {
  263. if (idx !== eq) {
  264. expect(el).to.have.attr('disabled');
  265. }
  266. });
  267. validateMessageContent('删除成功');
  268. }
  269. /** 校验导出 */
  270. export function validateExport(tableName: string) {
  271. const card = cy.getTestId(tableName).closest('.ant-card-body');
  272. card.getTestId('export_btn').click();
  273. card.getTestId('export_btn').should('have.class', 'ant-btn-loading');
  274. card.getTestId('export_btn').should('not.have.class', 'ant-btn-loading');
  275. }
  276. /** 关闭modal */
  277. export function closeModal() {
  278. cy.get('.ReactModal__Overlay').trigger('click', 'topRight');
  279. }
  280. /** 选择时间组件 */
  281. export function clickDatePicker(id: string) {
  282. cy.getTestId(id).click();
  283. cy.get('.ant-picker-panels')
  284. .children()
  285. .eq(0)
  286. .find('.ant-picker-content')
  287. .find('tbody')
  288. .find('td')
  289. .eq(0)
  290. .click();
  291. cy.get('.ant-picker-panels')
  292. .children()
  293. .eq(1)
  294. .find('.ant-picker-content')
  295. .find('tbody')
  296. .find('td')
  297. .eq(0)
  298. .click();
  299. }
  300. /** 选择所有的筛选框 */
  301. export function selectAllFilters(toolId: string, count: number) {
  302. indexedDB.deleteDatabase('filterGroup');
  303. cy.getTestId(toolId).getTestId('filter_btn').click();
  304. cy.get('.ant-transfer')
  305. .find('.ant-transfer-list')
  306. .first()
  307. .find('.ant-transfer-list-header')
  308. .find('input[type="checkbox"]')
  309. .check();
  310. cy.get('.ant-transfer')
  311. .find('.ant-transfer-operation')
  312. .find('button')
  313. .first()
  314. .click();
  315. cy.getTestId('filter_select_modal').find('form').submit();
  316. cy.getTestId(toolId)
  317. .children('.ant-space')
  318. .first()
  319. .children()
  320. .should('have.length', count + 1);
  321. }
  322. /** 生成返回内容 */
  323. export function generateResult(
  324. data: Record<string, any>,
  325. length: number,
  326. options: {
  327. limit: string;
  328. key?: string;
  329. isList?: boolean;
  330. title?: string;
  331. value?: string;
  332. },
  333. ) {
  334. const {key = 'id', isList = false, title, value, limit} = options;
  335. const result = Array.from({length: Number(limit)}, function (_, idx) {
  336. const temp = {...data, [key]: idx + 1};
  337. return title ? {...temp, [title]: value ?? ''} : temp;
  338. });
  339. return {msg: '200', data: isList ? {total: length, list: result} : result};
  340. }
  341. /** 生成请求结果 */
  342. export function generateNetworkResult(options: {
  343. search: URLSearchParams;
  344. basicData: Record<string, unknown>;
  345. reply: (params: StaticResponse) => void;
  346. title: string;
  347. }) {
  348. const {search, basicData, reply, title} = options;
  349. const page = search.get('page'),
  350. limit = search.get('limit');
  351. for (const [name, searchValue] of search.entries()) {
  352. if (name === 'page' || name === 'limit' || name === 'id') continue;
  353. if (searchValue) {
  354. return reply({
  355. body: generateResult(basicData, Number(limit) * 3, {
  356. limit,
  357. isList: true,
  358. title,
  359. value: searchValue,
  360. }),
  361. });
  362. }
  363. }
  364. if (search.has('id') && search.get('id').length > 0) {
  365. return reply({
  366. body: generateResult(basicData, 1, {limit: '1', isList: true}),
  367. });
  368. }
  369. reply({
  370. body: generateResult(basicData, Number(limit) * 3, {
  371. limit,
  372. isList: true,
  373. title,
  374. value: `page-${page}`,
  375. }),
  376. });
  377. }