anasarbescu anasarbescu - 6 months ago 12
Javascript Question

Cannot locate element using recursion after it found it as visible

My Problem:

I am trying to click options in a dropdown with Nightwatch, using sections in page objects. I'm not sure if it's a problem with the section declaration or i'm missing something scope-related. Problem is that it finds the element as visible, but when it tries to click it will throw error that it cannot locate it using recursion.

What could i try to do to fix this issue using sections?

In the test:

var myPage = browser.page.searchPageObject();
var mySection = searchPage.section.setResults;

// [finding and clicking the dropdown so it opens and displays the options]
browser.pause (3000);

browser.expect.section('@setResults').to.be.visible.before(1000);
myPage.myFunction(mySection, '18');


In the page object:

var searchKeywordCommands = {
myFunction: function (section, x) {
section.expect.element('@set18').to.be.visible.before(2000);
if (x == '18') section.click('@set18');
//[...]
};

module.exports = {
//[.. other elements and commands..]
sections: {
setResults: {
selector: '.select-theme-result', //have also tried with '.select-content' and '.select-options' but with the same result
elements: {
set18: '.select-option[data-value="18"]',
set36: '.select-option[data-value="36"]' //etc

}}}}


Here is my source code:
enter image description here

When i run this piece of core, it seems to find the section, finds the element visible (i also can clearly see that it opens the dropdown and shows the options) but when trying to click any option, i get the error:
ERROR: Unable to locate element: Section[name=setResults], Element[name=@set18]" using: recursion


Here is the full error:
enter image description here

My attempts:

I have tried to declare that
set18
selector as an individual element instead of inside of the section and everything works fine this way, but won't work inside of the section. I have also tried all the selectors available to define the section's selector, but it won't work with any of them.

Answer

This is what i am doing with(LOL) I assume steps would be (find dropbox - click dropbox - select value).

var getValueElement = {
        getValueSelector: function (x) {
            return 'li[data-value="'+ x + '"]';
        }
}; 

module.exports = {
    //[.. other elements and commands..]
    sections: {
        setResults: {
            commands:[getValueElement],
            selector: 'div[class*="select-theme-result"', //* mean contains,sometime class is too long and unique,also because i am lazy.
            elements: {
                setHighlight:'li[class*="select-option-highlight"]',
                setSelected:'li[class*="select-option-selected"]', 
                //set18: 'li[data-value="18"]',
                //set36: 'li[data-value="36"]' 
                // i think getValueFunction is better,what if you have 100+ of set.

            }}}}

In your test

var myPage = browser.page.searchPageObject();
var mySection = searchPage.section.setResults;

// [finding and clicking the dropdown so it opens and displays the options]
mySection
     .click('@dropboxSelector')
     .waitForElementVisible('@setHighlight',5000,false,
          function(){
            var set18 = mySection.getValueElement(18);
            mySection.click(set18);
            });

Ps:in my case(i think your case also), dropbox or any small third-party js framework which is used many times in your web app, so better create a different PageObject for it,make pageObject/section is simple as possible.