bob.mazzo
bob.mazzo

Reputation: 5627

Using Protractor to select nav menu items

I'm some issues launching certain menu items. The menu DOM below contains <ul> items:

Uploads Reports Downloads Admin

Here's a DOM sample of the menu structure:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>

<div id="TheMenu">
<ul class="rmRootGroup rmHorizontal">
<li class="rmItem rmSelected" style="z-index: 0;">
<span class="rmLink rmRootLink rmExpand rmExpandDown" tabindex="0">Bal Sheet)</span><div class="rmSlide" style="display: none; visibility: visible; width: 141px; height: 126px; left: 0px; top: 28px; z-index: 9; overflow: hidden;">
    <ul class="rmVertical rmGroup rmLevel1" style="top: -126px; left: 0px; display: block; visibility: visible; transition: none;">
        <li class="rmItem rmFirst" style="z-index: 0;">
            <span class="rmLink rmExpand rmExpandRight" " style="width: 69px;"><img alt="" src="images/foldericon.gif" class="rmLeftImage"><span class="rmText">Uploads</span></span><div class="rmSlide" style="display: none; visibility: visible; width: 144px; height: 126px; left: 135px; top: 0px; z-index: 5; overflow: hidden;">
                <ul class="rmVertical rmGroup rmLevel2">
                    <li class="rmItem rmFirst"><span class="rmLink" tabindex="0" ><img alt="" src="images/document.gif" class="rmLeftImage"><span class="rmText">Upload List</span></span></li>
                    <li class="rmItem ">
                        <span class="rmLink rmExpand rmExpandRight" tabindex="0" ><img alt="" src="images/foldericon.gif" class="rmLeftImage"><span class="rmText">Adj123</span></span><div class="rmSlide">
                            <ul class="rmVertical rmGroup rmLevel3">
                                <li class="rmItem rmFirst"><span class="rmLink" tabindex="0"><img alt="" src="images/document.gif" class="rmLeftImage"><span class="rmText">BLAH Adjustment This</span></span></li>
                                <li class="rmItem rmLast"><span class="rmLink" tabindex="0"><img alt="" src="images/document.gif" class="rmLeftImage"><span class="rmText">BLAH2 Adjustment That</span></span></li>
                            </ul>
                        </div>
                    </li>
                    <li class="rmItem ">
                        <span class="rmLink rmExpand rmExpandRight" tabindex="0" style="width: 72px;"><img alt="" src="images/foldericon.gif" class="rmLeftImage"><span class="rmText">Targets</span></span><div class="rmSlide">
                            <ul class="rmVertical rmGroup rmLevel3">
                                <li class="rmItem rmFirst"><span class="rmLink" tabindex="0"><img alt="" src="images/document.gif" class="rmLeftImage"><span class="rmText">Target1 BLAH1</span></span></li>
                                <li class="rmItem rmLast"><span class="rmLink" tabindex="0"><img alt="" src="images/document.gif" class="rmLeftImage"><span class="rmText">Target2 BLAH2</span></span></li>
                            </ul>
                        </div>
                    </li>
                    <li class="rmItem rmLast">
                        <span class="rmLink rmExpand rmExpandRight" tabindex="0" style="width: 72px;"><img alt="" src="images/foldericon.gif" class="rmLeftImage"><span class="rmText">Actuals</span></span><div class="rmSlide">
                            <ul class="rmVertical rmGroup rmLevel3">
                                <li class="rmItem rmFirst"><span class="rmLink" tabindex="0"><img alt="" src="images/document.gif" class="rmLeftImage"><span class="rmText">Actual This</span></span></li>
                                <li class="rmItem rmLast"><span class="rmLink" tabindex="0"><img alt="" src="images/document.gif" class="rmLeftImage"><span class="rmText">Actual That</span></span></li>
                            </ul>
                        </div>
                    </li>
                </ul>
            </div>
        </li>
        <li class="rmItem ">
            <span class="rmLink rmExpand rmExpandRight" tabindex="0" style="width: 69px;"><img alt="" src="images/foldericon.gif" class="rmLeftImage"><span class="rmText">Reports</span></span><div class="rmSlide">
                <ul class="rmVertical rmGroup rmLevel2">
                    <li class="rmItem rmFirst"><span class="rmLink" tabindex="0"><img alt="" src="images/document.gif" class="rmLeftImage"><span class="rmText">REPT 1</span></span></li>
                    <li class="rmItem "><span class="rmLink" tabindex="0"><img alt="" src="images/document.gif" class="rmLeftImage"><span class="rmText">REPT 2</span></span></li>
                    <li class="rmItem rmLast"><span class="rmLink" tabindex="0"><img alt="" src="images/document.gif" class="rmLeftImage"><span class="rmText">REPT 2</span></span></li>
                </ul>
            </div>
        </li>
        <li class="rmItem ">
            <span class="rmLink rmExpand rmExpandRight" tabindex="0" style="width: 69px;"><img alt="" src="images/foldericon.gif" class="rmLeftImage"><span class="rmText">Administration</span></span><div class="rmSlide">
                <ul class="rmVertical rmGroup rmLevel2">
                    <li class="rmItem rmFirst"><span class="rmLink" tabindex="0"><img alt="" src="images/document.gif" class="rmLeftImage"><span class="rmText">Sub123 List Admin</span></span></li>
                    <li class="rmItem "><span class="rmLink" tabindex="0"><img alt="" src="images/document.gif" class="rmLeftImage"><span class="rmText">THIS MENU</span></span></li>
                    <li class="rmItem rmLast"><span class="rmLink" tabindex="0"><img alt="" src="images/document.gif" class="rmLeftImage"><span class="rmText">THAT MENU</span></span></li>
                </ul>
            </div>
        </li>
        <li class="rmItem rmLast">
            <span class="rmLink rmExpand rmExpandRight" tabindex="0" style="width: 69px;"><img alt="" src="images/foldericon.gif" class="rmLeftImage"><span class="rmText">Downloads</span></span><div class="rmSlide">
                <ul class="rmVertical rmGroup rmLevel2">
                    <li class="rmItem rmFirst"><span class="rmLink" tabindex="0"><img alt="" src="images/document.gif" class="rmLeftImage"><span class="rmText">FIRST DOWNLOAD THING</span></span></li>
                    <li class="rmItem rmLast"><span class="rmLink" tabindex="0"><img alt="" src="images/document.gif" class="rmLeftImage"><span class="rmText">SECOND DOWNLOAD THING</span></span></li>
                </ul>
            </div>
        </li>
    </ul>
