how to loop though elements in nightmare js - nightmare

Im doing a project for my JS class. I want to build a nightmare.js script that sends a message to every product post on close5.com within a location.
I already figured out how to login and send a message to a single product but I cant figure out how to loop through all product send a message and the click "Show More" then do the next 20 products
This is what i have so far
var Nightmare = require('nightmare');
var startingLink = "https://www.close5.com/l/los_angeles-california"
var nightmare = Nightmare({ show: true });
nightmare
//login code
.goto('https://www.close5.com/login')
.type('input[name="email"]', 'email#email')
.type('input[name="password"]', 'password')
.click('.button__root__3pI8a')
.wait(600)
//end login code
.goto(startingLink)
.evaluate(function() {
var elements = Array.from(document.getElementsByClassName('ItemsListCard__item__8yykb'));
return elements.map(function(element) {
.click('.ItemListingActionButtons__ask__3x7L_')
.type('.ThreadViewInput__input__37Ra7', 'random test msg')
.click('.ThreadViewInput__send__2FcoR')
});
})
.end()
.then(function(content) {
console.log(content);
})
how do i loop though every element and click then send the message?
how to you click a element inside .evaluate()?

Related

Cannot link to a webpart on SPO page with certain parameters

I have created a hyperlink which opens up a modal that shows a specific item from a SharePoint Online list.
Here's what I've got so far (with help from AmosWu!):
private _filterListOnEmail = () => { //this runs on componentdidmount
var urlParams = new URLSearchParams(window.location.search);
var urlParamstoString = urlParams.toString();
var justUrl = window.location.href;
var trimHref = justUrl.split('&')[0];
var trimHref2 = trimHref.substring(trimHref.indexOf("=") + 1);
var txtUrlParams = urlParams.toString();
var trimtxtUrlParams = txtUrlParams.substring(3);
this.setState({
urlParams: trimHref2
}, () => {
if(urlParamstoString){
this.setState({
showWelcomeModal: true,
ByEmail: 'Yes',
});
}
The URL I have constructed:
<a href={`https://mytenant.sharepoint.com/sites/MySite?ID=${this.props.id}`}>Here</a>
This works if the URL is https://mytenant.sharepoint.com/sites/MySite?ID=1 and it shows my modal and it gets the correct ID and shows the correct list item. But if it's ID=2 or any other number, the page shows No item exists at
https://mytenant.sharepoint.com/sites/MySite/SitePages/Home.aspx?ID=2
I don't understand why it's putting the extra SitePages/Home.aspx on the end....I guess this is causing the No item exists error.
The webpart is on the home page of the SP site.
It works with any ID number in workbench but not when deployed.
Really need help with this.
My test result:
I show the editform in the modal, it works well.
The code is the code I shared with you in Q&A. If you need the complete project code, please let me know and I will share it on Github.

Angular js watch for value in two fucntions

I want to update my data based on data received from back-end
there are two functions:
function getData(data){
Service.getRequest(url).then(function (_response) {
console.log(_response)
var res = _response
if(res.data.success) {
$scope.$watch('data.photo', function() {
alert('hey, myVar has changed!');
});
data.photo = res.data.result;// this will tell that Image received against the corresponding data
}
else {
ctrl.errorCallBack = true
ctrl.errorFunction = 5
}
$rootScope.showPreloader = false;
});
}
now I have second function that receives the selected data and called when clicked on button , now question is can I update the data inside this function when above Get request is completed:
function syncData(data) {
console.log('image received')
console.log(data)
}
First function is called n times based on number of images , now user click on second function to view Image but user don't see any Image because Image is not received yet but I want a way to update second function as Image is received
examples
ist image is loaded....user doesn't click on second function
2nd image is pending....user clicks on second function or second function is active
2nd image is received....active function image received
https://plnkr.co/edit/zKeDT84W6eF9cc3FpcmG?p=preview
If you use $scope for variables they will be automatically sync with DOM whenever it changes.
I did some changes for you in plnkr i hope solve your problem.
http:// plnkr.co/edit/Ug53a03kB7Ap1EWf2jZK?p=preview

Protractor testing AngularJS fails to find an element by an id that does exist

I have a sample AngularJS site # https://gamersweb-js.firebaseapp.com/ with a protractor test case which is supposed to find an element by id on one of it's pages. The element with this id 'displayNameInHome' certainly does exist (in the user's 'Home' page), but the test case fails to find it there.
To get to the web page, log in using the credentials of user 'tester#qa.com' + password '123456', which will take you to the user's home page. The following test case fails to find element 'displayNameInHome' on this page, which will be the id of string 'tester' after the Welcome ....:
beforeEach(function() {
//browser.get('http://localhost:5000/');
browser.get('https://gamersweb-js.firebaseapp.com');
});
it('Testing display name in profile for logged in user:', function() {
element(by.model('loginUI.email')).clear().sendKeys('tester#qa.com');
element(by.model('loginUI.password')).clear().sendKeys('123456');
element(by.id('loginBtn')).click();
return browser.wait(function() {
var displayNameInHome = element(by.id('displayNameInHome'));
return displayNameInHome.getText().then(function(text) {
return text =="tester";
});
}, 10000);
});
I cannot figure out why the element 'displayNameInHome' is not found by the test case. Any help would be greatly appreciated.
Thank you.
The first parameter of browser.wait() is actually a condition to wait on. So your test is exiting pretty fast because the first parameter is not a condition.
Also, your test is lacking expects.
I changed your code so that the test waits 10 seconds for the #displayNameInHome element to be present and then perform the assertion.
it('Testing display name in profile for logged in user:', function() {
element(by.model('loginUI.email')).clear().sendKeys('tester#qa.com');
element(by.model('loginUI.password')).clear().sendKeys('123456');
element(by.id('loginBtn')).click();
var displayNameInHome = element(by.id('displayNameInHome'));
browser.wait(function() {
return browser.isElementPresent(displayNameInHome)
}, 10000);
expect(displayNameInHome.getText()).toEqual('tester');
});

Protractor won't get repeater inside a ng-view

I've a tricky question for you guys out there. I've made a simple exercise webapp using AngularJS and ngRoute.
Inside my index.html I got an ng-view element which provide two pages search_page.html and detail_of_result_page.html. The code works pretty fine, I put something in the first page input field, hit search button and all results magically appears in my page. The troubles comes with protractor that seems to not see my result in results repeater with his:
element.all(by.repeater("result in results"))
I've tried to put in browser.pause() and watch for errors, but everything seems right.
I've forgot the error code from Protractor:
Failed: Index out of bound.
Trying to access element at index: 0, but there are only 0 elements that match locator by.repeater("result in results")
OK, under your searchTest.js line: 27
beforeEach(function () {
var EC = protractor.ExpectedConditions;
browser.wait(EC.presenceOf($('li')),5000);
var resultItem = element.all(by.repeater('result in results')).first(); //BUG
var resultLink = resultItem.element(by.css('a'));
resultLink.click();
resultId = resultLink.getAttribute('href').then(function (attr) {
//var res = attr.match('/\/TDDBook\/Search\/#\/detail\/(\d+)/')[1]; // TODO: fix this shit
return 1;
});
});
Things seem alright until you do resultLink.click(); Assuming that it work fine for the first it ("should set the url to the selected detail view"). But when it come to second it("should see the details in the main page component") at this moment you are no longer on /#/splash route. Therefore your pereater no longer available to be located when your beforeEach() run again.
Solution
Your beforeEach doesn't seem useful and logically not run-able for your second it("should see the details in the main page component"). So just move all the thing like this:
it ("should set the url to the selected detail view",function () {
var EC = protractor.ExpectedConditions;
browser.wait(EC.presenceOf($('li')),5000);
var resultItem = element.all(by.repeater('result in results')).first(); //BUG
var resultLink = resultItem.element(by.css('a'));
resultLink.click();
resultId = resultLink.getAttribute('href').then(function (attr) {
//var res = attr.match('/\/TDDBook\/Search\/#\/detail\/(\d+)/')[1]; // TODO: fix this shit
return 1;
});
resultId.then(function (id) {
var expectedUrl = '/detail/'+id;
browser.getLocationAbsUrl().then(function (url) {
expect(url).toBe(expectedUrl);
})
})
})
P.S. just for your information, there is Page Object in protractor, which will be fit with the thing you attempt to do with your beforeEach() . Plus with a tiny bit of knowledge of commonJS (module.exports & require()) it will perfectly suit your needs ;) Cheer!

tell Protractor to wait for the page before executing expect

When I click the export button, it makes a REST call to our endpoint then few seconds after, I receive the response then I also render the table. Unfortunately, I read that every call is asynchronous which means my expect will be executed even if table hasn't been rendered yet. The expect I wrote checks if the string is on the table but it's failing since it's not there yet. What is the proper approach to this?
it('should generate global user report', function() {
element(by.css('button#exportButton')).click();
expect(element(by.css("th[name*=Date]")).getText()).
toEqual('Date');
})
The error on the console is
NoSuchElementError: No element found using locator: By.cssSelector("th[name*=Date]")
I noticed that the table hasn't been rendered yet that's why it's failing.
Protractor 1.7 introduced a feature called "Expected Conditions", that can be applied here.
Wait for element to become visible:
var EC = protractor.ExpectedConditions;
var elm = element(by.css("th[name*=Date]"));
browser.wait(EC.visibilityOf(elm), 5000);
expect(elm.getText()).toEqual('Date');
I had problem waiting for a dynamic element to appear. Have the driver wait for it to either be present or displayed. The number at the end is the timeout.
element(by.css('button#exportButton')).click();
var header = element(by.css("th[name*=Date]"));
browser.driver.wait(function() {
return header.isPresent();
}, 1000);
expect(header.getText()).toEqual('Date');
I had to wait until it was present AND displayed before the test was fully stable. You can do that like this:
var header = element(by.css("th[name*=Date]"));
browser.driver.wait(function() {
return header.isPresent().then(function(present) {
if (present) {
return header.isDisplayed().then(function(visible) {
return visible;
});
} else {
return false;
}
});
}, 1000);

Resources