How to catch ngToast with Protractor? - javascript

I need somehow to catch ngToast message after some action. I tried different solutions from this site, but they didn't help me and I don't know why. Does anyone has a working solution ? My last attempt was like:
var HomePage = require('./home.pageObject');
describe('Home Page tests', function () {
var homePage = new HomePage();
var EC = protractor.ExpectedConditions;
beforeEach(function () {
browser.get('/#/');
});
it('should fail login', function () {
var toast = $('.ng-toast');
homePage.signinBtn.click();
homePage.login('admin', 'Password')
.then(function () {
var toast = $('.alert');
browser.wait(EC.visibilityOf(toast), 3000);
});
});
});
Thanks.

Inspect the toast element once it is shown and then try to grab the message using css.
In one of our projects where we use angular-toastr, this does the trick:
element(by.css('#toast-container .toast-message')

You can use this function and call it in the test:
First I'm waiting presence in the dom, then visibility and then I return the text:
this.returnToastText= function(){
browser.wait(EC.presenceOf(element(by.css(".alert"))), 3000).then(function () {
browser.wait(EC.visibilityOf(element(by.css(".alert"))), 3000).then(function () {
return toastText= element(by.css(".alert")).getText();
})
})
};

Related

MDC-Web: Multiple dialogs

I use google MATERIAL COMPONENTS FOR THE WEB and have problems with the "Dialogs".
Check my codepen: Dialog
What do I have to do to have multiple dialogs per page?
JS:
// Find all the dialogs on the page
const dialogEls = Array.from(document.querySelectorAll('.mdc-dialog'));
dialogEls.forEach((ele) => {
const dialog = new mdc.dialog.MDCDialog(ele);
dialog.listen('MDCDialog:accept', function() {
console.log('accepted');
})
dialog.listen('MDCDialog:cancel', function() {
console.log('canceled');
})
// From here I do not know how to continue....
// Here the selector '#dialog-login' should still be dynamic
document.querySelector('#dialog-login').addEventListener('click', function (evt) {
event.preventDefault(evt);
dialog.lastFocusedTarget = evt.target;
// This shows all dialogs, which is wrong.
dialog.show();
})
});
I have updated answer from #Jodo.
I suggest for dynamic approach using data attribute on dialog tags with value of opening button.
// Find all the dialogs on the page
const dialogEls = Array.from(document.querySelectorAll('.mdc-dialog'));
dialogEls.forEach((ele) => {
const dialog = new mdc.dialog.MDCDialog(ele);
dialog.listen('MDCDialog:accept', function() {
console.log('accepted');
})
dialog.listen('MDCDialog:cancel', function() {
console.log('canceled');
})
document.querySelector('#' + ele.dataset.dialog).addEventListener('click', function (evt) {
dialog.show();
});
});
https://codepen.io/woytam/pen/abvdZBQ?editors=1010
Simply add data-dialog attribute to each dialog with value of your button/link. JavaScript function then will use ele.dataset.dialog in foreach.
The Dialog opens twice because you create two event listeners for #dialog-login.
One of them opens the Login Dialog the other one opens the Delivery Dialog.
Since you have two different distinct Dialogs, I would suggest a more static way and declare both dialogs independently:
const dialogLoginEle = document.getElementById('mdc-dialog-login');
const dialogLogin = new mdc.dialog.MDCDialog(dialogLoginEle);
dialogLogin.listen('MDCDialog:accept', function() {
console.log('accepted login');
});
dialogLogin.listen('MDCDialog:cancel', function() {
console.log('canceled login');
});
const dialogDeliveryEle = document.getElementById('mdc-dialog-delivery-condition');
const dialogDelivery = new mdc.dialog.MDCDialog(dialogDeliveryEle);
dialogDelivery.listen('MDCDialog:accept', function() {
console.log('accepted delivery');
});
dialogDelivery.listen('MDCDialog:cancel', function() {
console.log('canceled delivery');
});
document.querySelector('#dialog-login').addEventListener('click', function (evt) {
dialogLogin.show();
});
document.querySelector('#dialog-delivery').addEventListener('click', function (evt) {
dialogDelivery.show();
});
https://codepen.io/j-o-d-o/pen/XZqNYy?editors=1010
Here a "dynamic" approach as requested, but IMHO this is not very readable and error prone.
// Find all the dialogs on the page
const dialogEls = Array.from(document.querySelectorAll('.mdc-dialog'));
// First one is the Login, Second one is the Delivery
var dialogArr = [];
dialogEls.forEach((ele) => {
const dialog = new mdc.dialog.MDCDialog(ele);
dialog.listen('MDCDialog:accept', function() {
console.log('accepted');
})
dialog.listen('MDCDialog:cancel', function() {
console.log('canceled');
})
dialogArr.push(dialog);
});
document.querySelector('#dialog-login').addEventListener('click', function (evt) {
dialogArr[0].show();
});
document.querySelector('#dialog-delivery').addEventListener('click', function (evt) {
dialogArr[1].show();
});
https://codepen.io/j-o-d-o/pen/jZxmxa?editors=1010

Events fire but nothing happens?

I'm following this course on pluralsight about making web apps using .NET Core. The author uses jQuery 2.4.3 I think and I just picked the newest jQuery myself which 3.x.
So I write the code exactly like he does:
(function () {
var ele = $("#userName");
ele.text("Some Dude");
var main = $("#main");
main.on("mouseenter", function () {
main.css("background-color", "#888;");
});
main.on("mouseleave", function () {
main.css("background-color", "");
});
})();
And at first nothing happened when I moused over my div. It doesn't change color. Nothing much seems to register at all. So I went hunting an I found that this is how I should probably do it instead:
(function () {
var ele = $("#userName");
ele.text("Some Dude");
var main = $("#main");
main.on("mouseover", function () {
console.log("enter");
main.css("background-color", "#888;");
})
.on("mouseout", function () {
console.log("out");
main.css("background-color", "");
});
})();
And while the console prints out "enter" and "out", the background color of my div still doesn't change.
What did I miss about this?
Maybe remove ";" in main.css("background-color", "#888;")

Cannot get the text of a span element using .getText() on a non-angular page

I'm trying to get the text value of an element <span> but it doesn't return anything with .getText()
`
//spec
var statPage = require('something');
describe('Start', function () {
describe('Setup', function () {
it('test quality', function(){
new statPage().quality();
});
});
});
//page object
Sender.prototype.quality = function () {
browser.ignoreSynchronization = true;
this.verifyPageUrl();
this.verifyTabName();
};
Sender.prototype.verifyTabName = function () {
console.log("inside verifyTabName()");
var EC = protractor.ExpectedConditions;
var tab = element(by.css("span.active-tab-head"));
browser.wait(EC.textToBePresentInElement(tab, 'u4uvpzn4'), 5000).then(function(){
console.log('inside browser wait');
});
tab.getText().then(function(tabFullName) {
console.log('tab name is : ' + tabFullName);
});
};
Sender.prototype.verifyPageUrl = function () {
browser.getCurrentUrl().then(function(text){
console.log('this is the right page : ' + text);
});
};
`
The code you've presented, looks correct and, I suspect, there could be a timing issue. Let's use textToBePresentInElement Expected condition and wait for u4uvpzn4 text to be present inside an active tab:
var EC = protractor.ExpectedConditions;
var tab = element(by.css("span.active-tab-head"));
browser.wait(EC.textToBePresentInElement(tab, 'u4uvpzn4'), 5000);
tab.getText().then(function(tabFullName) {
console.log('tab name is : ' + tabFullName);
});
You can make your code more dynamic by trying:
var tabName = element(by.css('.tab-head.active-tab-head'));
The only other issue I could think of off-hand is that you may not have any tabs set to .active-tab-head, which would return an empty string.
Something weird was happening coz protractor was not even recognizing browser.pause() But, reinstalling protractor fixed the issues!

Protractor test cases are failing on Jenkins server but they pass on Local machine: Error: Element is not clickable at

I have written as script in which I create one form and then Delete it. While creating and deleting one modal dialogue box appears on the screen and "Create" & "Delete" buttons are present on the Modal Dialogue. When I execute this script in my local machine, test script is running fine but when I run the same on Jenkins server, test script will fail with below message:
[31mUnknownError: unknown error: Element is not clickable at point (370, 24). Other element would receive the click: <div class="modal-backdrop fade" ng-class="{in: animate}" ng-style="{'z-index': 1040 + (index && 1 || 0) + index*10}" modal-backdrop="" style="z-index: 1031;"></div>
(Session info: chrome=37.0.2062.124)
(Driver info: chromedriver=2.9.248315,platform=Windows NT 6.1 SP1 x86_64)[0m
Here is my test script:
describe('Tests Scripts', function () {
var baseurl = `"http://test/index.html"`;
var url = `"/index.html"`;
var driver = browser.driver;
var ptor = protractor.getInstance();
var tabIndex = 1;
beforeEach(function () {
ptor.ignoreSynchronization = true;
});
it('WILL load the page', function () {
browser.get(baseurl);
helper.waitForElementByXpath('//*[#id="xyz"]/ul/li/a/i');
expect(browser.driver.isElementPresent(by.xpath('//*[#id="xyz"]/ul/li/a/i'))).toBeTruthy();
expect(browser.getCurrentUrl()).toContain(url);
});
it('Delete the form', function () {
element(by.xpath('//*[#id="xyz"]/ul/li/a/i')).click().then(() => {
helper.waitForElementById('controlItem');
element(by.id('controlItem')).click().then(()=> {
helper.waitForElementById('modalDialogue');
var form_name = "DeleteForm";
element(by.id('title')).sendKeys(form_name);
browser.wait(function () {
helper.clickByIDAndWait('createbutton');
tabIndex++;
return true;
}, 5000).then(function () {
browser.getCurrentUrl().then(function (curr_url) {
var arr_url = curr_url.split(':');
var instance_id = arr_url[arr_url.length - 1];
helper.clickByXpathAndWait('//*[#id="windowTab-1"]/a');
helper.waitForElementById('form-control');
var xp = '//*[#id="Forms-' + instance_id + '"]/td[2]';
expect(driver.isElementPresent(by.xpath(xp))).toBeTruthy();
element(by.id('deleteForm-' + instance_id)).click().then(()=> {
helper.waitForElementById('DeleteFormModal');
browser.wait(function () {
helper.clickByIDAndWait('modal-deleteForm-btn');
return true;
}, 5000).then(function () {
helper.waitForElementById(form-control');
expect(driver.isElementPresent(by.xpath(xp))).toBeFalsy();
});
});
});
});
});
Here are the functions used in above code:
var clickByIDAndWait = function (btnId) {
var returnVal = false;
browser.wait(function () {
if (!returnVal) {
element(by.id(btnId)).click().then(function () {
returnVal = true;
});
}
return returnVal;
}, 30000);
};
var waitForElementById = function(elementId){
browser.wait(function(){
return browser.driver.isElementPresent(by.id(elementId));
},30000);
};
I have found the solution.
Test cases are working fine on jenkins now after making some changes in the test cases. I think the problem was, once the focus is at the bottom of the page it was not going up automatically to click on the element, I restructured the test cases in such a way that my list will not be too long and focus will not go at the bottom of the page. Also, I am resetting the window size before every test case by using below line of code in beforeEach function:
beforeEach(function () {
ptor.ignoreSynchronization = true;
browser.driver.manage().window().setSize(1280, 1024);
});
I am not sure whether my assumptions are correct and resolution will work for everyone but its working fine for me. you may want to give a try and see.

reset javascript timer on click

I have this javascript code:
var logout_warning = 6000;
$(document).ready(function () {
window.setTimeout(function () {
$('#logout_warning').reveal();
}, logout_warning)
});
$(document).ready(function () {
window.setTimeout(function () {
alert("logout");
//location.href = "/login/logout.php?url=/index.php?r=inactivity";
}, logout_warning*2)
});
that displays a warning after 6000ms then redirects to a URL to logout a user after 12000ms
I have this a href link:
Stay Logged In
which i want to reset the time on click to stop the user from being logged out, i created this function but im not sure what to put inside it
function ResetLogoutTimer() {
}
try this:
var log_outer = window.setTimeout(function () {
alert("logout");
//location.href = "/login/logout.php?url=/index.php?r=inactivity";
}, logout_warning*2)
function ResetLogoutTimer() {
window.clearTimeout(log_outer);
}
Sorry for poor English, its my second language.
You should try:
var timeoutID = window.setTimeout(function () {
$('#logout_warning').reveal();
}, logout_warning)
and than
function ResetLogoutTimer() {
window.clearTimeout(timeoutID);
}
The docs for it https://developer.mozilla.org/en-US/docs/Web/API/Window.setTimeout
One last thing, do not use w3c schools for learning javascript (the docs are not complete , instead use mdn site https://developer.mozilla.org/pl/docs/JavaScript

Categories

Resources