</div>
</li>
</ul>
</div>

</body>
</html>

And my Protractor script below...

FYI: My first elem.click() does work, and successfully enters the .Then() section; and the dropdown menu opens.

Now, I can use '.rmItem .rmFirst' to open the "Uploads" sub menu, but what if I want to open the "Reports" menu ? Which selector should I use ? 'ul li:nth-child(2)' only goes to the siblings which goes back to the top menu bar again (not what I want).

this.launchUploadsMenu = function () {
  var sel = '#RadMenu1 > ul > li:nth-child(3)';
  var elem = element(by.css(sel));

  elem.click().then(function () {
    //var elem2 = element.all(by.cssContainingText('.rmLink', 'Uploads')).first();	// THIS STILL NOT WORKING
    
    var elem2 = element.all(by.css('.rmItem .rmFirst'));   // 
    elem2.click();
  });
}

Help is appreciated.

regards, Bob

Upvotes: 0

Views: 1581

Answers (2)

bob.mazzo
bob.mazzo

Reputation: 5627

Due to the fact that we have encountered so many road blocks traversing the DOM in this environment, we decided to go with a combination of browser.actions() and 'cssByText()` instead.

It's not ideal, but it does work.

For example, this will accomplish the menu clicks that are required to get to the required Angular page (fyi: the nav menus are NOT an Angular application; only the final landing page is where the Angular app loads within an iframe element).

var sel = '#RadMenu1 > ul > li:nth-child(3)'; // top-level menu       

var elem = element(by.css(sel));

elem.click().then(function () {    

    var elem2 = element(by.css(sel));
    browser.sleep(2000);        

    // OPENS SUBMENUS
    browser.actions()
	.mouseMove(elem2, { x: 25, y: 50 }) // an offset relative to the top-left corner of elem2
	.click()
	.perform()
	    .then(function () {
		browser.sleep(1000);
		browser.actions()
		    .mouseMove({ x: 150, y: 20 })   // opens next menu option
		    .click()
		    .perform()
			.then(function () {
			    var elem = element(by.cssContainingText('.rmText', 'Menu Item To Click'));   		
            		    elem.click();  
			});
	    });
    

});
}

Upvotes: 1

Maciej Ciach
Maciej Ciach

Reputation: 75

You want to use first() method in order to get first element from the array. But element() returns single element, you should use element.all() to return ElementArrayFinder and then you can apply first() .

Instead of using cssContaingText I would prefer to create some structure of levels in your menu and then just walking inside each level.

Also, why have you decided to waitForAngular ? Protractor is waiting by default, I don't understand why you use browser.sleep in that case. Most thing you can achive by chaning then promises.

Can you specify on which element exactly you want to click ?

EDIT:

Also, there is no such element with rmLink class and containing text Adjust This, I think that you should look for rmText.

Upvotes: 1

Related Questions