在Playwright测试中如何精准点击Material UI日期选择器按钮?
问题描述
我在自动化测试中无法选中Material UI日期选择器按钮以打开日历选择日期:
- Codegen生成的代码
await page.getByRole('button', { name: 'Choose date, selected date is Feb 14, 2023' }).click();仅在已知已选日期时可用,通用性极差; - 使用正则匹配
await page.getByRole("button", { name: /Choose date, selected date is/ }).click();会因页面存在多个日期选择器而失效; - 尝试通过
await page.getByLabel("Start date").press("Tab").press("Enter");或await page.getByLabel("Start date").getByRole("button").click();操作,但均无效。
此外,我有一个仅在未选日期时可用的测试示例(但页面有其他日期选择器,所以用了first(),这是我想避免的):
test("select from a date picker", async ({ page }) => { await page.goto("https://mui.com/x/react-date-pickers/date-picker/"); await page.getByLabel("Basic Date Picker").click(); const datepicker = await page .locator("div") .filter({ hasText: "Basic date picker" }) .getByRole("button", { name: "Choose date" }) .first(); await datepicker.click(); await page .getByRole("dialog", { name: "Basic date picker" }) .getByRole("gridcell", { name: "14" }) .click(); });
可行解决方案
1. 通过标签关联父容器精准定位按钮
MUI日期选择器会把带label的输入框和触发按钮放在同一父容器内,先定位目标输入框,再向上找到父容器,最后定位内部按钮,彻底避免多选择器冲突:
// 针对"Start date"选择器的通用写法 await page .getByLabel("Start date") .locator("..") // 向上获取直接父元素 .getByRole("button", { name: /Choose date/ }) // 匹配未选/已选状态的按钮文本 .click();
如果locator("..")不够精准,可根据实际DOM结构换成更具体的父容器定位,比如locator("xpath=ancestor::div[contains(@class, 'MuiDatePicker-root')]")。
2. 直接操作输入框唤起日历
部分场景下,点击日期选择器的输入框本身就能唤起日历面板,无需专门找按钮:
// 直接点击输入框 await page.getByLabel("Start date").click(); // 若点击无效,尝试聚焦后按空格唤起 await page.getByLabel("Start date").focus(); await page.keyboard.press("Space");
3. 用filter+has实现精准筛选
通过filter筛选包含目标标签的日期选择器容器,再定位内部按钮,这种方式更健壮:
// 先锁定包含"Start date"标签的选择器容器 const startDatePicker = page.locator(".MuiDatePicker-root").filter({ has: page.getByLabel("Start date") }); // 定位容器内的触发按钮(兼容未选/已选两种状态) await startDatePicker.getByRole("button", { name: /^Choose date(, selected date is .+)?$/ }).click();
4. 覆盖两种状态的通用正则定位
按钮文本在未选时是Choose date,已选时是Choose date, selected date is ...,用正则覆盖两种状态,同时结合父容器定位避免冲突:
await page .getByLabel("Start date") .closest("div") // 获取最近的div父容器 .getByRole("button", { name: /^Choose date(, selected date is .+)?$/ }) .click();
完整测试示例(针对"Start date")
test("select start date from MUI date picker", async ({ page }) => { // 唤起日历面板 await page .getByLabel("Start date") .locator("..") .getByRole("button", { name: /Choose date/ }) .click(); // 选择目标日期(以14号为例) await page .getByRole("dialog", { name: /Start date/ }) // 匹配对应选择器的弹窗 .getByRole("gridcell", { name: "14" }) .click(); });
内容的提问来源于stack exchange,提问作者arecaps
相关产品推荐
相关产品推荐

