Cypress seems to have stalled - cypress

I'm new to cypress and love the way it is architected. However, I seem to have run into a problem early on for a very simple thing that I'm trying to do.
My workflow is:
1) Visit the site
2) Enter username and password
3) On the next screen, type a number and press submit,
4) On the next screen, select a value from a dropdown and press enter.
5) I get to the landing page of my website.
Cypress works totally fine till step 4). It seems to stall at step 5. The test runner suddenly stalls and without warning or error, shows
"Whoops, there is no test to run."
From here, when I click the "View All Tests" button, it takes me to the runner tool. There I see the indication that something is still running in the background. I tried waiting for more than 10 minutes but nothing happens until I click on the "Stop" action.
How do I debug this? Can I see what is happening via any log etc?
There could even be something wrong with my website as well, but without any log information, I'm unable to proceed further. Any help is appreciated.
To provide more context, I don't think this is a timeout based issue as if that were the case, cypress did report to me about this and stopped. I then increased the timeout.
My spec file
describe('My first test', function() {
it('Visits home page', function() {
cy.visit('https://mywebsite.com:5800', {timeout: 400000}, {pageLoadTimeout: 400000}, {defaultCommandTimeout: 400000})
cy.get('#USERNAME').type('myusername')
cy.get('#PASSWORD').type('mypassword')
cy.get('#loginbutton').click()
cy.get('#SOMELEMENT_WHERE_I_TYPE_A_UNIQUE_NUMBER').type('8056')
cy.get('#loginbutton').click()
cy.get('#loginbutton').click()
})
})
Thanks.

If you run DEBUG=cypress:* cypress open from the terminal when initially opening Cypress, there will be more debug log information printed there while you run your tests.
Also, it's always a good idea to search the issues for the project to see if anyone else has had this happen.
For some reason, the Cypress automation gets into a state where it thinks that you have no spec file. All Cypress does to determine this is to see if there is a location.hash defined on the main window -> where it usually says https://localhost:2020/__/#tests/integration/my_spec.js.
Likely this is due to security mechanisms in the app that prevent your application from being run within an iframe (which is how Cypress runs all applications under test). Maybe in your application code it is something like:
if (top !== self) {
top.location.href = self.location.href;
}
You can simply disable these checks while testing or in Cypress you can add to your test file (or a support file to have it work on every test file):
Cypress.on('window:before:load', (win) => {
Object.defineProperty(win, 'self', {
get: () => {
return window.top
}
})
})

I had the same issue. Usually this is related to the page moving out of the parent and can be solved by invoking the attribute and changing it to the current page.
cy.get('.approved-content .no-auto-submit').invoke('attr', 'target', '_self');

Related

Cypress tests failing in firefox in pages with polling requests

