For a React project, I put in place a CI with Cypress end-to-end tests on Github Actions.
Here is the issue:
- my tests pass locally
- they all fail with this error on Github Actions : AssertionError: Timed out retrying after …ms: Expected to find content: ‘Do the laundry’ but never did. It seems like the tests cannot access the data
Add task
1) Should add a task
0 passing (22s)
1 failing
1) Add task
Should add a task:
AssertionError: Timed out retrying after 20000ms: Expected to find content: 'Do the laundry' but never did.
at Context.eval (webpack:///./cypress/e2e/addTask.cy.ts:7:36)
(Results)
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Tests: 1 │
│ Passing: 0 │
│ Failing: 1 │
│ Pending: 0 │
│ Skipped: 0 │
│ Screenshots: 1 │
│ Video: true │
│ Duration: 22 seconds │
│ Spec Ran: addTask.cy.ts │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
Here is the AddTask Spec:
describe("Add task", () => {
it("Should add a task", () => {
cy.visit("/");
cy.fixture("taskList").then((taskList) =>{
cy.get("[data-cy='add-task']").type(taskList[0].task);
cy.get("[data-cy='submit']").click();
cy.contains(taskList[0].task).should("exist");
})
});
});
My data comes from a file in the fixture folder:
[
{
"task": "Do the laundry"
},
{
"task": "Call Mark"
},
{
"task": "Do the dinner"
},
{
"task": "Do the lunch"
},
{
"task": "Buy cinema tickets"
},
{
"task": "Go to the supermarket"
}
]
And this is my cypress.config.ts file:
import { defineConfig } from "cypress";
export default defineConfig({
e2e: {
baseUrl: "http://localhost:3000",
defaultCommandTimeout: 20000,
setupNodeEvents(on, config) {
// implement node event listeners here
},
},
});
Here are the solutions I put in place:
-
in the cypress.config file I added a defaultCommandTimeOut of 20000 seconds
-
I tried increasing { timeout: 20000 } directly in the code
-
I also improved my YAML, like this:
name: CI
on: push
jobs:
cypress-run:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: 18
- name: Install dependencies
run: npm install
working-directory: ./front-end
- name: Cypress run
uses: cypress-io/github-action@v5
with:
working-directory: ./front-end
build: npm run build
start: npm start
wait-on: http://127.0.0.1:3000
wait-on-timeout: 180
browser: chrome
Please, let me know if you have any solutions for this problem!
2
Answers
Since it is working locally, but not in the Github Actions side, I would check first for any difference between the two set up.
differences in environment (variable, file, database)
difference in data access: The error suggests that Cypress is not able to find the content ‘Do the laundry’. If this content is loaded asynchronously (for example, fetched from an API), it might be that it is taking longer to load in the CI environment than in your local environment. In this case, you might need to increase the timeout or use Cypress commands that wait for certain conditions to be true (like
cy.wait()
,cy.intercept()
, orcy.fixture()
).difference in port: better to let your application choose a free port dynamically and then have Cypress wait for that port to become available.
difference in
baseUrl
incypress.json
: Make sure that thebaseUrl
in your cypress.json is correct and accessible from the CI environment.Another debug idea: add some logging or screenshots to your tests to help with debugging.
For example, you could take a screenshot after the task is added to see if it is appearing on the screen as expected:
You can also add logs to see if the fixture data is being loaded correctly:
Remember to check the logs and screenshots in the GitHub Actions job output to help identify the issue.
Thanks for adding the full details.
I can’t say definitively what it is, but some things to try:
it isn’t missing the fixture file, since
cy.fixture("taskList")
would throw a different error.it might be using a different version of the
taskList
, but can’t see how. Add anexpect()
to see if the fixture file is correctuse
cy.get(...).should('contain', taskList[0].task)
for a better error message – it should tell you what the task texts actually are.since it’s React, try adding a
cy.wait(0)
after theclick()
. Sometimes hooks do not complete their event handlers because the Cypress test hogs the Javascript thread, andcy.wait(0)
releases the thread so that React hooks can complete theclick()
action.instead of increasing the timeout to
20_000
for the Github run, try decreasing it to say 200 – 500 ms for the local run to see if you can reproduce the error locally