how to click same classed element each time on page with protractor - angularjs

it('it should click each of the title elements to reveal its content', function(){
element(by.css('.cardtitle')).click();
});
I have the above lines which work properly and click the first item in the series of 3 with this class. I need to click all 3 items with this class using protractor, how do I do this? (the are all on the same page, very straightforward)
for whats its worth there will be upcoming instances where there may be 2 or 5 items to click all sharing the same class.
thanks!

Loop through the elements and click them one after the other using each() function available in protractor. Here's how -
element.all(by.css('.cardtitle')).each(function(elem){
elem.click();
});
If at all you want to click the elements serially then you need to wait until click is completed resolving its promise. Here's a sample -
element.all(by.css('.cardtitle')).each(function(elem){
elem.click().then(function(){
//If you want perform some operation after click, you can do it here.
browser.sleep(1000);
});
});
Hope this helps.

You can get a collection of items and click them individually.
eg.
var cards = element.all(by.css('.cardtitle'));
expect(cards.length).toBe(3);
cards.get(0).click();
cards.get(1).click();
cards.get(2).click();

Related

protractor - issues with scrolling into infinite scroller

I have a protractor test looking for a record in my infinite scroller component like this.
searchPage.searchEntitlement('search criteria');
var myHiddenElementInScroller = element(by.repeater('result in ctrl.results track by $index').row(12));
browser.driver.executeScript(function () { arguments[0].scrollIntoView(); }, myHiddenElementInScroller .getWebElement());
myHiddenElementInScroller.click();
This is supposed to scroll to the element and click it. Instead its throwing me element not visible error.
Has anyone come across this situation? Any help greatly appreciated.
You might need to explicitly wait for the scrolling into view actually happen:
browser.driver.executeScript("arguments[0].scrollIntoView()", myHiddenElementInScroller.getWebElement()).then(function () {
myHiddenElementInScroller.click();
});
Or, with browser.actions():
browser.actions().mouseMove(myHiddenElementInScroller).click().perform();
In few scenarios the element which we are looking for will be covered with some other element from DOM.when protractor tries to click it,the click will be received by the element that covers the actual element. So in such situation you need to use native javascript click event. Look at the below code.
browser.executeScript("arguments[0].click()", myHiddenElementInScroller.getWebElement())
The above code will send a click event directly to the mentioned webElement even if it is visible or not.
NOTE: this is not the recommended way for clicking an element. but you can you this in scenarios where you have no other workaround to achieve the click event.
Thanks for all the responses. I was able to resolve this issue by using element(by.CssContainingText(cssSelector, searchText)) locator.

Execution order of protractor tests

