Protractor: inconsistent test reports? - protractor

Testing an angular app, the test are sometimes passing and sometimes failing...
My test cases look like:
it('test-1: should has main button', function () {
expect(page.demoButton).not.toBeUndefined();
});
it('test-2: should open modal on click secondary button', function () {
page.demoButton.click().then(function () {
page.SecondaryButton.click().then(function() {
expect(page.Modal).not.toBeUndefined();
});
});
});
it('test-3: should open modal with correct text', function () {
page.demoButton.click().then(function () {
page.SecondaryButton.click().then(function() {
expect(page.Modal.text.getText()).toEqual('Are you sure to cancel
this?');
});
});
});
If I run the test, sometimes the tests are passed sometimes some of them get failed..
Most of the time error is like: No element found using locator: By.cssSelector(".myButton"). or Cannot read property 'getText' of undefined
Thank you in advance!

I fixed that issue with using:
browser.waitForAngular();
As I see that issue occurs with getText and click events, So:
it('test-2: should open modal on click secondary button', function () {
page.demoButton.click().then(function () {
browser.waitForAngular();
page.SecondaryButton.click().then(function() {
browser.waitForAngular();
expect(page.Modal.text.getText()).toEqual('Are you sure to cancel
this?');
});
});
});
was the solution.

Related

protractor typescript closing a popup in a non angular application

I'm working on protractor/typescript in non angular application, using handlers & trying to verify and close a popup message. Here is the code, but this does not looks like closing the popup window. Maybe the click is not really clicking the okbutton.
Here is the code:
Then(/^user validate login error message and ok to close the popup message and return to main page$/, async () => {
browser.getAllWindowHandles().then(function (handels) {
// browser.switchTo().window(handels[1]).then(function () {
return browser.wait(function () {
// return browser.isElementPresent(element(by.xpath('//*.....message')))
// }, 40000).then(function (text) {
// console.log("returned text is " + text);
// expect(text).to.equal('Error Signing In');
// browser.sleep(5000);
browser.getAllWindowHandles().then(function (handels) {
browser.switchTo().window(handels[1]).then(function () {
element(by.xpath('//*.....okbutton')).click();
})
browser.switchTo().window(handels[0]).then(function () {
expect(browser.getTitle()).to.eventually.equal('login page');
//browser.getTitle().then(function (title) {
// console.log(title);
//})
})
})
})
Can you help ?
Thank you
Sean,
Can you try sending escape key on the popup(assuming your browser.switchTo().window(handels[1]).then)is working as expected : Try sending escape key to the control
element(by.xpath('//*.....okbutton')).sendKeys(protractor.Key.ESCAPE);

e2e Testing in protractor. SignIn

I am not able to redirect on required page on sigIn page. It clicks on button but not giving the output as required. Not able to hit the server for further process after signin process.Plz help
describe("it should be able to run on different events as defined", function(){
it("should be get on browser", function(){
browser.get("http://www.localhost:8100/#/signin");
expect(browser.getCurrentUrl()).toEqual("http://www.localhost:8100/#/signin");
browser.sleep(2000);
element(by.css("[ng-model='user.email']")).sendKeys('ash.mat23.23#gmail.com');
element(by.css("[ng-model='user.email']")).getAttribute('placeholder').then(function(element){
expect(element).toEqual('Email');
browser.sleep(2000);
});
element(by.css("[ng-model='user.password']")).sendKeys('123456');
element(by.css("[ng-model='user.password']")).getAttribute('placeholder').then(function(element){
expect(element).toEqual('Password (at least 6 characters)');
browser.sleep(2000);
});
element(by.id('signin_submit_btn'));
browser.driver.actions().sendKeys(protractor.Key.ENTER).perform();
browser.sleep(5000);
});
});
Are you sure it's clicking the button properly? To my mind the line that reads:
element(by.id('signin_submit_btn'));
Should have a click event on the end, i.e. it should read:
element(by.id('signin_submit_btn')).click();
I'm not completely sure what you are asking. It looks to me that you are preforming all actions at the same time. You should make sure filling in the username and password is done before clicking on submit or pressing enter. I hope this helps:
describe("it should be able to run on different events as defined", function () {
it("should be get on browser", function () {
browser.get("http://www.localhost:8100/#/signin").then(() => {
expect(browser.getCurrentUrl()).toEqual("http://www.localhost:8100/#/signin");
Promise.all([
$("[ng-model='user.email']").sendKeys('ash.mat23.23#gmail.com'),
$("[ng-model='user.password']").sendKeys('123456'),
$("[ng-model='user.email']").getAttribute('placeholder').then(function (element) {
expect(element).toEqual('Email');
}),
$("[ng-model='user.password']").getAttribute('placeholder').then(function (element) {
expect(element).toEqual('Password (at least 6 characters)');
})
]).then(()=>{
$('#signin_submit_btn').click(); // or browser.driver.actions().sendKeys(protractor.Key.ENTER).perform();
})
})
});
});

Clicking buttons after a modal event with protractor

I'm having a problem clicking on a button that is on a modal or on a page after a modal is supposed to have been closed. Here is my experience:
I have a modal i'm dealing with. I create the actions to have it displayed. I have a wait function that waits for one of the modal's items to be "clickable" (This allows it to be both present and displayed). I then verify the text on the modal.
All of the above is successful. However, when I try to click on the button to close it, I'm getting an error stating that another element on the page would be clickable. I'm thinking I need to disable angular (and CSS?) animation. Is this answer still relevant to the latest version of protractor?
How to disable animations in protractor for angular js application
The problem I have with the above answer is that typescript didn't recognize the "angular" object.
I also see this question: Click on a button in a Modal Window - Protractor But the "answer" is to sleep for 2 seconds. Not my desired solution (if at all possible).
In any case, I found a way to reproduce what I'm talking about. The following spec will load the angular materials page to the dialog demo page. It will click on the Confirm Dialog button, verify the header text on the modal, click the close button, then try to repeat the steps a second time. It fails on the second time, even though it is supposed to have waited until the button is clickable.
/**
* modal.conf.js
*/
exports.config = {
framework: 'jasmine',
specs: ['modal.spec.js'],
useAllAngular2AppRoots: false,
jasmineNodeOpts: {
'stopSpecOnExpectationFailure': true,
showColors: true
}
};
'use strict';
/**
* modal.spec.js
*/
var headerText = "Would you like to delete your debt?";
describe('Click Modal and Close test', function () {
beforeAll(function () {
browser.get('https://material.angularjs.org/latest/demo/dialog')
});
it('should click to open modal', function () {
confirmBtn.click().then(function () {
WaitForLoad(cancelBtn).then(function () {
expect(headerTextEl).toEqual(headerTextEl);
});
});
});
it('should click to close modal', function () {
cancelBtn.click().then(function () {
WaitForLoad(confirmBtn);
});
});
it('should click to open modal', function () {
confirmBtn.click().then(function () {
WaitForLoad(cancelBtn).then(function () {
expect(headerTextEl).toEqual(headerTextEl);
});
});
});
it('should click to close modal', function () {
cancelBtn.click().then(function () {
WaitForLoad(confirmBtn);
});
});
});
// region Page Objects
var confirmBtn = $('.layout-margin > button:nth-child(2)');
var headerTextEl = $('.md-title');
var cancelBtn = $('button.md-cancel-button');
// endregion
// region actions
var WaitForLoad = function (el, timeout) {
var EC = protractor.ExpectedConditions;
return browser.wait(EC.elementToBeClickable(el), timeout);
};
// endregion

How to get karma to clear the dom after each test?

The component I'm testing does some changes to the dom in an it() test, however it remains there in the next it() test, and this breaks my test. Is there a way to reset the DOM each it() test?
For none JQuery users:
afterEach(function () {
document.body.innerHTML = '';
});
Above removes all the <script> tags which are added by default, but that does not matter, because they have alreay been executed once (and Karma does never refresh the browser, at least not till all tests finish).
Hence you can also use beforeEach(...) (but I like to think of it as a dining table, you don't clean up before you start, you clean up after yourself).
I wrote a little DomCleaner that keeps track of events boud during your tests and cleans the body on cleanup (requireJS but you can change the code to your needs):
define(function () {
'use strict';
var installed = false,
documentAddListener,
documentListeners,
windowAddListener,
windowListeners;
return {
install: function () {
if (installed) {
throw new Error('Trying to install document cleaner, but its already installed!');
}
installed = true;
documentAddListener = document.addEventListener;
windowAddListener = window.addEventListener;
spyOn(document, 'addEventListener');
spyOn(window, 'addEventListener');
documentListeners = [];
windowListeners = [];
document.addEventListener.and.callFake(function () {
documentListeners.push(arguments);
documentAddListener.apply(null, arguments);
});
window.addEventListener.and.callFake(function () {
documentListeners.push(arguments);
windowAddListener.apply(null, arguments);
});
},
cleanup: function () {
if (!installed) {
throw new Error('Trying to cleanup document, but cleaner is not installed!');
}
installed = false;
documentListeners.forEach(function (listener) {
document.removeEventListener.apply(null, listener);
});
windowListeners.forEach(function (listener) {
window.removeEventListener.apply(null, listener);
});
documentListeners = [];
windowListeners = [];
document.body.innerHTML = '';
},
};
});
use it like this (in your first describe):
beforeEach(function () {
domCleaner.install();
});
afterEach(function () {
domCleaner.cleanup();
});
If using Jasmine - Use the beforeEach function to run a command before each test. In that function, you can clear the DOM. An example using jQuery:
describe("A test suite", function() {
beforeEach(function () {
$('body').empty();
});
});
I had to do this manually in each test method.
Just use DOM operations that remove stuff from the html using javascript.
stuff like
document.body.innerHTML = '';

Trying To Add A Edit Function Into Todo List Program With Meteor JS?

I am new to Meteor JS and I was following the official tutorial on their website.
I thought it would be nice to add an edit button to the original finished and delete buttons.
I can't seem to figure out how to add the functionality of editing the todo item. I have added the edit button itself via html but I just need to figure out how to add the functionality of actually editing the item itself.
Here is the javascript code:
Tasks = new Mongo.Collection("tasks");
if (Meteor.isClient) {
// This code only runs on the client
Template.body.helpers({
tasks: function () {
// Show newest tasks first
return Tasks.find({}, {sort: {createdAt: -1}});
}
});
Template.body.events({
"submit .new-task": function (event) {
// This function is called when the new task form is submitted
var text = event.target.text.value;
Tasks.insert({
text: text,
createdAt: new Date() // current time
});
// Clear form
event.target.text.value = "";
// Prevent default form submit
return false;
}
});
Template.task.events({
"click .toggle-checked": function () {
// Set the checked property to the opposite of its current value
Tasks.update(this._id, {$set: {checked: ! this.checked}});
},
"click .delete": function () {
Tasks.remove(this._id);
},
"click .edit": function () {
Tasks.update(this._id, {});
}
});
}
Help Would Be Much Appreciated!