I have a following test in Cypress:
visit first page with the header A
click on the Go to B Page button
assert that the header of the page is now B
It works fine in Chrome, but failing in Firefox, as on the page B I have some background polling requests, and when cypress switches to another test and those requests get "canceled" away, I get either TypeError: NetworkError when attempting to fetch resource or AbortError: The operation was aborted
All the requests are using fetch api, by the way.
The possibility to mute those errors through the uncaught:exception event seems a bad idea, and so does the idea to do something on the page to cancel the polling, as it is not the thing under testing.
Maybe someone has encoutnered this problem too and got some non-hacky solution?
I had a similar issue with Cypress tests in Firefox and resorted to the slightly hacky solution of using an uncaught:exception handler as you mention. It is possible to filter error messages somewhat at least:
function handleUncaughtException(err){
if (err.message.includes('Request aborted') ) {
console.log("Request aborted. Test will continue. Error:",err);
return false; // return false to make test continue
}
throw err;
}
cy.on('uncaught:exception',handleUncaughtException);
In principle you can cancel this handler when it's no longer needed. In my case though, this stopped the test working, presumably because the request started previous to or after the calls.
cy.removeListener("uncaught:exception", handleUncaughtException)
The Cypress docs have some advice on defining these: see at https://docs.cypress.io/api/events/catalog-of-events#Examples. It may be useful to put the handler in a support file, so that it is applied to all tests.
(See also https://docs.cypress.io/api/events/catalog-of-events#Event-Types and https://nodejs.org/api/events.html#events_emitter_removelistener_eventname_listener).

Lauching cypress test for the 2nd time, url lands on error page

I am trying to run a test using cypress, 1st time the test runs, it goes to the URL specified i.e. http://demo.nopcommerce.com/,
but 2nd time I run the test, the I am redirected to https://demo.nopcommerce.com/page-not-found#/tests/integration\examples\Locators.spec.js
Here is my Script:
describe('Locating Elements', function() {
it('Verify Types of locators', function() {
cy.visit('http://demo.nopcommerce.com/')
cy.get('#small-searchterms').type('Apple MacBook Pro 13-inch')
cy.get('.button-1.search-box-button[value="Search"]').click()
cy.get('.button-2.product-box-add-to-cart-button[value="Add to cart"]').click()
cy.get('#product_enteredQuantity_4').clear().type('3')
cy.get('input[type="button"][id="add-to-cart-button-4"]').click()
cy.contains('The product has been added to your').should('be.visible')
cy.get('.close').click()
cy.contains('Shopping cart').click()
cy.get('.estimate-shipping-button').click()
cy.get('.estimate-shipping-popup').then(function() {
cy.log('Hello.......')
cy.get('#CountryId').select('India')
})
})
})
Could you please try https://demo.nopcommerce.com/ instead of http:// inside cy.visit(), also please add "chromeWebSecurity" : false in cypress.json. When i tried with https://, it is working fine while rerunning the test.
May be a good idea to check with the dev team whether the nopcommerce.com domain/subdomain is configured properly to accepts http:// requests.

Log Javascript console output in Laravel Dusk

I am using Laravel 5.6 and Laravel Dusk 3.0.9.
Dusk is pretty handy, but when a test fails on a page where there is some Javascript functionality it can be pretty hard to work out what went wrong. Dusk generates a screenshot, which helps, but what I really need is to see the output from the Javascript console.
Apparently this is possible - Dusk creates a tests/Browser/console directory as part of its installation, and this PR suggests the JS console output is logged, or at least loggable.
There is no documentation (that I can find) about how to actually do that though. Browsing the diffs in that PR, I see a new method logConsole() (later renamed to storeConsoleLog() as #Jonas pointed out in the comments), but I can't seem to get it to do anything, eg:
$browser->visit('/somewhere')
->select('#foo', '2')
->value('#date', '2018-07-29')
->storeConsoleLog('bar')
->assertEnabled('button[type=submit]');
This test fails, and generates a nice screenshot, but there is no sign of any logfile. I've tried moving the position of ->storeConsoleLog('bar') around in the chain, eg first or last, and as a separate line before or after the chain:
$browser->visit('/somewhere')
->...full chain here;
$browser->storeConsoleLog('bar');
But none of them make any difference. My JS has a series of console.log()s which I use when testing myself in a browser, and which will tell me exactly what went wrong. I was expecting this functionality to log those messages.
Am I misunderstanding that PR, is this even possible? If so, how?
UPDATE
By debugging the storeConsoleLog() method in vendor/laravel/dusk/src/Browser.php I can see that the method is being called correctly, but there is no console content to log. If I manually repeat the steps the test is taking in Chrome, there are lines being written to Chrome devtools console, in fact 3 are written on page load. Why can't Dusk see those?
UPDATE 2
I found that if you remove '--headless' from the driver() method in DuskTestCase, the browser will be displayed during tests. You can then display the dev tools for that browser, and watch the console output live as the tests run. It is too fast to really be useful, and if there is an error the browser closes and you lose whatever was on the console anyway (unless there's a way to leave the browser open on failure?), but adding this here in case it is useful to someone!
There is apparently no way to get non-error console output from the browser.
There are other log types, but Chrome only supports browser (used by Dusk) and driver.
You'll probably have to use alerts. But screenshots don't contain alerts, so you have to get the text:
$browser->driver->switchTo()->alert()->getText()
You could also use something like document.write() and check the output on the screenshot.
It is possible. There's an answer here written in Python from 2014 that shows it's been possible since at least that long.
Override \Laravel\Dusk\TestCase::driver:
protected function driver()
{
$desired_capabilities = new DesiredCapabilities([
'browserName' => 'chrome',
'platform' => 'ANY',
]);
// the proper capability to set to get ALL logs stored
$desired_capabilities->setCapability('loggingPrefs', [
'browser' => 'ALL',
'driver' => 'ALL',
]);
// return the driver
return RemoteWebDriver::create(
'http://localhost:9515',
$desired_capabilities
);
}

How to debug and log own code on the server side of Meteor?

Never mind. The reason this did not work: I forgot to meteor reset so debugger did not get a chance to stop. Duh!
More info: I am using the method in the answer by Mason Chang to the related question, not the kill -s USR1 [proc_id] (where I could see the scripts, but not able to stop in the startup() function.). Also, I am using meteorite.
I am trying to debug the Meteor.startup(function ()) code on Meteor server side (i.e., under /server) with node-inspector, I have read this question, and following the answer to change run.js, but somehow, my own script for the startup function does not show up in the scripts section of Chrome.
How do I see my code here and set break points and stop at those points? BTW, the Meteor_debug() does not output anything to stdout, stderr, or node-inspector browser console. I also tried console.log() with no avail. How to enable logging on Meteor server side?
If it matters, I am on auth branch.
The code here is very simple (/server/bootstrap.js):
Meteor.startup(function () {
if (Logs.find().count() === 0) {
var data = [/*...some data...*/];
var timestamp = (new Date()).getTime();
Meteor._debug("timestamp: "+timestamp+", data.len: " + data.length);
debugger;
for (var i = 0; i < data.length; i++) {
data[i].timestamp = timestamp++;
var entry_id = Logs.insert(data[i]);
Meteor._debug("entry_id: "+ entry_id);
}
}
});
Now that I know how to do this, I will answer my own question so that we can keep this information (in details) here: (This is based on Mason Chang's answer to this question.)
Stop meteor execution.
Edit /usr/lib/meteor/app/meteor/run.js (or the corresponding run.js installed by meteorite in HOME//.meteorite/meteors/meteor/meteor/[LONG_HEX_CODE]/app/meteor):
change the line
[path.join(bundle_path, 'main.js'), '--keepalive']
to
['--debug-brk', path.join(bundle_path, 'main.js'), '--keepalive']
//--debug-brk makes the new thread break at the first line;
Add debugger statements as breakpoints in your server code;
Run node-inspector & in a server terminal. (google "node-inspector" to install it.)
Run meteor; (this will not have the debugger attached as there's no server thread yet, if you have no client window open.)
Refresh client browser window; (to initiate a server thread that will break at the first line, and be attached to node-inspector.)
Open a browser window at [SERVER:8080], your server code stops at first line (main.js in your [PROJECT_DIR]/.meteor/local/build);
Hit the RUN button on the debugger browser window; depending on where your debugger statements are, you may have to do some triggering actions in client browser window to run to the debugger breakpoints. (Note that if you wait too long to hit the RUN button, your client window may time out, and you have to refresh again.)
Now you can do the usual debugging stuff in server debugger window: step through, watch variables, execute in console, look at the stack, etc.
Edit: For logging on server side, you can use either Meteor._debug() and console.log(), they will show up in the terminal where you run meteor. On client side, these logging statements will output to the console of your browser's dev. tools.
On MacOSX, you can use with Chrome :
NODE_OPTIONS="--debug-brk" meteor
and in another terminal
node-inspector --debug-port=5858 --web-port=12345
Then connect Chrome to 127.0.0.1:12345/debug?port=5858
Otherwise with Webstorm, just create a Node.js Remote Debug configuration and run it :
Name : Meteor
Host : 127.0.0.1
Port 5858
Note that once the server has started, you need to press run in order for Meteor to load, and then pause in order to debug from the server console.

Node Inspector: Running Code - Not Just Stepping Through

What I want
I want to be able to run a whole script in node during debugging with node-inspector and Web Inspector. - I don't want to step through the individual JavaScript calls.
What I did
(My PowerShell Instructions)
PS C:\Users\JK> node-inspector
info - socket.io started
visit http://0.0.0.0:8080/debug?port=5858 to start debugging
...
==[In another PowerShell instance:]==
PS %> node —debug-brk myscript.js
debugger listening on port 5858
Why I want that
I'm writing a node script. In this script I console.log a lot of objects in order to be able to explore them during the debugging process. But the simple static textual console output isn't really nice - You can't fold and expand your object's properties or get the source code of a function:
(For Example)
{ [Function: Xy]
a: [Function],
b: 8.2,
c: [Function],
d: [Circular],
e: '2011-11-11' }
So I decided to use Web Inspector with node-inspector in order to get a good object browse experience (because of Web Inspector's nice output formatting).
Why I Don't Step Through
(Structure of My Script)
var fs = require('fs');
fs.readFile('myfile', function (err, data) {
if (err) {
throw err;
}
//My Script...
console.log(something);
});
The console.log() calls are executed in a callback function of
require('fs').readFile(). I won't get there just with "normal"
steps.
It's simply boring the click the Step buttons again and again.
My Questions
Is there a possibility to run a script without stepping through using the following Web Inspector user interface? (I don't want to use node —debug myscript.js instead of node —debug-brk myscript.js because then Inspector throws Error: connect ECONNREFUSED
Is node running with --debug port 5858? because the script runs too fast)
(Web Inspector Interface)
Or is there at least any other way to do what I described above (in the Why I want that section).
Thanks. -
(I hope it's clear what I wanted to ask. - Please write a comment if it isn't.)
You have a couple options.
Using --debug-brk:
Start your script, let it stop on the first line.
In the Script pane, click the line number inside the callback (line
4 in this
example).
Click "Continue" (the "|> icon above the right-hand panel).
Using --debug:
Add the line debugger; to your callback. This will stop the
debugger at that point. Click "|>" when you're done.

Resources