Always getting 'Error: timeout of 2000ms exceeded' with Selenium - javascript

Good morning,
I am currently learning how to drive Selenium with javascript (using mocha). I created a really basic test that is giving me a lot of trouble at runtime. Whenever I run the test a new instance of chrome is created and the browser displays. When the browser initially comes up it places "data:," in the URL box then proceeds to google.com. I then get the following error back:
$ mocha test
Array
#indexOf()
✓ should return -1 when the value is not present!
Google Search
1) should work
1 passing (2s)
1 failing
1) Google Search should work:
Error: timeout of 2000ms exceeded
at null.<anonymous> (/usr/local/lib/node_modules/mocha/lib/runnable.js:157:19)
at Timer.listOnTimeout [as ontimeout] (timers.js:112:15)
Here is the test itself:
var assert = require('assert'),
test = require('selenium-webdriver/testing'),
webdriver = require('selenium-webdriver'),
chrome = require('selenium-webdriver/chrome');
test.describe('Google Search', function() {
test.it('should work', function() {
var chromeOptions = new chrome.Options();
chromeOptions.addArguments(['test-type']);
var driver = new webdriver.Builder().withCapabilities(chromeOptions.toCapabilities()).build();
driver.get('http://www.google.com');
driver.findElement(webdriver.By.name('q')).sendKeys('webdriver');
driver.findElement(webdriver.By.name('btnG')).click();
driver.wait(function() {
return driver.getTitle().then(function(title) {
return title === 'webdriver - Google Search';
});
}, 1000);
driver.quit();
});
});

The error message you get looks like a Mocha timeout to me. The normal way to set a timeout in Mocha is:
it("foo", function () {
this.timeout(value);
...
});
where value is whatever value you want (in ms). A value of 0 turns off Mocha's timeouts. The default is 2000ms.

IF it fail somewhere in particular consistently maybe you should be considering calling driver.Manage().Timeouts().
ImplicitlyWait() doesn't actually wait like a Thread.sleep() does, it just sets the drivers maximum wait time for implicit waits. Just calling it once at the start of your code (with 20 second parameter passed in) is sufficient. Read up on ImplicitlyWait and the WebDriverWait class.
As far as I remember (when I had to used) this is caused because you don't get the response in the expected/by default time.

Related

Testing a non angular website using Protractor

