skip to Main Content

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


  1. 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(), or cy.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 in cypress.json: Make sure that the baseUrl 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:

    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");
          cy.screenshot(); // take a screenshot for debugging
        })
      });
    });
    

    You can also add logs to see if the fixture data is being loaded correctly:

    describe("Add task", () => {
     it("Should add a task", () => {
        cy.visit("/");
        cy.fixture("taskList").then((taskList) =>{
          cy.log(`Loaded taskList: ${JSON.stringify(taskList)}`); // log the loaded fixture data
          cy.get("[data-cy='add-task']").type(taskList[0].task);
          cy.get("[data-cy='submit']").click();
          cy.contains(taskList[0].task).should("exist");
        })
      });
    });
    

    Remember to check the logs and screenshots in the GitHub Actions job output to help identify the issue.

    Login or Signup to reply.
  2. 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 an expect() to see if the fixture file is correct

      cy.fixture("taskList").then((taskList) => {
        expect(taskList[0].task).to.eq('Do the laundry')
      
    • use 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 the click(). Sometimes hooks do not complete their event handlers because the Cypress test hogs the Javascript thread, and cy.wait(0) releases the thread so that React hooks can complete the click() 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

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search