You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Playwright中稳健选择Ant Design DatePicker的可用日期(目标日期可能不存在或禁用)

如何在Playwright中稳健选择Ant Design DatePicker的可用日期(目标日期可能不存在或禁用)

我之前在做React+AntD项目的Playwright端到端测试时,也被DatePicker这个问题折腾过好多次——想选15号,结果要么当前面板显示的是上个月,要么15号因为超出了业务设置的日期范围被禁用了,测试用例直接卡壳。后来摸索出几个稳健的处理方式,分享给你:

首先,核心思路就是别硬写死点击某个日期,而是先判断目标日期的状态,再做对应的操作:

方案一:循环切换月份,直到找到可用的目标日期

这个方法适合目标日期本身在允许范围内,但不在当前显示的日历面板里的情况。我们可以封装一个可复用的函数,自动切换月份找目标日期,要是实在找不到(比如目标日期被禁用),就选最近的可用日期:

async function selectAvailableDate(page, targetDay, datePickerSelector) {
  // 先打开日期选择器弹窗
  await page.locator(datePickerSelector).click();

  while (true) {
    // 定位当前面板里所有未被禁用的日期元素
    const availableDateCells = page.locator('.ant-picker-cell:not(.ant-picker-cell-disabled) .ant-picker-cell-inner');
    
    // 检查当前面板有没有我们要的目标日期
    const targetCell = availableDateCells.filter({ hasText: targetDay.toString() });
    const isTargetInPanel = await targetCell.count() > 0;

    if (isTargetInPanel) {
      // 找到可用的目标日期,直接点击
      await targetCell.click();
      break;
    }

    // 检查能不能切换到下一个月(如果下月按钮被禁用,说明到了最大允许的月份)
    const nextMonthBtn = page.locator('.ant-picker-header-next-btn:not(.ant-picker-header-btn-disabled)');
    if (await nextMonthBtn.count() === 0) {
      // 目标日期不可用,直接选当前面板最后一个可用的日期
      await availableDateCells.last().click();
      break;
    }

    // 切换到下一个月,然后等待面板更新
    await nextMonthBtn.click();
    // 用waitForSelector代替固定超时,更稳妥
    await page.waitForSelector('.ant-picker-cell-inner', { state: 'visible' });
  }
}

// 调用示例:给#date_acquired选择器选15号
await selectAvailableDate(page, 15, '#date_acquired');

方案二:提前获取日期范围,避免无效切换

如果你的DatePicker设置了minDatemaxDate,可以先通过页面评估获取这些限制,提前判断目标日期是否在允许范围内,这样能减少不必要的月份切换:

async function selectTargetOrNearestAvailable(page, targetDay, datePickerSelector) {
  await page.locator(datePickerSelector).click();

  // 获取DatePicker的min和max日期限制
  const [minDate, maxDate] = await page.evaluate((selector) => {
    const picker = document.querySelector(selector);
    // 拿到React组件的props(AntD的DatePicker是React组件)
    const reactProps = Object.getOwnPropertySymbols(picker).find(s => s.description === 'reactProps');
    if (!reactProps) return [null, null];
    return [picker[reactProps].minDate, picker[reactProps].maxDate];
  }, datePickerSelector);

  // 这里可以根据minDate和maxDate判断目标日期是否合法,比如目标日期超过maxDate的话,直接选maxDate对应的日期
  // (具体日期比较逻辑可以根据你的业务需求调整)
  // 然后再执行月份切换和选择逻辑...
}

一些避坑小贴士

  • 别直接修改input的value:虽然有时候能成功,但AntD的受控DatePicker可能不会触发onChange事件,导致表单数据没同步,模拟用户点击的方式更符合真实操作流程,也更稳定。
  • 优先用waitForSelector代替固定超时:比如切换月份后,等新的日期面板加载完成再操作,避免页面加载慢导致的元素找不到错误。
  • 处理过去的日期:如果你的目标日期是上个月的,只需要把代码里的nextMonthBtn改成prevMonthBtn,逻辑类似,切换到上月面板查找即可。

内容来源于stack exchange

火山引擎 最新活动