I am trying to test my website which is a non angular website through Protractor. My code is:
describe("Supplier Portal: Login ", function () {
//ui.setSmallScreenSize();
// ui.testLogger(100);
it("test", co.wrap(function* () {
browser.ignoreSynchronization = true;
yield browser.driver.get("https://cit.supplier.ext.here.com/");
yield element(by.xpath("//*[#id=\"rnav\"]/li[2]/a")).click();
var elmOK = element(by.xpath( "//*[#id=\"sign-in-email\"]"));
browser.driver.wait(protractor.until.elementIsVisible(elmOK.getWebElement()))
}));
});
But when I try to execute the code I got the following error:
Failed: No element found using locator: By(xpath, //*[#id="sign-in-email"])
But the element is there on the website.
Please advice what I'm doing wrong
Since you are working on a non-angular site and using browser.ignoreSynchronization = true, Protractor will not wait for the angular variable to become available, so it starts firing tests off because it thinks the app is ready, more info here.
You need to manipulate the Control Flow by using Expected Conditions so Protractor knows that it is waiting for something. This will make your tests more consistent and reliable.
A few examples to guide you:
Wait for an element to be loaded/present in the DOM:
var EC = protractor.ExpectedConditions;
var ele = element(by.css('div.class'));
browser.wait(EC.presenceOf(ele), 5000);
The 5000 parameter value I passed in says wait a maximum of 5 seconds, if not present in 5 seconds then fail.
Wait for an element visible:
browser.wait(EC.visibilityOf(ele), 5000);
Wait for an element to be clickable:
browser.wait(EC.elementToBeClickable(ele), 5000);
Again, it's important to note that these are implicit waits and they will wait a maximum of the time parameter provided. It is not a guaranteed amount of time to wait, they fire off ASAP when they find the element you told it to wait for.

Protractor opens and closes the chrome browser immediately without running the full scenario

I have written one scenario to test the application using protractor. My application starts with login page which is non-angular page then, after logging in moves on to the angular page.
Below is the javascript code snippet that i used to run:
var chai = require('chai');
var chaiAsPromised = require('chai-as-promised');
chai.use(chaiAsPromised);
var expect = chai.expect;
var myStepDefinitionsWrapper = function () {
this.Given(/^that I login with valid user credentials$/, function (callback) {
console.log("I'm in before URL");
browser.driver.get('http://localhost:8000/#');
console.log("I'm in after URL");
browser.driver.wait(function() {
console.log("I'm in Wait");
return browser.driver.isElementPresent(by.xpath("//input[contains(#placeholder,'Username')]"));
},10000);
browser.driver.findElement(by.xpath("//input[contains(#placeholder,'Username')]")).then(function(username) {
console.log("I'm in Username");
username.sendKeys("welby");
});
browser.driver.findElement(by.xpath("//input[contains(#type,'password')]")).then(function(password) {
console.log("I'm in Password");
password.sendKeys("asdf");
});
browser.driver.findElement(by.xpath("//button[#type='submit']")).click();
console.log("I'm after click");
callback();
});
this.When(/^I click perform button in Tasks window$/, function (callback) {
browser.waitForAngular();
element(by.xpath("//*[text()[contains(.,'Smith, Sally')]]/following::td[2]/button[text()='Perform']")).click();
console.log("Clicked Perform");
callback();
});
}
Output:
"C:\Program Files (x86)\JetBrains\WebStorm 10.0.4\bin\runnerw.exe" "C:\Program Files (x86)\nodejs\node.exe" node_modules\protractor\lib\cli.js E2E\protractor-conf.js Using the selenium server at http://127.0.0.1:4444/wd/hub [launcher] Running 1 instances of WebDriver
- I'm in before URL
- I'm in after URL
- I'm after click
- Clicked Perform
1 scenario (1 passed) 3 steps (3 passed)
[launcher] 0 instance(s) of WebDriver still running [launcher] chrome #1 passed
Process finished with exit code 0
Judging by the style of the code in your question you appear to be using Cucumber.js for your test runner. In this case then, you should be able to omit the callback parameter to your step definitions and simply return a promise:
this.Given(/^that I login with valid user credentials$/, function () {
// The rest of the code remains the same.
return browser.driver.findElement(by.xpath("//button[#type='submit']")).click();
});
And:
this.When(/^I click perform button in Tasks window$/, function () {
browser.waitForAngular();
return element(by.xpath("//*[text()[contains(.,'Smith, Sally')]]/following::td[2]/button[text()='Perform']")).click();
});
The capability of Cucumber.js to use promises is documented here.
Protractor is built on Selenium. I strongly suggest reading the entire "Understanding the API" section of the Selenium documentation so that you understand how the JavaScript version of Selenium uses and sequences promises.
The reason your code is not working right now is that by calling callback() like you do you are telling Cucumber.js that your step is finished before Protractor (and Selenium) has actually performed the actions you want. When you return a promise, Cucumber.js waits until the promise is resolved or fails before moving on.

Protractor test failing with angular-growl-v2

I'm using angular-growl-v2 notifications in my app.
They work ok, the problem comes on my protractor tests. I have to use a TTL (around 6 seconds) as it is a requirement. Then I have the following test:
it('should send a request and notify the user about the result',function(){
detailPage.verifyEmailtButton.click().then(function(){
var expectedDiv = element(by.css('.alert-success'));
expect(expectedDiv).toBeDefined();
});
});
But it is always throwing an error:
NoSuchElementError: No element found using locator: By.cssSelector(".alert-success")
This does not happens when the TLL is -1.
Someone can help here? Thanks in advance.
angular-growl-2 uses $timeout, which doesn't play nicely with protractor: protractor waits for the timeout to end before it completes its sync with angular process.
So by the time it reaches your expect call, the timeout has elapsed and the alert is no longer there. Check out the Waiting for page synchronization section of this doc:
https://github.com/angular/protractor/blob/master/docs/timeouts.md
(This page relates to timeouts, which you don't appear to be experiencing, but since the default timeout is 11 seconds, it could well be that the entire process, including your 6 second TTL, takes place before a timeout happens)
There's a PR to angular-growl-v2 to use $interval instead of $timeout, but its currently waiting for tests:
https://github.com/JanStevens/angular-growl-2/pull/85
Explicitly wait for the alert to be present after clicking the button:
detailPage.verifyEmailtButton.click();
var EC = protractor.ExpectedConditions;
var expectedDiv = element(by.css('.alert-success'));
browser.wait(EC.presenceOf(expectedDiv), 10000, "No alert present");

AngularJS Protractor element by.model can't find element?

using the element(by.model()) syntax to find a field and input text.
element(by.model('sample_ad.id')).sendKeys('batman');
gets the exception from chromedriver:
Stacktrace:
Error: Timed out waiting for Protractor to synchronize with the page after 11 seconds
at Error (<anonymous>)
==== async task ====
WebDriver.executeScript()
at Protractor.waitForAngular (/Users/jon/dev/project_name/node_modules/protractor/lib/protractor.js:278:22)
at Protractor.findElement (/Users/jon/dev/project_name/node_modules/protractor/lib/protractor.js:427:8)
at Object.elementFinder.(anonymous function) [as sendKeys] (/Users/jon/dev/project_name/node_modules/protractor/lib/protractor.js:62:21)
at null.<anonymous> (/Users/jon/dev/project_name/test/e2e/features/somedirectiveSpec.js:24:39)
at /Users/jon/dev/project_name/node_modules/protractor/jasminewd/index.js:54:12
==== async task ====
at null.<anonymous> (/Users/jon/dev/project_name/node_modules/protractor/jasminewd/index.js:53:12)
at null.<anonymous> (/Users/jon/dev/project_name/node_modules/protractor/node_modules/minijasminenode/lib/async-callback.js:45:37)
at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)
Not sure why this is breaking, but Protractor seems very fragile right now... I have no issues using the browser object to find elements, input text, etc...
Any help would be appreciated
EDIT: if I change the line to the following, I am able to interact with the text field.
browser.driver.findElement(protractor.By.id('sample_ad_id')).sendKeys('batman');
hopefully this will help others....
Found this on github (see references link). The issue I believe is a script not returning, thus the sendKeys didn't work. Before interacting with the dom using protractor objects (element, ptor, etc), set this variable:
browser.ignoreSynchronization = true;
The reason the following works is because it doesn't rely on async calls, its just directly interacts with the dom and inserts the keys into the input field.
browser.driver.findElement(protractor.By.id('sample_ad_id')).sendKeys('batman');
The reason my call didn't work (I believe) is because there was an async call that didn't return in time.
element(by.model('sample_ad.id')).sendKeys('batman');
references:
https://github.com/angular/protractor/issues/325
See https://github.com/angular/protractor/blob/master/docs/faq.md#my-tests-time-out-in-protractor-but-everythings-working-fine-when-running-manually-whats-up
for more information on timeouts.
It looks like your test is timing out. The default timeout for protractor is 11 seconds.
Try setting a different timeout for this test:
it('should override timeout', function() {
// Timeout of 30 seconds.
element(by.model('sample_ad.id')).sendKeys('batman');
}, 30000)
You can also override the timeout for all your tests in the protractor configuration file. See this sample config file:
https://github.com/andresdominguez/protractor-meetup/blob/master/protractor-config.js#L19
// Inside the protractor config file.
onPrepare: function() {
// Override the timeout for webdriver.
var ptor = protractor.getInstance();
ptor.driver.manage().timeouts().setScriptTimeout(60000);
}

Nodeunit test hangs for async db call ORMnomnom

I am trying to write unit test for async db calls. I'm using NodeJS with ORMnomnom package installed as orm db access and nodeunit for unit testing.
But it hang for this simple test:
Here is code test\test1.js
modelsdb = require('../model/model_db')
exports['test db'] = function (test) {
test.expect(1);
console.log('test db');
modelsdb.MyTable.objects.all( function (err, data) {
test.ok(true, "this assertion should pass");
test.done();
console.log('test must finish here!');
});
}
exports.testSomething = function(test){
console.log('testSomething');
test.expect(1);
test.ok(true, "this assertion should pass");
test.done();
};
When I run this test all assertions passed, I see my messages in console: 'test db' 'test must finish here!' 'testSomething' (means that test.done() reached inside callback function) but test doesn't finish. I need to stop it manually, get: 'Process finished with exit code 1'. If I change to test.ok(false,""), so I get AssertionError but test doesn't finish either. If I remove 'test db' and left only testSomething function - test finished as expected, all assertion passed.
I also try testpilot package which is based on nodeunit.
It gives
test1
FAIL : test db
an error occurred during test:
Error: timed out waiting for test
Any suggestions?
Thanks.
Add a tearDown method to your exports to close mongoose's connection pool. As long as it's still open the test won't exit.
You don't show how you're opening your mongoose connection, but something like this:
exports.tearDown = function (callback) {
mongoose.disconnect(callback);
};
I'm having a similar issue with nodeunit and q/mongoose - There is a bug that has been opened for it. I've tried to do the terrible process.exit(0) after calling test.done(), but any logging that is pending may not be flushed, so it isn't ideal. Ended up having to call process.exit(0) in a timeout block.

Categories