Matching text in element with Protractor - javascript

I have an element on page. And there could be different text. I am trying to do like (code is below), and it is not printed to console.
this.checkStatus = function () {
var element = $('.message')
browser.wait(EC.visibilityOf(element), 5000).then(function () {
browser.wait(EC.textToBePresentInElement(conStatus, 'TEXT1'), 500).then(function () {
console.log('TEXT1');
})
browser.wait(EC.textToBePresentInElement(element, 'TEXT2'), 500).then(function () {
console.log('TEXT2');
})
browser.wait(EC.textToBePresentInElement(element, 'TEXT3'), 500).then(function () {
console.log('TEXT3');
})
browser.wait(EC.textToBePresentInElement(element, 'TEXT4'), 500).then(function () {
console.log('TEXT4');
})
})
return this;
}
thanks

I see two problems. first, not sure what 'constatus' is? you need to correct that. second, browser.wait will be throwing error/exceptions when it is not able to find matching condition and timeout expires, So, if your first condition doesn't meet, it will throw timeout exception and will never go to second one. Instead, try something like below
var section = "";
this.checkStatus = function () {
var element = $('.message')
browser.wait(EC.visibilityOf(element), 5000).then(function () {
browser.wait(()=>{
if(EC.textToBePresentInElement(element, 'TEXT1')){
section = "Text1";
}
else if(EC.textToBePresentInElement(element, 'TEXT2')) {
section = "Text2";
}
else if(EC.textToBePresentInElement(element, 'TEXT3')) {
section = "Text3";
}
else if(EC.textToBePresentInElement(element, 'TEXT4')) {
section = "Text4";
}
if(section !== "")
return true;
}, 5000).then(()=>{
<here you can do anything based on 'section'>
}
Note - I haven't verified compilation errors.. so check for that.

Not sure what are you up to, but you can join multiple expected conditions with "or":
var conStatus = $('.message');
var containsText1 = EC.textToBePresentInElement(conStatus, 'TEXT1');
var containsText2 = EC.textToBePresentInElement(conStatus, 'TEXT2');
var containsText3 = EC.textToBePresentInElement(conStatus, 'TEXT3');
var containsText4 = EC.textToBePresentInElement(conStatus, 'TEXT4');
browser.wait(EC.or(containsText1, containsText2, containsText3, containsText4), 5000);

Related

How can I use multiple pm.expect in one pm.test in postman tests

I want to check if request has a string then response has to contain this string in postman. I write a test like this but it doesn't work for me. I'm not sure I can use multiple pm.expect in one test with condition. My code is
pm.test("test",function(){
var hasA = data.hasOwnProperty('A');
var hasB = data.hasOwnProperty('B');
if(hasA === true){
pm.expect(response.A).to.eql(data.A);
}
if(hasB === true){
pm.expect(response.B).to.eql(data.B);
}});
Request can contain A and B both so I cannot use if..else statement. When I run this test if hasA flag true then code doesnt go into for second if even hasB option is true. How can I handle this problem.Can anyone help?
expect is hard assertion so if one fails then it won't goto next one so you can use any of the below approach:
try if conditions like:
pm.test("test", function () {
var hasA = data.hasOwnProperty('A');
var hasB = data.hasOwnProperty('B');
var hasBoth = hasA && hasB
if (hasBoth) {
pm.expect([response.A, response.B]).to.eql([data.A, data.B]);
} else if (hasA) {
pm.expect(response.A).to.eql(data.A);
} else if (hasB){
pm.expect(response.B).to.eql(data.B);
}
});
or
try catch like :
pm.test("test", function () {
var hasA = data.hasOwnProperty('A');
var hasB = data.hasOwnProperty('B');
let error = {};
try {
if (hasA) {
pm.expect(response.A).to.eql(data.A);
}
} catch (e) {
error.A = e
}
try {
if (hasB) {
pm.expect(response.A).to.eql(data.A);
}
} catch (e) {
error.B = e
}
if(Object.keys(error).length){
pm.expect.fail(JSON.stringify(error))
}
});

Invalid Locator error

I tried to rewrite my tests in Page Object style but something goes wrong.
I use Class Tab and this is a part of my code:
var World = require('../support/world.js');
const isAllAjaxRequests = require('../scripts/util').isAllAjaxRequests;
const isElementLocatedAndVisible = require('../scripts/util').isElementLocatedAndVisible;
module.exports.Tab = class Tab {
constructor(data) {
this.name = "Base";
this.locators = {
'nextStepIsLocked': {xpath: '//md-tab-item[#aria-selected="true"]//div[#class="cc-status red"]'},
'isActiveTab': {xpath: '//md-tab-item[#aria-selected="true"]//span[text()="'+ data + '"]'}
}
}
waitForElement(bySelector) {
var driver = World.getDriver();
var self = this;
//var bySelector = self.locators[bySelector];
return driver.wait(isAllAjaxRequests(driver), waitTimeOut).then(() => {
//console.log(bySelector)
return driver.wait(isElementLocatedAndVisible(bySelector), waitTimeOut);
});
}
tabIsOpen(tabName) {
var driver = World.getDriver();
var self = this;
var bySelector = By.xpath('//md-tab-item[#aria-selected="true"]//span[text()="'+ tabName + '"]');
return self.waitForElement(bySelector);
}
}
Code in util:
exports.isElementLocatedAndVisible = function isElementLocatedAndVisible(driver, bySelector) {
return new Condition('element is located and visible', function(driver) {
console.log(bySelector)
return driver.findElements(bySelector).then((arr) => {
if (arr.length > 0) {
return arr[0].isDisplayed();
}
else {
return false;
}
});
});
};
I tried to use is in my test:
this.Then(/^Tab "([^"]*)" is open$/, function (tabName) {
this.createTab(tabName);
//var bySelector = tab.getLocator(isActiveTab);
return tab.tabIsOpen(tabName);
});
But I recieved an Invalid Locator error.
Via debug print I see thah I miss bySelector value when code go to exports.isElementLocatedAndVisible function. This is undefiened.
What I did wrong?
I suspect it is just missing of a parameter causing the issue.
In the following line:
return driver.wait(isElementLocatedAndVisible(bySelector), waitTimeOut);
add driver object as first argument and then bySelector, as follows:
return driver.wait(isElementLocatedAndVisible(driver, bySelector), waitTimeOut);
function is defined as follows:
function isElementLocatedAndVisible(driver, bySelector)
so, expecting driver object along with bySelector

Waiting for multiple async operations in Nightwatch.js

I am attempting to test multiple sites for section headers being in the correct order. Of course everything is asynchronous in Nightwatch, including getting text from an element. The following code leads to the timeout never being called.
client.url(`www.oneofmyrealestatesites.com`);
client.waitForElementPresent("body", 5000);
var _ = require("underscore");
// This is the order I expect things to be in
var expected = ["Homes For Sale", "New Homes", "Apartments & Rentals"];
client.elements("css selector", ".listings .module-title .label", function (data) {
var listings = [];
data.value.forEach(function (element) {
client.elementIdText(element.ELEMENT, function (result) {
listings.push(result.value);
})
})
setTimeout(function () {
// Some of the sites have extra sections
var diff = _.intersection(listings, expected);
client.assert.ok(listings == diff);
}, 5000);
});
It would appear that no matter how much delay I give, listings is ALWAYS empty. If I console.log listings as it's being pushed to, it is getting populated, so that's not the issue. client.pause is always ignored as well.
Is there a way to make sure that listings is populated before asserting the diff?
I'm using async library for such cases https://github.com/caolan/async
Docs: https://github.com/caolan/async/blob/v1.5.2/README.md
var async = require("async");
/*use each, eachSeries or eachLimit - check docs for differences */
async.eachSeries(data.value, function (element, cb) {
client.elementIdText(element.ELEMENT, function (result) {
listings.push(result.value);
// this job is done
cb();
});
}, function() {
// Some of the sites have extra sections
var diff = _.intersection(listings, expected);
client.assert.ok(listings == diff);
});
setTimeout can only be called from .execute or .executeAsync because its actual javascript. The function below was only working until I used .executeAsync
Hope this works for you.
Cheers, Rody
LoopQuestionsLogSymptom: function() {
this.waitForElementVisible('.next-button', constants.timeout.medium, false);
this.api.executeAsync(function() {
let checkQuestion = function() {
// GET THE ELEMENTS
let nextButton = document.querySelectorAll('.next-button');
let answers = document.getElementsByClassName('flex-row');
let blueButton = document.querySelector('.blue-inverse-button');
let doneButton = document.querySelector('#doneButton');
let monitor = document.querySelector('.monitor');
//CHECK THE TYPES OF QUESTIONS AND CLICK THE RIGHT BUTTONS
if (!blueButton) {
answers[0].click();
nextButton[0].click()
} else if(blueButton){
blueButton.click();
}
setTimeout(() => {
if(!doneButton) {
console.log('Answering another question!');
checkQuestion();
}
if(doneButton){
doneButton.click();
}
else if(monitor) {
console.log("Exiting?")
.assert(monitor);
return this;
}
}, 2000);
};
// Initiating the check question function
return checkQuestion();
},[], function(){
console.log('Done?')
});
this.waitForElementVisible('.monitor', constants.timeout.medium);
this.assert.elementPresent('.monitor');
this.assert.urlEquals('https://member-portal.env-dev4.vivantehealth.org/progress');
return this;
},

API Key with colon, parsing it gives TypeError: forEach isn't a function

I'm trying to use New York Times API in order to get the Top Stories in JSON but I keep on getting a:
Uncaught TypeError: top.forEach is not a function
I feel like there's something wrong with the API key since it has : colons in the url. I even tried to encode it with %3A but it still doesn't work.
This is the basic url:
http://api.nytimes.com/svc/topstories/v2/home.json?api-key={API-KEY}
My function that grabs the data from the url:
```
function topStories(topStoriesURL) {
$.getJSON(topStoriesURL, function(top) {
top.forEach(function(data) {
link = data.results.url;
cardTitle = data.results.title;
if(data.results.byline == "") { postedBy = data.results.source; }
else { postedBy = data.results.byline; }
imgSource = data.results.media[0].media-metadata[10].url;
createCardElements();
});
});
}
I console.log(url) and when I click it inside Chrome console, it ignored the part of the key that comes after the colon. I've been debugging, but I can't seem to figure out the error.
Here is a version of the code that works.
function topStories(topStoriesURL) {
$.getJSON(topStoriesURL, function(data) {
if (data.error) {
alert('error!'); // TODO: Add better error handling here
} else {
data.results.forEach(function(result) {
var link = result.url,
cardTitle = result.title,
postedBy = result.byline == "" ? result.source : result.byline,
hasMultimedia = (result.multimedia || []).length > 0,
imgSource = hasMultimedia ? result.multimedia[result.multimedia.length - 1].url : null;
createCardElement(link, cardTitle, postedBy, imgSource);
});
}
});
}
function createCardElement(link, title, postedBy, imgSource) {
// create a single card element here
console.log('Creating a card with arguments of ', arguments);
}
topStories('http://api.nytimes.com/svc/topstories/v2/home.json?api-key=sample-key');
You are most likely going to need to do a for ... in loop on the top object since it is an object. You can not do a forEach upon on object the syntax would probably look like this:
function topStories(topStoriesURL) {
$.getJSON(topStoriesURL, function(top) {
for (var datum in top) {
link = datum.results.url;
cardTitle = datum.results.title;
if(datum.results.byline == "") { postedBy = datum.results.source; }
else { postedBy = datum.results.byline; }
imgSource = datum.results.media[0].media-metadata[10].url;
createCardElements();
});
});
}
Heres the documentation on for...in loops

Javascript: Firefox, why this error?

I am trying to make a firefox extension, and this is my very simple code:
var SlashUnblocker_Button = {
//*************************************
var prefManager = Components.classes["#mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
var prefs = Components.classes["#mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
prefs.QueryInterface(Components.interfaces.nsIPrefBranch2);
var alertsService = Components.classes["#mozilla.org/alerts-service;1"].getService(Components.interfaces.nsIAlertsService);
var urlbar = window.content.location.href;
prefManager.setCharPref("extensions.mf_unblocker.blocker_latest_url",urlbar);
prefManager.setCharPref("extensions.mf_unblocker.blocker_latest_url_title",document.title);
//*************************************
1: function () {
if(prefManager.getCharPref("extensions.mf_unblocker.blocker_user_email") != "a#a.com")
{
gBrowser.selectedTab = gBrowser.addTab("chrome://mf_unblocker/content/1_options.html");
}
else
{
gBrowser.selectedTab = gBrowser.addTab("chrome://mf_unblocker/content/0_register.html");
}
},
test: function () {alert("testing!");}
}
window.addEventListener("load", function (e)
{
SlashUnblocker_Button['test']();
}, false);
Here's the problem, see the part where I marked it with //********* ?
See the code inbetween.
If I put that code above the two functions it throws an error... but if I put it in function 1() then it works fine. The problem is I need to reference variable prefManager from both functions.
What am I doing wrong?
If I'm not mistaking, you are trying to put code into an object.
You should be putting it into a builder.
function SlashUnlockerButton(){
//*************************************
this.prefManager = Components.classes["#mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
this.prefs = Components.classes["#mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
prefs.QueryInterface(Components.interfaces.nsIPrefBranch2);
this.alertsService = Components.classes["#mozilla.org/alerts-service;1"].getService(Components.interfaces.nsIAlertsService);
this.urlbar = window.content.location.href;
prefManager.setCharPref("extensions.mf_unblocker.blocker_latest_url",urlbar);
prefManager.setCharPref("extensions.mf_unblocker.blocker_latest_url_title",document.title);
//*************************************
this.1 = function () {
if(prefManager.getCharPref("extensions.mf_unblocker.blocker_user_email") != "a#a.com")
{
gBrowser.selectedTab = gBrowser.addTab("chrome://mf_unblocker/content/1_options.html");
}
else
{
gBrowser.selectedTab = gBrowser.addTab("chrome://mf_unblocker/content/0_register.html");
}
};
this.test = function () {alert("testing!");};
}
var SlashUnblocker_Button = new SlashUnlockerButton();
//...
I haven't tested it, but that's the idea.
http://www.w3schools.com/js/js_objects.asp
Have you tried placing the //*** section before var SlashUnblocker_Button?

Categories

Resources