Protractor cannot find element after page has loaded

Viewed 297

Seems like a common question, but can't find anything corresponding to my issue.

My test runs fine until it reloads the page and needs to catch an element from dropdown. First I tried using IsPresent to see if Protractor can find the wrapper were dropdown lies called "workbenchItems" and I also added a long sleep, but it doesn't work, and then of course it can't catch the dropdown aswell - the element I need to catch is in the last row called: 'Element from dropdown that I need to catch'

See the Protractor code here:

<div class="workbenchItems">
    <div data-uib-accordion="" data-close-others="false" data-template- url="modules/common/accordion/accordion.tpl.html">
        <div role="tablist" class="panel-group accordion" ng-transclude="">
            <div data-uib-accordion-group="" ng-click="$ctrl.setIsOpen($ctrl.itemIndex, $ctrl.isOpen)" class="panel-default ng-scope ng-isolate-scope panel panel-open"
                data-template-url="modules/common/accordion/accordion-group.tpl.html" data-nobody="true"
                data-leveltitle="h3" data-is-open="$ctrl.isOpen">
                <div class="panel-heading no-bottom-border" data-ng-class="{'no-bottom-border': noBody}" style="">
                    <h2 class="panel-title"><a href="" tabindex="0" class="accordion-toggle" ng-click="toggleOpen()"
                            uib-accordion-transclude="heading"><span uib-accordion-header="" ng-class="{'text-muted': isDisabled}"
                                ng-bind-html="heading" class="ng-binding">
                                <div class="ng-scope"><span ng-bind="::$ctrl.item.sectionName" class="ng-binding">Element
                                        from dropdown that I need to catch</span> <span class="count ng-binding"
                                        ng-bind="::$ctrl.item.sectionCount">2159</span></div>
                            </span></a></h2>
                </div>
                <div class="panel-collapse in collapse" uib-collapse="!isOpen" aria-expanded="true" aria-hidden="false"
                    style="">

This is what I've tried to catch the second element from the row

const toolaud = await element.all(by.tagName('accordion-toggle')).get(1);
     toolaud.click();
     browser.waitForAngular();
     browser.sleep(60 * 1000);
1 Answers

Use by.css("h2.panel-title a") instead of by.tagName('accordion-toggle')

Solution:

element.all(by.css("h2.panel-title a")).get(0);

As there are many panel titles, the above code will get you the first panel title.
You can provide the value of index in get() function to get the respective panel title.
If you provide 2 as index like get(2) then it will get 3rd panel title [Indexing start from 0 and not 1].

Explanation:

h2.panel-title a means:

Search for h2 tag element which has class panel-title. After that, search for a tag inside that found tag HTML code.


Additional Information:

  1. If there is only 1 panel title, then there is 1 more way to solve the same problem.

    element(by.css("h2.panel-title a"));
    
  2. $$("h2.panel-title a").get(0) and element.all(by.css("h2.panel-title a")).get(0) have same meaning and works the same way. It is always better to keep the same syntax everywhere. So, it becomes less confusing to other developers. If you use element() or element.all() syntax instead of $() and $$(), then I would suggest to keep the syntax same and not change it, even if both the syntax produces the same result.

Related