Protractor tests getting stuck in between while resolving promises when executing in Chrome - google-chrome

My protractor tests were working perfectly fine yesterday on Chrome Browser.
Today, it started failing consistently at a point where in I resolve a Promise. On debugging further, I found that if I commented this promise statement then it would hang at the next promise resolution statement.
There has been no change in the protractor scripts between yesterday and today. There has been some changes made by the developers in the Angular app under test but not major ones.
Can anyone help me point out what might be going wrong here?
Following is the code snippet. Its hanging at the promise resolution statement template.getTemplatesCount().then :-
mainMenu.clickTemplatesMenuOption();
templatePage.getTemplatesCount().then(count => {
console.log("Count of template card is:-"+count.toString());
templateCountBeforeInsert = count;
});
templatePage.openCreateTemplatePanel();
createTemplatePage.createTemplateWithoutDocument(templateName);
My protractor conf.json looks like this:-
exports.config = {
allScriptsTimeout: 30000000,
specs: [
'./e2e/TestPlan/*.ts'
],
capabilities: {
'browserName': 'chrome'
},
directConnect: true,
baseUrl: 'http://10.37.1.86:81/',
getPageTimeout: 120000,
framework: 'jasmine2',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 120000,
print: function () { }
}
Following are the versions of Tools I am using:-
Protractor:- 5.1.2
ChromeDriver:- `2.32
Chrome Browser :- 61.x

You should be passing a function to your .then() block, it should be this:
templatePage.getTemplatesCount().then((count) => {
console.log("Count of template card is:-"+count.toString());
templateCountBeforeInsert = count;
});

A simple way is add catch() as below:
templatePage.getTemplatesCount().then(count => {
console.log("Count of template card is:-"+count.toString());
templateCountBeforeInsert = count;
})
.catch(function(err){
console.log('getTemplatesCount error: ' + err);
});
If you get the error log, please check getTemplatesCount() inside.

Related

Cypress throwing SecurityError

I am currently running with Chrome 74 and trying to use Cypress to test a style-guide in my app. When I load up Cypress it throws this error:
SecurityError: Blocked a frame with origin "http://localhost:3000"
from accessing a cross-origin frame.
Please let me know if there is a solution to this!
I had tried to follow along with this:
https://github.com/cypress-io/cypress/issues/1951
But nothing has changed/worked for me. :(
My code is shown below: cypress/plugins/index.js
module.exports = (on, config) => {
on('before:browser:launch', (browser = {}, args) => {
// browser will look something like this
// {
// name: 'chrome',
// displayName: 'Chrome',
// version: '63.0.3239.108',
// path: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
// majorVersion: '63'
// }
if (browser.name === 'chrome') {
args.push('--disable-site-isolation-trials');
return args
}
if (browser.name === 'electron') {
args['fullscreen'] = true
// whatever you return here becomes the new args
return args
}
})
}
in my cypress/support/index.js
This will load the site before every test I run to save myself from having to write cy.visit in every test.
beforeEach(() =>{
cy.visit('http://localhost:3000/style-guide')
})
I had the very same issue yesterday and the answer from #jsjoeio in the cypress issue #1951 you've referenced in your question actually helped me.
So basically only thing I've done was to modify my cypress.json and add following value:
{
"chromeWebSecurity": false
}
You can disable security to overcome this issue.
Go to cypress.json file.
Write { "chromeWebSecurity": false } and save.
Run the test again.
I had exactly the same problem, I advise you to do as DurkoMatko recommends. Documentation chromeWebSecurity
But I encountered another problem with a link pointing to localhost in an iframe.
If you want to use a link in an iframe I recommend this :
cy.get('iframe').then((iframe) => {
const body = iframe.contents().find('body');
cy.wrap(body).find('a').click();
});
I have also faced this issue. My application was using service workers. Disabling service workers while visiting a page solved the issue.
cy.visit('index.html', {
onBeforeLoad (win) {
delete win.navigator.__proto__.serviceWorker
}
})
Ref: https://glebbahmutov.com/blog/cypress-tips-and-tricks/#disable-serviceworker
So, at least for me, my further problem was an internal one with tokens, logins, etc. BUT!
the code I posted for how the index in the plugin folder is correct to bypass the chrome issue. That is how you want to fix it!
Goto your cypress.json file.
Set chrome web security as false
{
"chromeWebSecurity": false
}
To get around these restrictions, Cypress implements some strategies involving JavaScript code, the browser's internal APIs, and network proxying to play by the rules of same-origin policy.
Acess your project
In file 'cypress.json' insert
{
"chromeWebSecurity": false
}
Reference: Cypress Documentation

ResizeObserver - loop limit exceeded

About two months ago we started using Rollbar to notify us of various errors in our Web App. Ever since then we have been getting the occasional error:
ResizeObserver loop limit exceeded
The thing that confuses me about this is that we are not using ResizeObserver and I have investigated the only plugin which I thought could possibly be the culprit, namely:
Aurelia Resize
But it doesn't appear to be using ResizeObserver either.
What is also confusing is that these error messages have been occuring since January but ResizeObserver support has only recently been added to Chrome 65.
The browser versions that have been giving us this error are:
Chrome: 63.0.3239 (ResizeObserver loop limit exceeded)
Chrome: 64.0.3282 (ResizeObserver loop limit exceeded)
Edge: 14.14393 (SecurityError)
Edge: 15.15063 (SecurityError)
So I was wondering if this could possibly be a browser bug? Or perhaps an error that actually has nothing to do with ResizeObserver?
You can safely ignore this error.
One of the specification authors wrote in a comment to your question but it is not an answer and it is not clear in the comment that the answer is really the most important one in this thread, and the one that made me comfortable to ignore it in our Sentry logs.
This error means that ResizeObserver was not able to deliver all observations within a single animation frame. It is benign (your site will not break). – Aleksandar Totic Apr 15 at 3:14
There are also some related issues to this in the specification repository.
It's an old question but it still might be helpful to someone. You can avoid this error by wrapping the callback in requestAnimationFrame.
For example:
const resizeObserver = new ResizeObserver(entries => {
// We wrap it in requestAnimationFrame to avoid this error - ResizeObserver loop limit exceeded
window.requestAnimationFrame(() => {
if (!Array.isArray(entries) || !entries.length) {
return;
}
// your code
});
});
If you're using Cypress and this issue bumps in, you can safely ignore it in Cypress with the following code in support/index.js or commands.ts
const resizeObserverLoopErrRe = /^[^(ResizeObserver loop limit exceeded)]/
Cypress.on('uncaught:exception', (err) => {
/* returning false here prevents Cypress from failing the test */
if (resizeObserverLoopErrRe.test(err.message)) {
return false
}
})
You can follow the discussion about it here.
As Cypress maintainer themselves proposed this solution, so I believe it'd be safe to do so.
We had this same issue. We found that a chrome extension was the culprit. Specifically, the loom chrome extension was causing the error (or some interaction of our code with loom extension). When we disabled the extension, our app worked.
I would recommend disabling certain extensions/addons to see if one of them might be contributing to the error.
For Mocha users:
The snippet below overrides the window.onerror hook mocha installs and turns the errors into a warning.
https://github.com/mochajs/mocha/blob/667e9a21c10649185e92b319006cea5eb8d61f31/browser-entry.js#L74
// ignore ResizeObserver loop limit exceeded
// this is ok in several scenarios according to
// https://github.com/WICG/resize-observer/issues/38
before(() => {
// called before any tests are run
const e = window.onerror;
window.onerror = function(err) {
if(err === 'ResizeObserver loop limit exceeded') {
console.warn('Ignored: ResizeObserver loop limit exceeded');
return false;
} else {
return e(...arguments);
}
}
});
not sure there is a better way..
add debounce like
new ResizeObserver(_.debounce(entries => {}, 200);
fixed this error for me
The error might be worth investigating. It can indicate a problem in your code that can be fixed.
In our case an observed resize of an element triggered a change on the page, which caused a resize of the first element again, which again triggered a change on the page, which again caused a resize of the first element, … You know how this ends.
Essentially we created an infinite loop that could not be fitted into a single animation frame, obviously. We broke it by holding up the change on the page using setTimeout() (although this is not perfect since it may cause some flickering to the users).
So every time ResizeObserver loop limit exceeded emerges in our Sentry now, we look at it as a useful hint and try to find the cause of the problem.
In my case, the issue "ResizeObserver - loop limit exceeded" was triggered because of window.addEventListener("resize" and React's React.useState.
In details, I was working on the hook called useWindowResize where the use case was like this const [windowWidth, windowHeight] = useWindowResize();.
The code reacts on the windowWidth/windowHeight change via the useEffect.
React.useEffect(() => {
ViewportService.dynamicDimensionControlledBy(
"height",
{ windowWidth, windowHeight },
widgetModalRef.current,
{ bottom: chartTitleHeight },
false,
({ h }) => setWidgetHeight(h),
);
}, [windowWidth, windowHeight, widgetModalRef, chartTitleHeight]);
So any browser window resize caused that issue.
I've found that many similar issues caused because of the connection old-javascript-world (DOM manipulation, browser's events) and the new-javascript-world (React) may be solved by the setTimeout, but I would to avoid it and call it anti-pattern when possible.
So my fix is to wrap the setter method into the setTimeout function.
React.useEffect(() => {
ViewportService.dynamicDimensionControlledBy(
"height",
{ windowWidth, windowHeight },
widgetModalRef.current,
{ bottom: chartTitleHeight },
false,
({ h }) => setTimeout(() => setWidgetHeight(h), 0),
);
}, [windowWidth, windowHeight, widgetModalRef, chartTitleHeight]);
One line solution for Cypress. Edit the file support/commands.js with:
Cypress.on(
'uncaught:exception',
(err) => !err.message.includes('ResizeObserver loop limit exceeded')
);
https://github1s.com/chromium/chromium/blob/master/third_party/blink/renderer/core/resize_observer/resize_observer_controller.cc#L44-L45
https://github1s.com/chromium/chromium/blob/master/third_party/blink/renderer/core/frame/local_frame_view.cc#L2211-L2212
After looking at the source code, it seems in my case the issue surfaced when the NotifyResizeObservers function was called, and there were no registered observers.
The GatherObservations function will return a min_depth of 4096, in case there are no observers, and in that case, we will get the "ResizeObserver loop limit exceeded" error.
The way I resolved it is to have an observer living throughout the lifecycle of the page.
Managed to solve this in React for our error logger setup.
The Observer error propagates to the window.onerror error handler, so by storing the original window.onerror in a ref, you can then replace it with a custom method that doesn't throw for this particular error. Other errors are allowed to propagate as normal.
Make sure you reconnect the original onerror in the useEffect cleanup.
const defaultOnErrorFn = useRef(window.onerror);
useEffect(() => {
window.onerror = (...args) => {
if (args[0] === 'ResizeObserver loop limit exceeded') {
return true;
} else {
defaultOnErrorFn.current && defaultOnErrorFn.current(...args);
}
};
return () => {
window.onerror = defaultOnErrorFn.current;
};
}, []);
I had this issue with cypress tests not being able to run.
I found that instead of handling the exception the proper way was to edit the tsconfig.json in a way to target the new es6 version like so:
{
"extends": "../tsconfig.json",
"compilerOptions": {
"baseUrl": "../node_modules",
"target": "es5", --> old
"target": "es6", --> new
"types": ["cypress", "#testing-library/cypress"],
"sourceMap": true
},
"include": [
"**/*.ts"
]
}

nothing happens after .url() calling

I have the following nightwatch test:
module.exports = {
'Set Initial Dataset' : function (browser) {
browser
.url('http://localhost/nightwatch/load-initial-dataset')
.end()
}
}
When I execute it the browser is opened and the url is loaded, but when the loading is ended it doesn't close the browser to begin the next test.
The test worked 1 month ago... I updated nightwatch to the nigthwatch latest version (v0.9.8), downloaded selenium-server-standalone-3.0.1.jar, chromedriver 2.25 and Chrome 54.0.2840.87
My Nigthwatch.js is
module.exports = {
src_folders: ['./tests'],
output_folder: './results',
selenium: {
start_process: true,
server_path: './selenium-server-standalone-3.0.1.jar',
log_path: './results',
host: '127.0.0.1',
port: 4444,
"cli_args" : {
"webdriver.chrome.driver" : "./osx/chromedriver"
}
},
test_settings: {
default: {
waitForConditionPollInterval: 1,
selenium_host: '127.0.0.1',
selenium_port: 4444,
screenshots: {
enabled: true,
path: './results/screenshots'
},
desiredCapabilities: {
browserName: 'chrome',
javascriptEnabled: true,
acceptSslCerts: true
}
}
}
};
I tried to launch this test and I have the same problem: https://github.com/nightwatchjs/nightwatch/blob/master/examples/tests/google.js (the browser stay opened at the url and nothing from the terminal)
I have no particular problem when I ran my test with safari.
Thx
From a first glance it looks like your test doesn't actually perform any assertions and thus doesn't actually 'test' for anything. This might be confusing the test runner.
My other theory is that the waitForConditionPollInterval setting is too low. 1 millisecond seems a bit overkill.
Two things to do from here:
Perform an actual assertion inside your test. For example, after navigating to the page try this...
Example:
module.exports = {
'Set Initial Dataset' : function (browser) {
browser
.url('http://localhost/nightwatch/load-initial-dataset')
.assert.title('Some Title')
.end()
}
}
Remove the waitForConditionPollInterval setting and see if that helps. If it does, try setting it to something a little more sane, like 100ms, and check if the test still hangs.
My experience has been that selenium hangs when a verification isn't performed. You're not getting any output because navigating isn't a "verification" step.
While you can check for the page title to confirm that you've hit the correct url, I would consider that a bit brittle. If the page title changes for any reason it would fail your test, even if the URL you navigated to was correct. To test that you're hitting the correct url, try using .urlContains(); instead.
Example:
module.exports = {
'Set Initial Dataset' : function (browser) {
browser
.url('http://localhost/nightwatch/load-initial-dataset')
.verify.urlContains('/load-initial-dataset')
.end();
}
}
You're also missing the semi-colon after .end(); which might not be telling nightwatch the test case is actually complete.
Maybe try that, too.

gulp-tslint not printing linting erros on console

Hi I am trying to run a tslint task using gulp on a small angular 2 app but it does not seem to work.Here is what I have so far:
This are is my gulpFile:
const gulp = require('gulp');
const tslint = require('gulp-tslint');
gulp.task('tslint', () => {
return gulp.src("app/**/*.ts")
.pipe(tslint({ configuration: "tslint.json" }))
.pipe(tslint.report('verbose'));
});
To be absolutely sure I get errors I have set in tslist.json the following option: "max-line-length": [ true, 5 ]
When I run this task I get the following:
[10:29:54] Using gulpfile ~\Desktop\InovationWeek\InovationWeek\Gulpfile.js
[10:29:54] Starting 'tslint'...
Process terminated with code 1.
It does not say anything about what linting errors it found just that the process terminated with code 0.
What am I doing wrong?
I had a similar issue where tslint was running into a problem with my configuration and was not actually performing any linting.
This resulted in the process teminating with code 1, but not returning any linting errors which seems to be same problem you are seeing.
My solution was to add a bit of error handling in gulp:
gulp.task("tslint", function() {
return gulp.src(config.tsSrc)
.pipe(tslint({
formatter: "verbose",
configuration: "tslint.json"
}))
.on('error', printError)
.pipe(tslint.report());
});
// print the error out
var printError = function(error) {
console.log(error.toString());
}
This meant that the configuration error that cause tslint not to run was written to the console and I was able to fix my configuration.

Why doesn't chrome.bluetooth work in a Chrome App?

Following the instructions on the Chrome App Create Your First App page, I was able to create a simple app that I can run from More tools > Extensions in Chrome.
I then added "bluetooth": {} to the manifest, and added the following JS file to my code:
console.log('chrome.bluetooth');
console.log(chrome.bluetooth);
chrome.bluetooth.onAdapterStateChanged.addListener(function (state) {
console.log('onAdapterStateChanged callback');
console.log(state);
});
chrome.bluetooth.onDeviceAdded.addListener(function (device) {
console.log('onDeviceAdded callback');
console.log(device);
});
chrome.bluetooth.getAdapterState(function (adapterInfo) {
console.log('getAdapterState callback');
console.log(adapterInfo);
});
chrome.bluetooth.getDevices(function (deviceInfos) {
console.log('getDevices callback');
console.log(deviceInfos);
});
console.log('startDiscovery method call');
chrome.bluetooth.startDiscovery(function () {
console.log('startDiscovery callback');
console.log(chrome.runtime.lastError);
});
However, it does not work.
I get the following output to the console; most notably the startDiscovery error at the end:
What would cause this to fail and why? How can I fix it?
I should note that I am using Chrome on Windows 7, if that affects anything.
Thank you.