import dayjs from 'dayjs'; import { mockLoginSuccess } from '../../support/mock/handlers/user'; describe('年龄和出生日期联动功能测试', () => { beforeEach(() => { // 设置登录 Mock mockLoginSuccess(); // 登录并进入注册页面 cy.visit('/'); cy.get('[data-testid="username"]').type('admin'); cy.get('[data-testid="password"]').type('123456'); cy.get('[data-testid="login-button"]').click(); cy.wait('@loginSuccess'); // 导航到患者管理 -> 注册页面 cy.get('[data-testid="patient-management"]').click(); cy.get('[data-testid="register"]').click(); cy.wait(1000); // 等待页面加载 }); describe('场景1:修改年龄自动更新出生日期', () => { it('应该在修改年龄为25年时,自动更新出生日期为25年前', () => { // 获取年龄输入框和出生日期选择器 const ageInput = cy.get('[data-testid="patient_age-number"]').should('exist'); const ageUnitSelect = cy.get('[data-testid="patient_age-unit"]').should('exist'); const dobPicker = cy.get('[data-testid="patient_dob"]').should('exist'); // 修改年龄为25 ageInput.clear().type('25'); // 确认单位为"年" ageUnitSelect.click(); cy.contains('.ant-select-item-option-content', '年').click(); // 等待联动更新 cy.wait(500); // 验证出生日期已更新(应该是25年前的日期) const expectedDate = dayjs().subtract(25, 'year'); dobPicker.should(($input) => { const value = $input.val() as string; const selectedDate = dayjs(value); // 允许1天的误差 expect(Math.abs(selectedDate.diff(expectedDate, 'day'))).to.be.lessThan(2); }); // 验证Redux store cy.window().its('store').invoke('getState').its('form').its('formData').its('patient_dob').should('exist'); }); it('应该在修改年龄为6月时,自动更新出生日期为6个月前', () => { const ageInput = cy.get('[data-testid="patient_age-number"]').should('exist'); const ageUnitSelect = cy.get('[data-testid="patient_age-unit"]').should('exist'); const dobPicker = cy.get('[data-testid="patient_dob"]').should('exist'); // 修改年龄为6月 ageInput.clear().type('6'); ageUnitSelect.click(); cy.contains('.ant-select-item-option-content', '月').click(); cy.wait(500); // 验证出生日期(应该是6个月前) const expectedDate = dayjs().subtract(6, 'month'); dobPicker.should(($input) => { const value = $input.val() as string; const selectedDate = dayjs(value); expect(Math.abs(selectedDate.diff(expectedDate, 'day'))).to.be.lessThan(2); }); }); it('应该在修改年龄为15天时,自动更新出生日期为15天前', () => { const ageInput = cy.get('[data-testid="patient_age-number"]').should('exist'); const ageUnitSelect = cy.get('[data-testid="patient_age-unit"]').should('exist'); const dobPicker = cy.get('[data-testid="patient_dob"]').should('exist'); // 修改年龄为15天 ageInput.clear().type('15'); ageUnitSelect.click(); cy.contains('.ant-select-item-option-content', '天').click(); cy.wait(500); // 验证出生日期(应该是15天前) const expectedDate = dayjs().subtract(15, 'day'); dobPicker.should(($input) => { const value = $input.val() as string; const selectedDate = dayjs(value); expect(Math.abs(selectedDate.diff(expectedDate, 'day'))).to.be.lessThan(2); }); }); }); describe('场景2:修改出生日期自动更新年龄', () => { it('应该在选择出生日期为2000-01-01时,自动计算并更新年龄', () => { const dobPicker = cy.get('[data-testid="patient_dob"]').should('exist'); const ageInput = cy.get('[data-testid="patient_age-number"]').should('exist'); const ageUnitSelect = cy.get('[data-testid="patient_age-unit"]').should('exist'); // 点击出生日期选择器 dobPicker.click(); // 选择年份2000 cy.get('.ant-picker-year-btn').click(); cy.contains('.ant-picker-cell', '2000').click(); // 选择月份1月 cy.get('.ant-picker-month-btn').click(); cy.contains('.ant-picker-cell', '一月').click(); // 选择日期1日 cy.contains('.ant-picker-cell', '1').first().click(); cy.wait(500); // 验证年龄自动更新 const expectedYears = dayjs().diff(dayjs('2000-01-01'), 'year'); ageInput.should('have.value', expectedYears.toString()); // 验证单位为"年" ageUnitSelect.should(($select) => { const text = $select.text(); expect(text).to.contain('年'); }); }); it('应该在选择6个月前的日期时,年龄单位自动设置为"月"', () => { const dobPicker = cy.get('[data-testid="patient_dob"]').should('exist'); const ageInput = cy.get('[data-testid="patient_age-number"]').should('exist'); const ageUnitSelect = cy.get('[data-testid="patient_age-unit"]').should('exist'); // 选择6个月前的日期 const targetDate = dayjs().subtract(6, 'month'); dobPicker.click(); // 选择年份 cy.get('.ant-picker-year-btn').click(); cy.contains('.ant-picker-cell', targetDate.year().toString()).click(); // 选择月份 cy.get('.ant-picker-month-btn').click(); const monthNames = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月']; cy.contains('.ant-picker-cell', monthNames[targetDate.month()]).click(); // 选择日期 cy.contains('.ant-picker-cell', targetDate.date().toString()).click(); cy.wait(500); // 验证年龄约为6个月 ageInput.should(($input) => { const value = parseInt($input.val() as string); expect(value).to.be.closeTo(6, 1); }); // 验证单位为"月" ageUnitSelect.should(($select) => { const text = $select.text(); expect(text).to.contain('月'); }); }); it('应该在选择未来日期时,年龄显示为0天', () => { const dobPicker = cy.get('[data-testid="patient_dob"]').should('exist'); const ageInput = cy.get('[data-testid="patient_age-number"]').should('exist'); const ageUnitSelect = cy.get('[data-testid="patient_age-unit"]').should('exist'); // 选择明年的日期 const futureDate = dayjs().add(1, 'year'); dobPicker.click(); cy.get('.ant-picker-year-btn').click(); cy.contains('.ant-picker-cell', futureDate.year().toString()).click(); cy.get('.ant-picker-month-btn').click(); const monthNames = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月']; cy.contains('.ant-picker-cell', monthNames[futureDate.month()]).click(); cy.contains('.ant-picker-cell', futureDate.date().toString()).click(); cy.wait(500); // 验证年龄为0 ageInput.should('have.value', '0'); // 验证单位为"天" ageUnitSelect.should(($select) => { const text = $select.text(); expect(text).to.contain('天'); }); }); }); describe('场景3:快速连续修改不产生循环', () => { it('应该能够连续修改年龄和出生日期而不出错', () => { const ageInput = cy.get('[data-testid="patient_age-number"]').should('exist'); const ageUnitSelect = cy.get('[data-testid="patient_age-unit"]').should('exist'); const dobPicker = cy.get('[data-testid="patient_dob"]').should('exist'); // 第一次:修改年龄为25 ageInput.clear().type('25'); ageUnitSelect.click(); cy.contains('.ant-select-item-option-content', '年').click(); cy.wait(300); // 第二次:修改出生日期 dobPicker.click(); cy.get('.ant-picker-year-btn').click(); cy.contains('.ant-picker-cell', '2000').click(); cy.get('.ant-picker-month-btn').click(); cy.contains('.ant-picker-cell', '一月').click(); cy.contains('.ant-picker-cell', '1').first().click(); cy.wait(300); // 第三次:再次修改年龄为30 ageInput.clear().type('30'); cy.wait(300); // 验证最终状态一致 ageInput.should('have.value', '30'); // 不应该有控制台错误 cy.window().then((win) => { expect(win.console.error).not.to.be.called; }); }); }); describe('场景4:表单提交时数据正确', () => { it('应该在提交表单时包含正确的年龄和出生日期数据', () => { // 填写必填项 cy.get('input[name="accession_number"]').type('ACC001'); cy.get('input[name="patient_id"]').type('P001'); cy.get('input[name="patient_name"]').type('测试患者'); // 修改年龄为25岁 const ageInput = cy.get('[data-testid="patient_age-number"]'); const ageUnitSelect = cy.get('[data-testid="patient_age-unit"]'); ageInput.clear().type('25'); ageUnitSelect.click(); cy.contains('.ant-select-item-option-content', '年').click(); cy.wait(500); // 验证Redux store中的数据 cy.window().its('store').invoke('getState').its('form').its('formData').should((formData) => { // 验证年龄数据 expect(formData.patient_age).to.exist; expect(formData.patient_age.number).to.equal(25); expect(formData.patient_age.unit).to.equal('Y'); // 验证出生日期数据 expect(formData.patient_dob).to.exist; }); }); }); describe('场景5:边界情况处理', () => { it('应该正确处理年龄为0的情况', () => { const ageInput = cy.get('[data-testid="patient_age-number"]'); const dobPicker = cy.get('[data-testid="patient_dob"]'); // 设置年龄为0 ageInput.clear().type('0'); cy.wait(500); // 出生日期应该是今天 dobPicker.should(($input) => { const value = $input.val() as string; const selectedDate = dayjs(value); const today = dayjs(); expect(Math.abs(selectedDate.diff(today, 'day'))).to.be.lessThan(1); }); }); it('应该正确处理极大年龄(如100岁)', () => { const ageInput = cy.get('[data-testid="patient_age-number"]'); const ageUnitSelect = cy.get('[data-testid="patient_age-unit"]'); const dobPicker = cy.get('[data-testid="patient_dob"]'); // 设置年龄为100岁 ageInput.clear().type('100'); ageUnitSelect.click(); cy.contains('.ant-select-item-option-content', '年').click(); cy.wait(500); // 出生日期应该是100年前 const expectedDate = dayjs().subtract(100, 'year'); dobPicker.should(($input) => { const value = $input.val() as string; const selectedDate = dayjs(value); expect(Math.abs(selectedDate.diff(expectedDate, 'day'))).to.be.lessThan(2); }); }); it('应该正确处理1岁以下年龄的单位切换', () => { const ageInput = cy.get('[data-testid="patient_age-number"]'); const ageUnitSelect = cy.get('[data-testid="patient_age-unit"]'); // 设置年龄为11月 ageInput.clear().type('11'); ageUnitSelect.click(); cy.contains('.ant-select-item-option-content', '月').click(); cy.wait(500); // 修改出生日期,触发反向计算 const dobPicker = cy.get('[data-testid="patient_dob"]'); const targetDate = dayjs().subtract(11, 'month'); dobPicker.click(); cy.get('.ant-picker-year-btn').click(); cy.contains('.ant-picker-cell', targetDate.year().toString()).click(); cy.get('.ant-picker-month-btn').click(); const monthNames = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月']; cy.contains('.ant-picker-cell', monthNames[targetDate.month()]).click(); cy.contains('.ant-picker-cell', targetDate.date().toString()).click(); cy.wait(500); // 验证年龄约为11个月 ageInput.should(($input) => { const value = parseInt($input.val() as string); expect(value).to.be.closeTo(11, 1); }); // 验证单位为"月" ageUnitSelect.should(($select) => { const text = $select.text(); expect(text).to.contain('月'); }); }); }); describe('场景6:初始化时的联动', () => { it('应该在表单加载时保持初始值的一致性', () => { const ageInput = cy.get('[data-testid="patient_age-number"]'); const dobPicker = cy.get('[data-testid="patient_dob"]'); // 验证初始值都存在 ageInput.should('have.value'); dobPicker.should('have.value'); // 验证Redux store中的数据 cy.window().its('store').invoke('getState').its('form').its('formData').should((formData) => { if (formData.patient_age && formData.patient_dob) { // 如果两个字段都有值,验证它们的一致性 expect(formData.patient_age).to.exist; expect(formData.patient_dob).to.exist; } }); }); }); });