Mark Longair
Mark Longair

Reputation: 467181

How can I see `cy.log` output when using Cypress headlessly?

When running Cypress headlessly, I can see console.log output from the frontend code under test by using the DEBUG environment variable, like:

DEBUG='cypress:launcher' npx cypress run --browser chrome

However, I haven't found any similar way to see the output of cy.log from the Cypress test code when running headlessly. Even with DEBUG='cypress:*' I don't see them - they only seem to be visible in the interactive interface. It feels like there must be some way to see the cy.log output headlessly - can someone help with that?

Upvotes: 12

Views: 9398

Answers (2)

hughsk
hughsk

Reputation: 3997

The first step is to add a new task in your Cypress config file cypress.config.js (in the cypress root folder) so that you can run console.log from Node:

import { defineConfig } from "cypress";

export default defineConfig({
  e2e: {
    setupNodeEvents(on, config) {
      on("task", {
        log(args) {
          console.log(...args);
          return null;
        }
      });
    },
  },
});

Then, you can override cy.log so that it calls this task whenever you run the command in headless mode, and console.log when you're running in headed mode. You can do this by adding the following to your commands file commands.js (in the support folder):

Cypress.Commands.overwrite("log", function(log, ...args) {
  if (Cypress.browser.isHeadless) {
    return cy.task("log", args, { log: false }).then(() => {
      return log(...args);
    });
  } else {
    console.log(...args);
    return log(...args);
  }
});

If you want the output to be tabbed/indented (so it will look nicer in the log),
you can do a slight improvement, like so:

Cypress.Commands.overwrite("log", function(log, ...args) {
  const indent = "\t"; // You can adjust the number of tabs or spaces here
  const formattedArgs = args.map((arg) =>
        typeof arg === "string" ? indent + arg : indent + JSON.stringify(arg)
  );
  if (Cypress.browser.isHeadless) {
    return cy.task("log", formattedArgs, { log: false }).then(() => {
      return log(...args);
    });
  } else {
    console.log(...formattedArgs);
    return log(...args);
  }
});

One tab should be sufficient.

Upvotes: 19

mgpmul
mgpmul

Reputation: 175

I can see the output of cy.log by using DEBUG=cypress.server.task. I used it to get a log of the headers of a sent request when running in headless mode.

Although I first tried the solution of @hughsk, I noticed that I could to without it; just using DEBUG suffices for me. Because we also have code coverage running as a task, this will still generate a lot of logging, after which it is a bit tedious to find the cy.log task that your are interested in. In that case, you can redirect the output to a file and then use a text editor to search for it.

In Linux/Unix, the DEBUG output is going to the error output, so you'll have to use '2>' to redirect it to a file.

Like this:

DEBUG='cypress:server:task' npx cypress run --browser=chrome 2> DEBUG_cypress-server-task.log

Upvotes: 2

Related Questions