Closed honzabrecka closed 1 year ago
Cypress catches uncaught exceptions and will display them because they fail the test.
What warnings / errors do you want to get? Also what do you mean "get output from the console"?
Are you saying you want console.log
to be output in headless mode?
Hi !
Maybe I can suggest you something. I need more info in console too. In browser. When an assertion failed, concerning an element, it could be great to console.log it.
For example, I would like to know if all the images in my page has src attribute and if this attribute starts for each one by "https://". If one not, the cypress.each will say me it has failed. But on which one? I have to edit my test, console.log each element and find myself. Not really useful (juste for this part, cypress itself is very useful)
To clarify, in nightwatch I have a custom command/assert to check that the code haven't produced any runtime warning/error. For example 'React in development mode warns that markup produced on server differs from markup produced on client'. Something like this:
// this would be the last step
cy
.getConsoleLog()
.should(function(log) {
// log = [['warn', 'warning message'], ['log', 'regular log message'] ['warn', 'another warning message']]
// check that log does not contain any 'warn' or 'error' entry
const disallowedLevels = new Set(['warn', 'error'])
expect(log.some(([level]) => disallowedLevels.has(level)).false
})
Oh, we didn't speak about the same thing. I'll create a separate issue
+1 on this. We use the cypress run
command in continuous integration. Currently we are looking at a test which fails using cypress run
, but succeeds when using the non-headless version. The movie shows that our webgl canvas is not loaded in the headless version, but we have no information on where to start debugging (the movie just shows the canvas absent). I would like to see the console log with errors coming from javascript when executing cypress run
.
There is a non-documented way of seeing the headless GUI and being able to use dev tools on it. You'll have to run this from a local machine (cannot do this in CI environment).
You invoke the binary directly like so:
On linux:
/home/<user>/.cypress/Cypress/Cypress --project <fully_qualified_project_path> --show-headless-gui
On OSX
/Applications/Cypress.app/Contents/MacOS/Cypress --project <fully_qualified_project_path> --show-headless-gui
A way to see console.log
is currently being worked on. Please leave any feedback on this issue: #448
Just FYI the one easy solution is just to spy
on console functions.
cy.window().then((win) => {
cy.spy(win.console, "log")
})
That will print a command log every time that function is called, and you could also then assert on what has been logged.
@brian-mann in response to your Nov 20, 2016 comment: I added a throw new Error('Error!')
to the created()
component hook of a Vue.js application. Cypress didn't catch the exception and tests passed.
Hmm, @ianwalter can you put the entire repo with this problem up somewhere on github so we can investigate the same code, please?
@ianwalter without a doubt, Cypress will catch uncaught exceptions - as long as:
onerror
handler (and then chose not to call the original fn)My guess is that vue.js
might have added its own error handling so errors in your components will not bubble up to the window.onerror
function.
Additionally Cypress sets the onerror
handler on your application so it can be notified when uncaught exceptions occur. Sometimes users / frameworks will then override this function - but they typically will call the original function to pass up the errors in the case where the function is already defined. You can check this by simply typing window.onerror
in your console (in your App's context frame). That will show you what the function is.
@brian-mann Ah good point, I'll check that out, thanks.
@brian-mann Looks like you're right. Vue gobbles up the exception and console.error
's it unless you set your own handler via Vue.config.errorHandler
.
What is the best solution?
Vue.config.errorHandler
to a function that will fail the test within Cypress?console.error
and fail the test there?It's really dumb for vue not to bubble up to window.onerror
if you haven't set a Vue.config.errorHandler
.
How would you get error notifications to services like Sentry or Raygun? It would require configuring that explicitly instead of it "just working" by default.
Anyway you could manually recreate the connection again using Cypress itself.
cy.visit('/app', {
onLoad: (win) => {
// something like that
win.onerror = cy.onUncaughtException
// or maybe this..
win.Vue.config.errorHandler = cy.onUncaughtException
}
})
I agree. Looks like services like Sentry set the Vue.config.errorHandler
in it's Vue-specific plugin (See https://github.com/getsentry/raven-js/blob/master/plugins/vue.js).
Anyway, thanks for the workaround. I'm really enjoying Cypress!
A massive hack is to do something like
<div>{ JSON.stringify(this.state) }</div>
Than, just watch the video artefact and pause it at the right time 🤣
One note for others who want to use @brian-mann's solution of spying on the console log: the spy should be set up in a listener for the window:before:load
event:
// globally somewhere like cypress/support/index.js, or for an individual test
beforeEach(() => {
cy.on("window:before:load", (win) => {
cy.spy(win.console, "log");
})
})
Calling it directly in a global beforeEach
block won't raise errors but also won't track log statements (the window object seems to be swapped out); calling it directly in a beforeEach
block in a test complains that the function is already spied on (not sure why).
@arsduo it complains because unless you are spying on the remote window, you'd be spying on the spec window, which would have already been spied on.
Also you don't have to put cy.on(...)
in a beforeEach. cy
listeners are removed after each test, and that's why the Cypress listeners exist (this is documented in the same place).
So add you need to do in a support file somewhere..
Cypress.on('window:before:load', (win) => {
cy.spy(win.console, "log")
})
Hi, I would like to see the brower's console log in the headless output.
I have added this to support/index.js
But I cannot see any console log. What else should I do?
Cypress.on('window:before:load', (win) => {
cy.spy(win.console, "log")
})
I am having the same issue!
For some context: I'm running a cypress run --record inside a docker container. Cypress test runner outside of docker works fine, but I'm having issues running tests when running cypress inside a docker container, using the official cypress/base:8 image as a foundation. Hence I'm trying to debug whats going on when cypress runs headlessly inside of docker.
It seems to work for me, however the only place I can see the log is in the video (see attached screenshot (at step SPY-1)). However my log is clipped by the size of the left command pane... so the usefulness is low.
Is there a way to see the command log without watching the video?
Here's a workaround I'm using to show console logs and console errors while in headless mode. It also(as an unintended side effect) fails the tests which have any console logs/errors.
in cypress/support/index.js
:
Cypress.on('window:before:load', win => {
cy.stub(win.console, 'log', msg => {
cy.task('log', `console.log --> ${msg}`)
})
cy.stub(win.console, 'error', msg => {
cy.task('log', `console.error --> ${msg}`)
})
})
in cypress/plugins/index.js
(this is a snippet from the docs):
module.exports = (on, config) => {
on('task', {
log(message) {
console.log(message)
return null
},
})
}
@siowyisheng I tried your approach, but never see the logs via cy.log
or files if I write 'em via fs.writeFileSync
. Cypress keeps complaining I'm doing a cy.task
inside the cy.visit
. Is this what you meant by causing all to fail intentionally? Is there some detail I'm missing?
So i'm having the same issue as @JesterXL.
@glomotion @JesterXL I've written an SO answer with one possible workflow, summing up some of the points from this topic + addressing the cypress "complaints".
Related issue involving printing console information to CLI output: https://github.com/cypress-io/cypress/issues/700 If you're goal is to see the console information printed within the CLI, please comment in that issue.
I am leaving this issue open and repurposing it as "Print console information to Command Log" as that has been the bulk of the conversation of this thread.
This issue is still related to the larger issue of logging ALL events and commands to display in the Dashboard here: https://github.com/cypress-io/cypress/issues/448
@darenyong I had the same issue, where my test did not work as expected but the video from cypress run
did not give enough information to fix it. I ended up running the CI job locally using circleci-cli, and adding steps so that I could create an SSH session with X forwarding. Then, I manually ran cypress open
and used the browser's development tools to find the problem.
The steps I used to do this are here: cypress-debug.md
@glomotion @JesterXL I've written an SO answer with one possible workflow, summing up some of the points from this topic + addressing the cypress "complaints".
This actually works very well!
The following worked for me and it even includes the full error message.
cypress/support/index.js
beforeEach(() => {
cy.window().then((win) => {
cy.spy(win.console, "error");
cy.spy(win.console, "warn");
});
});
afterEach( () => {
cy.window().then((win) => {
expect(win.console.error).to.have.callCount(0);
expect(win.console.warn).to.have.callCount(0);
});
});
Here's a sample of the output when a console error or console warning has occurred:
The solution I provided below doesn't work 100% of the time (more like 1% of the time) because it seems that a new window (win
) object is created after each call to cy.visit('/some/page')
. So make sure you create the spy after each call to cy.visit()
. This was clarified for me in #4808.
The following worked for me and it even includes the full error message.
cypress/support/index.js
beforeEach(() => { cy.window().then((win) => { cy.spy(win.console, "error"); cy.spy(win.console, "warn"); }); }); afterEach( () => { cy.window().then((win) => { expect(win.console.error).to.have.callCount(0); expect(win.console.warn).to.have.callCount(0); }); });
Here's a sample of the output when a console error or console warning has occurred:
Note: in order to avoid the error attempted to wrap error which is already wrapped
, make sure to restore the spy after each test, or simply before setting up a new spy:
if ((win.console.error as any).restore) {
(win.console.error as any).restore();
}
cy.spy(win.console, 'error');
The feature that I am looking for is: dump the entire content of the debug console to a file at the end of a test so it can be saved as a test artifact.
Recently migrated from Protractor to Cypress and was surprised a simple API for reading from the browser console does not exist yet. Very much looking forward to this feature!
This does exactly what I needed for catching any error in the console and do an assertion of the logs count. Just add the following in cypress/support/index.js
Cypress.on('window:before:load', (win) => {
cy.spy(win.console, 'error');
cy.spy(win.console, 'warn');
});
afterEach(() => {
cy.window().then((win) => {
expect(win.console.error).to.have.callCount(0);
expect(win.console.warn).to.have.callCount(0);
});
});
Our team wanted to log the console output to the terminal for debugging some issues. We ended up using a great package/plugin (https://github.com/flotwig/cypress-log-to-output) that was able to let us see what was going wrong in the headless Chrome's console from the CI terminal. Hopefully this package helps someone else!
how can we type into cypress browser console and assert on the returned value using cypress
There are some great suggestions here. I'm getting encouraging results in e2e tests with this addition to the support file:
Cypress.on("window:before:load", (win) =>
["error", "warn"].forEach((logLevel) => Cypress.sinon.mock(win.console).expects(logLevel).never())
);
It helps if you don't want failed assertions in your afterEach() to skip remaining tests.
Still experimenting with the component version, but it will probably be similar.
Closing this issue as making browser console info available for review during the run is part of Cypress Test Replay. Test Replay allows you to see all console logs, including errors, info and warnings, as they displayed when your tests ran.
If you'd like to log console output to the terminal, there are some great open source plugins available to facilitate this also like https://github.com/flotwig/cypress-log-to-output.
Thanks for all of your feedback on this issue. 🙏🏻
Is it possible to get output from the console? Especially warnings and errors. We are using it as a very simple and quick check that the commit didn't introduce any runtime error.