|
@@ -0,0 +1,354 @@
|
|
|
+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;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+ });
|
|
|
+});
|