0
votes

I am trying to click on a repeated list item in Protractor for my AngularJS application. The list is being repeated with ng-repeat and I want to change the tab items display. The html looks like so:

<ul class="navigation">
    <li ng-repeat="item in vm.navLinks" class="item"
     ng-class="{'active': item.view == vm.selectedState.view}"
     ng-click="vm.selectApiView(item.view)">
         <div class="tabText">{{item.title}}</div>
     </li>
</ul>

 <div class="containerClass">
     <div id="firstDiv" class="tab-view">
       Tab Item 1
      </div>
 </div>

In my controller, I have code that changes the style of the clicked div so it is visible in my tab menu:

vm.selectApiView = function(view) {
    vm.selectedState.view = view;

    var elementView = document.getElementsByClassName("tab-view");

    for (var i = 0; i < elementView.length; i++) {
        elementView[i].style.display = "none";
    }

    document.getElementById(view).style.display = "block";
};

In my protractor test, I have the following code which is supposed to loop over the list by the repeater and click the second list item. My guess is that it is not clicking because the style is not set to block, but I don't know how to prove that. I also might be mis-interpreting it.

describe("the tab selection", function() {
    it("should expect vm.selectedState.view to be 'fieldname' when clicked",function(){
        element.all(by.repeater('item in vm.navLinks')).get(1).click();
        let view = element(by.model('vm.selectedState.view'));
        console.log('view', view)
        expect(view).toEqual('fieldname')
    });

});

Is this how the protractor test should be setup to click on the div? Or am I missing a step?

1

1 Answers

0
votes

1) add a css class to change active tab display style

.active-view {
    display: block !important;
}

2) add a attribute: data-id to place the ID value from item.view for each li

<ul class="navigation">
    <li class="item" 
        ng-repeat="item in vm.navLinks" 
        ng-class="{'active': item.view == vm.selectedState.view}"
        ng-click="vm.selectApiView(item.view)"
        data-id="{{item.view}}">
            <div class="tabText">{{item.title}}</div>
    </li>
</ul>

<div class="containerClass">
    <div id="firstDiv" class="tab-view">
    Tab Item 1
    </div>
</div>

3) In Angular controller change tab's class attribute to remove active-view from all tabs' class attribute, then add active-view into active tab.

vm.selectApiView = function(view) {
    vm.selectedState.view = view;

    var tabs = document.getElementsByClassName("tab-view");

    for (var i = 0; i < tabs.length; i++) {
        tabs[i].setAttribute('class', tabs[i].className.replace(' active-view', ''));
    }

    var activeTab = document.getElementById(view);
    activeTab.setAttribute('class', activeTab.className + ' active-view');
};

4) find the active tab by css locator div.tab-view.active-view, compare the data-id of active li with the id of active div.

describe("the tab selection", function() {

    it("should expect vm.selectedState.view to be 'fieldname' when clicked",function(){

        var activeTab = element.all(by.repeater('item in vm.navLinks')).get(1);
        activeTab.click();

        let activeView = element(by.css('div.tab-view.active-view'));

        // the `data-id` of active li should euqal to the `id` of active div
        activeTab.getAttribute('data-id').then(function(dataId){
            return expect(activeView.getAttribute('id')).toEqual(dataId);
        })

    });

});