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");
Related
I try to upload a file in ProTractor to the application, which is developed in Angular with Electron.
To do it manually I need to click on the "Browse" button and then select a file in the windows dialog "Open".
I managed already the part for providing of the path to the file and click on "Open" button on the dialog by using of AutoIt
var autoIt = require('autoit');
autoIt.Init();
autoIt.WinActivate("Open");
autoIt.WinWait("Open");
autoIt.ControlSetText("Open", "", "1148", appPath);
autoIt.ControlClick("Open", "", "1");
But this part of the code will be not executed after click on the "Browse" button
element(by.id('browseText')).click();
I guess that ProTractor waits for angular or for page loading, but because after clicking on the button the windows dialog is opened, the execution of further code is blocked. Also afterward I couldn't just output something in the console.
Is there an option to disable wait for page loading and to perform the action immediately after the click?
Unfortunately, the disabling of waiting for Angular didn't help as well as synchronization ignoring
browser.waitForAngularEnabled(false);
browser.ignoreSynchronization = true;
Thank you in advance for your support.
UPDATED
The problem is in the timing because when I try to execute the small following code
browser.waitForAngularEnabled(false);
element(by.id('browseText')).click()
.then(function () {
console.log("clicked");
});
browser.sleep(5000)
.then(function () {
console.log("5 sec are over!");
}); // wait 5 sec
browser.sleep(3000);
console.log("End");
The following happens:
Firstly the "End" will be added to the console without waiting for 3 seconds.
Afterward, the dialog will be opened, that means that the button was clicked
And at the end, the test will be failed with Error "function timed out, ensure the promise resolves within 90000 milliseconds".
Here is the output of this code:
[09:37:14] I/launcher - Running 1 instances of WebDriver
[09:37:14] I/direct - Using ChromeDriver directly...
..End
..F
Failures:
1) Scenario: Add an application # features\tst_General.feature:10
V Before # features\steps\DataGrid.js:20
V Before # features\steps\General.js:25
V When The "bounce" application has been added # features\steps\General.js:65
V After # features\steps\General.js:29
× After # node_modules\protractor-cucumber-framework\lib\resultsCapturer.js:2
5
Error: function timed out, ensure the promise resolves within 90000 milli
seconds
at Timeout._onTimeout (C:\Users\10050296\Documents\workspace\sm-protr
actor-automation\node_modules\cucumber\src\user_code_runner.js:61:18)
at ontimeout (timers.js:498:11)
at tryOnTimeout (timers.js:323:5)
at Timer.listOnTimeout (timers.js:290:5)
1 scenario (1 failed)
1 step (1 passed)
1m30.217s
Let's be clear.
This is work 100%:
browser.waitForAngularEnabled(false);
Protractor part, as I understand, also work. The Browser button is clicked.
So, the issue in the Autoit part. The question is - "How to run Autoit?"
Just add sleep to check is it waiting problem on the Autoit side:
element(by.id('browseText')).click();
browser.sleep(5000); // wait 5 sec
...
autoit code
...
If it works, so the issue in Autoit waiting.
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.
I have to run some tests agains a live site.
I have to pretty much just make tasks to wait on a website to time out (15 minutes), then run another task, once that has passed.
the longest i got it to wait is 26.6 seconds (26600 ms) on firefox, and about 30 on chrome.
I get the following error :
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
so basically i need adjust the specified timeout from jasmine to run this:
browser.get('www.page.com');
browser.sleep(900000);
browser.doSomethingElse();
This is a jasmine timeout happening in your case. You need to tell Jasmine that it's okay it takes time. You can set the timeout globally in jasmineNodeOpts in your config:
jasmineNodeOpts: {
defaultTimeoutInterval: 200000,
}
Or, you can also set it on a spec level (example here).
beforeEach(function(){
browser.waitForAngular();
jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000000;
});
I have this test code:
element(by.cssContainingText('a[ng-click="select()"]', 'Visual')).click()
browser.sleep(1000)
expect(element.all(by.tagName('angular-chart')).count()).toEqual(1);
But it hangs until timeout reach and then shows:
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
I suppose I need to wait for the content to load somehow then run the test?
If I replace the expect construct with the one below, it passes:
expect(true).toEqual(true)
Try this:
element(by.cssContainingText('a[ng-click="select()"]', 'Visual')).click().then( function(){
expect(element.all(by.tagName('angular-chart')).count()).toEqual(1);
});
Most calls in protractor returns a promise.
http://www.protractortest.org/#/api?view=webdriver.WebElement.prototype.click
Let's try adding an explicit wait to wait for the angular-chart element to become present:
var EC = protractor.ExpectedConditions;
element(by.cssContainingText('a[ng-click="select()"]', 'Visual')).click()
var chart = element(by.tagName('angular-chart'));
browser.wait(EC.presenceOf(chart), 10000);
You might also look into increasing jasmine timeout intervals.
I am doing test-driven development with Qunit: when creating a new function, I write tests for it, create the function, reload the page, and if all the tests pass I move on... Whilst this works fine at the beginning, it starts to become a time consuming process after a while as all the tests take several seconds to run, and that's the time I have to wait for every time I refresh my browser.
In an attempt to workaround that problem, I thought about introducing Zombie.js to perform head-less testing: the idea is to have Zombie.js continuously check the webpage (e.g. $ watch -n1 "node queryTheWebpage.js") and report to me Qunits's results while coding (once in a while, as Zombie.js isn't a "real" browser, I would open up a browser and check the page manually to validate).
So far here is what I have for my node/Zombie piece of code:
browser.visit("http://localhost/mywebpage.html", function () {
var qunit_tests = browser.query('body');
console.log(qunit_tests.innerHTML);
});
In the console output I do see the Qunit tests container <ol id="qunit-tests"></ol> but it is empty which means when the visit callback function is called, the tests haven't run.
I've tried to use the wait function to wait for the tests to run, but unsuccessfully:
function waitForQunitToEnd(window) {
var last = window.document.querySelector('selectorOfMyLastTest');
var first_failed = window.document.querySelector('li.failed');
return (last || first_failed);
}
browser.visit("http://localhost/mywebpage.html", function () {
browser.wait(waitForQunitToEnd, function() {
var qunit_tests = browser.query('body');
console.log(qunit_tests.innerHTML); // still gives me empty <ol id="qunit-tests"></ol>
});
});
I tried to play with the waitFor option (e.g. set to 5000ms) but that didn't help either.
Q1: Is what I'm trying to do making sense, or is there a much simpler way of doing something similar?
Q2: Do you know how I could get Zombie.js to wait for the Qunit tests to run?
I don't know if it will help you but look this : http://api.qunitjs.com/QUnit.done/