Which is the best way to control the execution order of Protractor tests?
Problem case 1: protractor swipes angular pages so quickly that it cannot manipulate (fill in) input data. (The swipe logic is to transfer from being invisible to visible and by translating them into the window visible area). thus protractor cannot see those beyond the window and with opacity 0. To test i can only fill in the first page. the others are swiped too fast (or async).
Problem case 2: After i filled in the first page and submitted the form, the data is saved and alert shows confirmation message. Then protractor has to click a drop-down list and browser should navigate to the page where saved data is displayed. The problem is that protractor clicks the drop-down list before the data is saved due to alert fired later (have to wait for alert).
Question is: Is there a way to control tests to be executed in the given order in protractor? And is there a way to hold down swiping to fill in the date (otherwise protractor does not see it)? Here is the simplified code:
it('should fill in form and send data', function() {
// fill in textarea field
element.all(by.css('textarea')).first().clear().sendKeys('test');
// goes to page 2
browser.executeScript("angular.element(document.documentElement)
.injector().get('$rootScope').$broadcast('nextPage', {direction: 'next'});");
// Here is Problem 1. Though i can see this page when testing,
// the input is not visible for protractor.
// fill in input-field
element.all(by.css('input')).first().clear().sendKeys('test');
// goes to page 1
browser.executeScript("angular.element(document.documentElement)
.injector().get('$rootScope').$broadcast('prevPage', {direction: 'prev'});");
// submit form
element(by.css('button[type=submit]')).click();
// Here is problem 2. The following test is executed earlier
// than the following alert.
//browser.wait(protractor.ExpectedConditions.alertIsPresent(), 3000);
var alertDialog = browser.switchTo().alert();
expect(alertDialog.getText()).toEqual('Saved');
alertDialog.accept();
});
it('should click drop-down-list', function() {
// click drop-down list
element(by.css('.drop-down-list')).click();
});
I personally believe browser.sleep(5000) should resolve the second issue.
if not can you try with promisies
element(by.css('button[type=submit]')).click().then(function(){
var alertDialog = browser.switchTo().alert();
expect(alertDialog.getText()).toEqual('Saved');
alertDialog.accept();
});
This should wait for the promise to get resolved (i.e to click submit button) and then execute the code snippet inside

Not able to remove the ionic filter

I am using ionic filter, When I click the cancel button in filter bar I am able to remove the filter but when I want to do that automatically without clicking the cancel button when shifting tabs I am not able to do that.
// code in angular controller for initializing the filter
var filterBarInstance;
filterBarInstance = $ionicFilterBar.show({
});
// when I shift tabs I am calling the below method to close the modal of the filter(if the modal is opened)
filterBarInstance = $ionicFilterBar.show({
cancel : '',
});
I am calling the above methods whcih are present in the filter directive but that method is not getting triggered. Kindly , use the url https://github.com/djett41/ionic-filter-bar/blob/master/js/ionic.filter.bar.directive.js and provide me some solutions to fix this.
try filterBarInstance()
I hope that solve your problem

Adding listener to Ext.Grid.panel in EXTJS 4

I am trying to add a listener to a Ext.grid.panel
listeners: {
itemclick:function( grid, record, item, index, event){
alert(index);
var record = grid.getStore().getAt(index);
alert("Edit " + record.get('data'));
alert("Type " + record.get('type'));
}
I suppose to get the index value of the row I clicked. So when I click the row for the first time I get : [object Object] in the alert box with index in it. The second two alerts don't appear at all.
So when I again click the same row. it shows the correct index and then "data" and then " type" in an alert box.
How can I get the right values on the first click only?
When I add your listener to a grid panel of my own, I get the same behavior every time. For example:
4/"Edit undefined"/"Type undefined".
That you are seeing different behaviors depending on if it is the first time you click an item or not likely has something to do with how the grid is created/rendered.
The content of the Object passed as "index" to your listener function might give you a clue. If you log it to the console you'll be able to inspect it. (At least that's how Chrome handles logging of objects).
While this is not a solution to your problem, I hope it helps in your debugging.

Display n time ago on various items using jquery, [issue with new elements generated after the loading the DOM]

I am using Jquery plugin http://timeago.yarp.com/ for showing time.
Issue is timeago will not take effect for dynamically generated items.
$(document).ready(function() {
$(".timeago").timeago(); // works perfectly fine for the items which are loaded on page load
//$(".timeago").live(timeago()); // gives me an error ie timeago is not defined
//$(".timeago").live($(".timeago").timeago()); // gives me an error too much recursion.
jQuery.timeago.settings.allowFuture = true;
});
From some google search I got to know something ie:
Using live is the same as using bind, except that it is limited only to the events click, dblclick, keydown, keypress, keyup, mousedown, mousemove, mouseout, mouseover, and mouseup.
Now how can do it cause I dont have any click event? How can I bind this?
.live() and .bind() assign callbacks to event. In your case, you don't have an event to assign the function to and so it fails.
You can, in theory, assign your callback to a custom event. You will however have to manually trigger the event (using .trigger()) whenever your item is generated. For example:
$("abbr.timeago").live("timeago", function() {
$(this).timeago();
});
// ... and in the bit that generates your item
$new_item.trigger("timeago")
Demo: http://jsfiddle.net/ZjuW4/9
Of course, using .live() in this situation is purely academic and does not really serve a good purpose.
If you do have access to the code that's generating the items, you can simply chain in the call to .timeago() as the items are generated, i.e. http://jsfiddle.net/ZjuW4/3/
take a look in this topic
here was discussed how to put timeago on dynamically loaded items
for example the results of an ajax request.
Activate timeago on newly added elements only
PS: allowFuture does not have anything to do with putting timeago on newly created items on your page. it just allows dates in the future (f.e. "in 3 days", "next week")

Resources