import LoginPage from '../../support/pageObjects/LoginPage'; import MainPage from '../../support/pageObjects/MainPage'; import ExamPage from '../../support/pageObjects/ExamPage'; import WorklistPage from '../../support/pageObjects/WorklistPage'; import { mockResetDeviceSuccess, mockResetDeviceFail, mockResetDeviceNetworkError, mockResetDeviceDelay, } from '../../support/mock/handlers/device'; import { mockI18nSuccess, mockGetLanguageListSuccess, mockAllRequiredAPIs, } from '../../support/mock/handlers/i18n'; import { mockLoginSuccess } from '../../support/mock/handlers/user'; import { mockGetStudyDetails } from '../../support/mock/handlers/study'; import { mockFetchTwoWorks } from '../../support/mock/handlers/worklist'; import { mockGetQuotaSuccess } from '../../support/mock/handlers/quota'; import { mockGetAprDetailsComplete, mockGetViewDetailComplete } from '../../support/mock/handlers/protocol'; describe('重置高压发生器功能测试', () => { const loginPage = new LoginPage(); const mainPage = new MainPage(); const examPage = new ExamPage(); const worklistPage = new WorklistPage(); beforeEach(() => { // Mock多语言资源和必要的API mockI18nSuccess('zh_CN'); mockGetLanguageListSuccess(); mockAllRequiredAPIs('zh_CN'); // Mock登录成功响应 mockLoginSuccess(); // Mock 进入worklist后得到两个数据 mockFetchTwoWorks(); // Mock得到配额成功 mockGetQuotaSuccess(); // Mock获取检查详情 mockGetStudyDetails('20250912135259444'); // Mock获取APR详情 mockGetAprDetailsComplete(); // Mock获取View详情 mockGetViewDetailComplete(); // 登录系统 loginPage.visit(); loginPage.login('admin', '123456'); // 等待页面渲染和路由跳转 cy.wait(1500); // 验证登录成功:登录页面元素不再存在 loginPage.getUsernameInput().should('not.exist'); loginPage.getPasswordInput().should('not.exist'); loginPage.getSubmitButton().should('not.exist'); // 导航到工作列表 // mainPage.clickPatientManagementButton(); //默认展开,不需要点击使之展开 mainPage.clickWorklistButton(); // 双击第一行进入检查页面 worklistPage.findTableAndDoubleClickFirstRow(); cy.wait(3000); // 验证已进入检查页面 cy.get('[data-testid="exam-page"]').should('exist'); }); describe('TC-RESET-01: 成功重置设备', () => { it('应该成功重置高压发生器并更新UI状态', () => { // 1. Mock设备重置API成功响应 mockResetDeviceSuccess(); // 2. 验证按钮初始状态为可用 examPage.verifyResetButtonEnabled(); // 3. 验证初始Redux状态 examPage.verifyDeviceStatus('idle'); // 4. 点击RESET按钮 examPage.clickResetGenerator(); // 5. 验证按钮变为禁用状态(loading) examPage.verifyResetButtonDisabled(); // 6. 等待API调用完成 cy.wait('@resetDevice').then((interception) => { // 验证请求体 expect(interception.request.body).to.deep.include({ deviceUri: 'DIOS/DEVICE/Generator', reqName: 'RESET', }); // 验证响应 expect(interception.response?.statusCode).to.eq(200); expect(interception.response?.body.code).to.eq('0x000000'); }); // 7. 验证按钮恢复为可用状态 examPage.verifyResetButtonEnabled(); // 8. 验证Redux状态更新为'succeeded' examPage.verifyDeviceStatus('succeeded'); // 9. 验证无错误信息 examPage.verifyDeviceError(null); }); }); describe('TC-RESET-02: API失败处理', () => { it('应该正确处理设备重置失败', () => { // 1. Mock设备重置API失败响应 mockResetDeviceFail('0x010001', '设备通信失败'); // 2. 点击RESET按钮 examPage.clickResetGenerator(); // 3. 等待API调用完成 cy.wait('@resetDeviceFail').then((interception) => { // 验证响应包含错误信息 expect(interception.response?.body.code).to.eq('0x010001'); expect(interception.response?.body.description).to.eq('设备通信失败'); }); // 4. 验证Redux状态更新为'failed' examPage.verifyDeviceStatus('failed'); // 5. 验证错误信息存储到state.error cy.window() .its('store') .invoke('getState') .its('device') .its('error') .should('exist'); // 6. 验证按钮恢复可用 examPage.verifyResetButtonEnabled(); // 7. 验证控制台输出错误日志 cy.window().then((win) => { cy.spy(win.console, 'error'); }); }); }); describe('TC-RESET-03: 按钮禁用状态管理', () => { it('应该在loading期间正确管理按钮状态', () => { // 1. Mock设备重置API延迟响应(2秒) mockResetDeviceDelay(2000); // 2. 验证初始Redux状态 examPage.verifyDeviceStatus('idle'); // 3. 点击RESET按钮 examPage.clickResetGenerator(); // 4. 验证按钮立即禁用 examPage.verifyResetButtonDisabled(); // 5. 验证Redux状态变为loading examPage.verifyDeviceStatus('loading'); // 6. 等待1秒,验证按钮仍然禁用 cy.wait(1000); examPage.verifyResetButtonDisabled(); examPage.verifyDeviceStatus('loading'); // 7. 等待API响应完成 cy.wait('@resetDeviceDelay'); // 8. 验证按钮恢复可用 examPage.verifyResetButtonEnabled(); // 9. 验证Redux状态更新为'succeeded' examPage.verifyDeviceStatus('succeeded'); }); }); describe('TC-RESET-04: 网络错误处理', () => { it('应该正确处理网络异常', () => { // 1. Mock网络错误 mockResetDeviceNetworkError(); // 2. 点击RESET按钮 examPage.clickResetGenerator(); // 3. 等待错误发生 cy.wait('@resetDeviceNetworkError'); // 4. 验证Redux状态更新为'failed' examPage.verifyDeviceStatus('failed'); // 5. 验证错误信息被捕获 cy.window() .its('store') .invoke('getState') .its('device') .its('error') .should('exist'); // 6. 验证按钮恢复可用 examPage.verifyResetButtonEnabled(); // 7. 验证用户可以重试 mockResetDeviceSuccess(); examPage.clickResetGenerator(); cy.wait('@resetDevice'); examPage.verifyDeviceStatus('succeeded'); }); }); describe('TC-RESET-05: 防止重复点击', () => { it('应该防止loading时重复点击', () => { // 1. Mock设备重置API延迟响应(3秒) let requestCount = 0; cy.intercept('POST', '/auth/device/action', (req) => { if (req.body.reqName === 'RESET') { requestCount++; req.reply({ statusCode: 200, body: { code: '0x000000', description: 'Success', data: {}, }, delay: 3000, }); } }).as('resetDeviceMultiple'); // 2. 点击RESET按钮 examPage.clickResetGenerator(); // 3. 验证按钮禁用 examPage.verifyResetButtonDisabled(); // 4. 立即再次尝试点击按钮(应该无效) examPage.getResetGeneratorButton().click({ force: true }); // 5. 等待1秒后再次尝试点击 cy.wait(1000); examPage.getResetGeneratorButton().click({ force: true }); // 6. 等待第一次请求完成 cy.wait('@resetDeviceMultiple'); // 7. 验证只发送了一次API请求 cy.wrap(null).then(() => { expect(requestCount).to.eq(1); }); // 8. 验证完成后可以再次点击 examPage.verifyResetButtonEnabled(); // 重新mock成功响应 mockResetDeviceSuccess(); examPage.clickResetGenerator(); cy.wait('@resetDevice'); examPage.verifyDeviceStatus('succeeded'); }); }); });