We have a strange behavior when running our cypress tests in a github action. MUI datepicker the datepicker is in readonly mode and we can't enter any date (it's fine in other environments).
Error in Cypress
CypressError: Timed out retrying after 4000ms: cy.clear()
failed because this element is readonly:
<input aria-invalid="false" readonly="" type="text" aria-readonly="true" aria-label="Choose date" class="MuiOutlinedInput-input MuiInputBase-input css-1x5jdmq" value="">
Visually looks the date picker does not have any button (something is going on) :
On other environments, windows/linux, the tests work fine, even though we launch the test in headless mode (all desktops with a UI). The MUI datepicker looks as nice as in MUI documentation (link).
Github action looks like :
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
The Cypress line that generates the error :
cy.getWidget(widgetId). // this is getting a div with wid = widgetId , works fine
.find("input.MuiInputBase-input")
.clear()
.type(date). // date is a string
Some hints are welcomed
We had the same error when running cypress test in azure devops pipelines. And I think its the same reason, looking at your screenshot of the date picker without any button.
The input which was giving us the error was @mui/lab/DatePicker
.
We found that this component is rendering as @mui/lab/MobileDatePicker
when we ran the cypress tests in azure devops pipelines. It's explained here: docs.
That version not accept direct text input, but opens a dialog to pick/input date, therefore cypress test fails when trying to type into the input.
Our solution was to use @mui/lab/DesktopDatePicker
directly.
The reason behind this is that Material UI renders the MobileDatePicker
component, since the query @media (pointer: fine)
doesn't match on the headless Chrome used by our Github Actions Workflow. The mobile component only has readonly inputs, therefore it can't be cleared or typed into with .type()
and .clear()
(as opposed to the DesktopDatePicker
component, which has typable and clearable inputs).
Since we don't want to remove the MobileDatePicker
component, we've created a custom command so it checks if the mobile date picker is currently being rendered. If on mobile, the test opens the date picker, clicks on the edit button, so the mobile input view is opened.
And in that input view, the input field is not readonly
anymore. Using that command, no matter if desktop or mobile, the input field can be cleared and typed into.
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);
Since I haven't seen all the code, I will try to comment as specific as I can, I would like you to review few topics.
1- Examine the properties in the transformed code. Make sure a Property such as helperText={null} is should not set.
2- You might need to install polyfills. For instance for the popper.js (transitive dependency). Although MUI claims that it is (polly) not needed. Technology is advancing every day and there may be changes that they cannot catch.
3- Be sure working right mode. Even test it with Jest. Such window.matchMedia.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With