WorklistPage.ts 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. class WorklistPage {
  2. getTable() {
  3. return cy.get('table');
  4. }
  5. findTableAndDoubleClickFirstRow() {
  6. cy.get('table').within(() => {
  7. cy.get('tbody tr[data-testid="row-0"]')
  8. .scrollIntoView()
  9. .should('be.visible')
  10. .dblclick({ force: true });
  11. });
  12. }
  13. /**
  14. * 获取表头(排除第一列选择框)
  15. */
  16. getTableHeaders() {
  17. return cy.get('table thead th').not(':first');
  18. }
  19. /**
  20. * 获取所有表头
  21. */
  22. getAllTableHeaders() {
  23. return cy.get('table thead th');
  24. }
  25. /**
  26. * 获取特定列
  27. * @param columnName 列名文本
  28. */
  29. getColumn(columnName: string) {
  30. return cy.get('table thead th').contains(columnName);
  31. }
  32. /**
  33. * 验证列存在
  34. * @param columnName 列名文本
  35. */
  36. columnExists(columnName: string) {
  37. return this.getTableHeaders().contains(columnName).should('exist');
  38. }
  39. /**
  40. * 验证列不存在
  41. * @param columnName 列名文本
  42. */
  43. columnNotExists(columnName: string) {
  44. return this.getTableHeaders().contains(columnName).should('not.exist');
  45. }
  46. /**
  47. * 获取列宽
  48. * @param columnName 列名文本
  49. */
  50. getColumnWidth(columnName: string) {
  51. return cy
  52. .get('table thead th')
  53. .contains(columnName)
  54. .invoke('width');
  55. }
  56. /**
  57. * 验证列的顺序
  58. * @param expectedOrder 期望的列名顺序数组
  59. */
  60. verifyColumnOrder(expectedOrder: string[]) {
  61. this.getTableHeaders().then(($headers) => {
  62. expectedOrder.forEach((columnName, index) => {
  63. cy.wrap($headers.eq(index)).should('contain', columnName);
  64. });
  65. });
  66. }
  67. /**
  68. * 获取表头数量
  69. */
  70. getHeaderCount() {
  71. return this.getTableHeaders().its('length');
  72. }
  73. /**
  74. * 点击指定索引的行
  75. * @param index 行索引(从0开始)
  76. */
  77. clickRowByIndex(index: number) {
  78. cy.get('table').within(() => {
  79. cy.get(`tbody tr[data-testid="row-${index}"]`)
  80. .scrollIntoView()
  81. .should('be.visible')
  82. .click({ force: true });
  83. });
  84. }
  85. /**
  86. * 验证指定行被选中(黄色高亮)
  87. * @param index 行索引(从0开始)
  88. */
  89. verifyRowSelected(index: number) {
  90. cy.get('table').within(() => {
  91. cy.get(`tbody tr[data-testid="row-${index}"]`)
  92. .should('be.visible')
  93. .should('have.class', 'bg-yellow-500');
  94. });
  95. }
  96. /**
  97. * 点击删除按钮
  98. */
  99. clickDeleteButton() {
  100. cy.get('[data-testid="delete-button"]').click();
  101. }
  102. /**
  103. * 获取删除确认对话框
  104. */
  105. getDeleteConfirmModal() {
  106. return cy.get('.ant-modal-confirm').should('be.visible');
  107. }
  108. /**
  109. * 在对话框中确认删除
  110. */
  111. confirmDeleteInModal() {
  112. cy.get('[data-testid="modal-confirm-delete"]').click();
  113. }
  114. /**
  115. * 在对话框中取消删除
  116. */
  117. cancelDeleteInModal() {
  118. cy.get('[data-testid="modal-cancel-delete"]').click();
  119. }
  120. /**
  121. * 验证删除成功提示消息
  122. */
  123. verifyDeleteSuccessMessage() {
  124. cy.contains('删除成功').should('be.visible');
  125. }
  126. /**
  127. * 验证删除警告消息
  128. * @param expectedMessage 期望的警告消息文本
  129. */
  130. verifyDeleteWarningMessage(expectedMessage: string) {
  131. cy.contains(expectedMessage).should('be.visible');
  132. }
  133. /**
  134. * 验证删除错误消息
  135. */
  136. verifyDeleteErrorMessage() {
  137. cy.contains('删除失败').should('be.visible');
  138. }
  139. /**
  140. * 验证表格行数
  141. * @param expectedCount 期望的行数
  142. */
  143. verifyRowCount(expectedCount: number) {
  144. cy.get('table tbody tr').should('have.length.at.least', expectedCount);
  145. }
  146. /**
  147. * 验证对话框不存在
  148. */
  149. verifyModalNotExist() {
  150. cy.get('.ant-modal-confirm').should('not.exist');
  151. }
  152. // ============ 日期范围验证方法 ============
  153. /**
  154. * 验证表格为空(无数据)
  155. */
  156. verifyTableEmpty() {
  157. cy.get('table tbody').should('not.exist');
  158. // 或者验证空状态提示
  159. cy.contains('暂无数据').should('be.visible');
  160. }
  161. /**
  162. * 验证表格中显示的 study 日期在指定范围内
  163. * @param startDate 开始日期
  164. * @param endDate 结束日期
  165. */
  166. verifyStudyDatesWithinRange(startDate: Date, endDate: Date) {
  167. cy.get('table tbody tr').each(($row) => {
  168. // 获取表格中的日期列(假设日期在特定列)
  169. cy.wrap($row)
  170. .find('td')
  171. .then(($cells) => {
  172. // 查找包含日期的单元格(通常是 StudyStartDatetime 列)
  173. const dateText = $cells
  174. .toArray()
  175. .map((cell) => cell.textContent)
  176. .find((text) => text && /\d{4}-\d{2}-\d{2}/.test(text || ''));
  177. if (dateText) {
  178. const studyDate = new Date(dateText);
  179. expect(studyDate.getTime()).to.be.gte(startDate.getTime());
  180. expect(studyDate.getTime()).to.be.lte(endDate.getTime());
  181. }
  182. });
  183. });
  184. }
  185. /**
  186. * 获取表格中第一行的检查日期
  187. */
  188. getFirstRowStudyDate() {
  189. return cy
  190. .get('table tbody tr')
  191. .first()
  192. .find('td')
  193. .then(($cells) => {
  194. // 查找包含日期的单元格
  195. const dateText = $cells
  196. .toArray()
  197. .map((cell) => cell.textContent)
  198. .find((text) => text && /\d{4}-\d{2}-\d{2}/.test(text || ''));
  199. return dateText ? new Date(dateText) : null;
  200. });
  201. }
  202. /**
  203. * 验证表格中所有行的日期都是今天
  204. */
  205. verifyAllStudyDatesAreToday() {
  206. const today = new Date();
  207. today.setHours(0, 0, 0, 0);
  208. const tomorrow = new Date(today);
  209. tomorrow.setDate(tomorrow.getDate() + 1);
  210. this.verifyStudyDatesWithinRange(today, tomorrow);
  211. }
  212. /**
  213. * 验证表格中所有行的日期在最近7天内
  214. */
  215. verifyAllStudyDatesWithinLast7Days() {
  216. const today = new Date();
  217. today.setHours(23, 59, 59, 999);
  218. const sevenDaysAgo = new Date(today);
  219. sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);
  220. sevenDaysAgo.setHours(0, 0, 0, 0);
  221. this.verifyStudyDatesWithinRange(sevenDaysAgo, today);
  222. }
  223. /**
  224. * 验证表格至少有指定数量的行
  225. * @param minCount 最小行数
  226. */
  227. verifyTableHasMinRows(minCount: number) {
  228. cy.get('table tbody tr').should('have.length.at.least', minCount);
  229. }
  230. /**
  231. * 验证表格显示指定数量的行
  232. * @param count 期望的行数
  233. */
  234. verifyTableHasExactRows(count: number) {
  235. if (count === 0) {
  236. this.verifyTableEmpty();
  237. } else {
  238. cy.get('table tbody tr').should('have.length', count);
  239. }
  240. }
  241. /**
  242. * 获取表格中所有 study 的 StudyID
  243. */
  244. getAllStudyIds() {
  245. return cy.get('table tbody tr').then(($rows) => {
  246. const studyIds: string[] = [];
  247. $rows.each((index, row) => {
  248. const studyId = Cypress.$(row).attr('data-testid')?.replace('row-', '');
  249. if (studyId) {
  250. studyIds.push(studyId);
  251. }
  252. });
  253. return studyIds;
  254. });
  255. }
  256. /**
  257. * 验证指定的 StudyID 在表格中
  258. * @param studyId StudyID
  259. */
  260. verifyStudyIdExists(studyId: string) {
  261. cy.get('table tbody').contains(studyId).should('be.visible');
  262. }
  263. /**
  264. * 验证指定的 StudyID 不在表格中
  265. * @param studyId StudyID
  266. */
  267. verifyStudyIdNotExists(studyId: string) {
  268. cy.get('table tbody').contains(studyId).should('not.exist');
  269. }
  270. }
  271. export default WorklistPage;