I have been trying for the past 3 days without success to get a function i'm using to get the CSS Selector paths of a list of elements fitting a certain selector, to work as a custom command in Nightwatch JS.
What you give to the command:
browser.getUniqueCssSelector('.note');
What the output should be:
['HTML> BODY> SECTION.upper-container > DIV.notes:nth-child(1) > DIV.note:nth-child(1)',
'HTML> BODY> SECTION.upper-container > DIV.notes:nth-child(1) > DIV.note:nth-child(2)',
'HTML> BODY> SECTION.upper-container > DIV.notes:nth-child(2) > DIV.note:nth-child(1)',
'HTML> BODY> SECTION.bottom-container > DIV.inner > DIV.notes:nth-child(1) > DIV.note'
'HTML> BODY> SECTION.bottom-container > DIV.inner > DIV.notes:nth-child(2) > DIV.note']
And so and so.
I have tried lots of different ways to implement it but with no success, I am fairly new to Async/Await so I have not been having alot of luck and haven't been able to relate the examples on the Nightwatch.js guide (https://nightwatchjs.org/guide/extending-nightwatch/#writing-custom-commands) to my issue.
I have written the following using the code segment found in How to generate unique css selector for DOM element? :
// getUniqueCssSelector.js file
exports.command = async function(selector) {
var browser = this;
let result = browser.execute(function (selector) {
const nodes = Array.from(document.querySelectorAll(selector))
var nodesSelectors = [];
nodes.forEach(node => {
nodesSelectors.push(getCssSelectorShort(node));
});
return nodesSelectors;
function getCssSelectorShort(el) {
let path = [], parent;
while (parent = el.parentNode) {
let tag = el.tagName, siblings;
path.unshift(
el.id ? `#${el.id}` : (
siblings = parent.children,
[].filter.call(siblings, sibling => sibling.tagName === tag).length === 1 ? tag :
`${tag}:nth-child(${1+[].indexOf.call(siblings, el)})`
)
);
el = parent;
};
return `${path.join(' > ')}`;
};
}, [selector], function(res) {
console.log('************INSIDE COMMAND RETURN CALLBACK ');
return res;
})
return result;
}
From there, I want in my test code which calls this custom command, to be able to await
it. This command will have to be called on multiple elements so making it a callback function, while would work, would also put my code in an eternal callback stack which would make it look very ugly, very fast.
ideally, I want the code to become something like this:
// nwtest.js file
let nodeSelectorsList= await browser.getUniqueCssSelectors('.note');
console.log(nodeSelectorsList); // Would bring me back the entire set I posted above.
nodeSelectorsList.forEach(async (noteElement)=> {
let resultSingle = await browser.element('css selector', noteElement);
console.log(resultSingle); // Should print the elements returned individually
})
Unfortunately, I always get undefined
as the fruit of my efforts. :/
I have been wrecking my brain over this for several days up to almost a week and tried both Promise and Event implementations, but this one was abit beyond me so I call on the help of SO. Any help would be massively appreciated!.