赛普拉斯测试 Material-UI 日期选择器不适用于 Github 操作
Posted
技术标签:
【中文标题】赛普拉斯测试 Material-UI 日期选择器不适用于 Github 操作【英文标题】:Cypress testing a Material-UI datepicker is not working on Github actions 【发布时间】:2021-12-16 07:48:09 【问题描述】:在 github 操作中运行 cypress 测试时,我们有一个奇怪的行为。 MUI datepicker datepicker处于只读模式,不能输入任何日期(在其他环境下没问题)。
赛普拉斯错误
CypressError: Timed out retrying after 4000ms: cy.clear()
failed 因为这个元素是只读的:
<input aria-invalid="false" readonly="" type="text" aria-readonly="true" aria-label="Choose date" class="MuiOutlinedInput-input MuiInputBase-input css-1x5jdmq" value="">
在视觉上看起来日期选择器没有任何按钮(正在发生的事情):
-
控制台日志未显示错误或警告
在其他环境(windows/linux)上,测试工作正常,即使我们以无头模式(所有具有 UI 的桌面)启动测试。 MUI 日期选择器看起来与 MUI 文档 (link) 中的一样好。
Github 操作看起来像:
on:
workflow_dispatch:
defaults:
run:
working-directory: ic3-test
jobs:
build:
runs-on: ubuntu-latest
container: cypress/included:8.6.0
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '16'
- name: Install dependencies
run: npm install
working-directory: ic3-test
- name: Cypress run with env
uses: cypress-io/github-action@v2
with:
# headless: true
browser: chrome
record: true
working-directory: ic3-test
产生错误的 Cypress 行:
cy.getWidget(widgetId). // this is getting a div with wid = widgetId , works fine
.find("input.MuiInputBase-input")
.clear()
.type(date). // date is a string
欢迎提供一些提示
【问题讨论】:
你能在失败的地方添加代码行吗? 看起来mui-lab
使用了来自外部库的日期函数。您的项目使用哪个库?例如:moment、luxon、dayjs、jalaali、hijri、js-joda
@AlapanDas,不确定这是否会对您有所帮助。查看更新的问题
@AJcodez ,它是 date-fns -> mui.com/components/pickers
@ic3 你如何将force: true
与type
和clear
一起添加并检查它是如何进行的 - cy.getWidget(widgetId).find("input.MuiInputBase-input").clear(force: true).type(date,force: true)
【参考方案1】:
在 azure devops 管道中运行 cypress 测试时,我们遇到了同样的错误。我认为这也是同样的原因,看看你没有任何按钮的日期选择器截图。
给我们错误的输入是@mui/lab/DatePicker
。
当我们在 azure devops 管道中运行 cypress 测试时,我们发现此组件呈现为 @mui/lab/MobileDatePicker
。这里有解释:docs。
该版本不接受直接文本输入,但会打开一个对话框来选择/输入日期,因此 cypress 测试在尝试输入输入时失败。
我们的解决方案是直接使用@mui/lab/DesktopDatePicker
。
【讨论】:
有道理,我们将朝这个方向进行调查。 那是因为媒体查询赖特?现在这是要考虑的事情【参考方案2】:这背后的原因是 Material UI 渲染了 MobileDatePicker
组件,因为查询 @media (pointer: fine)
在我们的 Github Actions Workflow 使用的无头 Chrome 上不匹配。移动组件只有只读输入,因此不能用.type()
和.clear()
清除或输入(与DesktopDatePicker
组件相反,它具有可键入和可清除的输入)。
由于我们不想删除 MobileDatePicker
组件,因此我们创建了一个自定义命令,以便检查当前是否正在呈现移动日期选择器。如果在移动设备上,测试会打开日期选择器,单击编辑按钮,从而打开移动输入视图。
在那个输入视图中,输入字段不再是readonly
。使用该命令,无论是台式机还是移动设备,都可以清除输入字段并输入。
Cypress.Commands.add(
'chooseDatePicker',
(selector: string, value: string) =>
cy.get('body')
.then(($body) =>
const mobilePickerSelector = `$selector input[readonly]`;
const isMobile = $body.find(mobilePickerSelector).length > 0;
if (isMobile)
// The MobileDatePicker component has readonly inputs and needs to
// be opened and clicked on edit so its inputs can be edited
cy.get(mobilePickerSelector)
.click();
cy.get('[role="dialog"] [aria-label="calendar view is open, go to text input view"]')
.click();
cy.get(`[role="dialog"] $selector`)
.find('input')
.clear()
.type(value);
cy.contains('[role="dialog"] button', 'OK')
.click();
else
cy.get(selector)
.find('input')
.clear()
.type(value);
);
,
);
// Usage:
const datePickerValue = '2021-01-03';
cy.chooseDatePicker('[data-testid="my-datepicker"]', datePickerValue);
【讨论】:
【参考方案3】:由于我没有看到所有的代码,我会尽可能具体地评论,我希望你审查几个主题。
1- 检查转换后的代码中的属性。确保不应设置诸如 helperText=null 之类的属性。
2- 你可能需要安装 polyfills。例如 popper.js (传递依赖)。尽管 MUI 声称它是(波利)不需要的。技术每天都在进步,可能会有他们无法捕捉到的变化。
3- 确保工作模式正确。甚至用 Jest 测试它。这样的window.matchMedia。
【讨论】:
以上是关于赛普拉斯测试 Material-UI 日期选择器不适用于 Github 操作的主要内容,如果未能解决你的问题,请参考以下文章