Like in title, I'm struggling with this from 2 days already and I couldn't find a solution.
How to .click on some css element containing text?
For example - I'm having 5 .search-results css elements, each of them containing unique text.
This can be done with:
browser.jqueryClick('.search-result-name:contains("Something")')
from custom nightwatch commands. But hey, they don't support Nightwatch.js Page Objects from what I know - atleast I couldn't make it working.
Am I missing something?
Best regards,
drptbl.
Yeah I had trouble using custom commands with page objects, so I just call it on the browser object instead. If I need the css from the page object I just embed it.
browser.customCommand(pageObject.elements.elementName.selector, callback);
Could you please explain this further? I'm trying to get this working, but without a success.
homePage.js -> page object file
mainSearch -> section containing desired object
searchResults -> element (defined with CSS) in section above -> this is equal to 5 elements on website with only one difference - they contain unique texts inside of them - and one of them contains "something" text for example.
So.. I want to click element by CSS containing "something" text, so from 5 elements I'm down to 1.
My example:
browser.customCommand(homePage.elements.section.mainSearch('@searchResults').?, callback);
I'm really not sure how to use it.
Custom commands are loaded onto page objects and their sections so you should be able to do:
homePage.section.mainSearch.customCommand('@searchResults', callback)
Sadly I couldn't make any progress in this topic, I'm still not able to understand this and get it working.
Tried various options of:
homePage.section.mainSearch.customCommand('@searchResults', callback)
browser.page.homePage().section.mainSearch.customCommand('@searchResults', callback)
without a success. I'm sure I'm doing this wrong.
Hm, looks like it should work. Can you post some sample code (test and page object snippet) as well as any error you're seeing?
On Sep 13, 2015, at 10:15 AM, drptbl [email protected] wrote:
Sadly I couldn't make any progress in this topic, I'm still not able to understand this and get it working.
Tried various options of:
homePage.section.mainSearch.customCommand('@searchResults', callback)
without a success. I'm sure I'm doing this wrong.—
Reply to this email directly or view it on GitHub.
That's how I'm trying to use it:
browser.page.homePage().section.mainSearch.customCommand('@searchResults', ?)
and here's another example I'm not capable to fix (it's different from this one above):
<div class="select2-result-label"><span class="select2-match"></span>single-select</div>
So.. I'm having 5 '.select2-match' elements and it's names are in divs not in spans. So I want to click on span but take text from entire div. This is crazy.
Also I'm struggling with click on element by it's unique number. For example: I have 5 '.search-results' elements and I want to click on 2nd one. How to accomplish this? I know you can add it's number with [number], for ex. [0], but I'm not quite sure how to do this in Nightwatch.js).
For these questions you're better off asking on the mailing list. But to point you in the right direction check out http://nightwatchjs.org/api#elements (can't be used currently with page objects though)
Closing this for now, if you find an issue in nightwatch feel free to re-open.
For people finding this via search engines, you can achieve this using xpath:
browser.useXpath().click("//*[contains(text(), 'Something')]")
@ndtreviv has a good and simple solution for this, but I have a project that has multiples of the same strings on a page. So I wrote this custom command that checks a string against the text of multiple elements that have the same attribute / selector, and clicks on the match:
/**
* Finds an array of elements based on a common selector, then finds a specific element within the array by its text, and clicks on it
*
* Example: browser.clickElementWithText('button', 'Confirm');
*
* @param selector - Selector of elements (ie. '[data-qa=MultipleElements]')
* @param text - Unique text of the specific element you want to click on
*/
exports.command = function (selector, text) {
let element = null;
this.waitForElementVisible(selector);
this.elements('css selector', selector, function (elements) {
let success = false;
for (let i = 0; (i < elements.value.length) && (success === false); i++) {
this.elementIdText(elements.value[i].ELEMENT, function (result) {
if (result.value === text) {
console.log(' ♦ Clicking ' + selector + ' with text: ' + result.value);
success = true;
element = elements.value[i].ELEMENT;
}
});
}
});
this.perform(function () {
if (element === null) {
throw new TypeError('Element was not found with text: ' + text);
}
else {
this.api.elementIdClick(element);
}
})
};
Let's say you have a page with 10 listed elements with a data-qa attribute of SequenceLink, and each has a unique string. To call this custom command and find the SequenceLink with a string of "Seeing the USA":
browser.clickElementWithText('[data-qa=SequenceLink]', 'Seeing the USA')
You can also call this from a page object:
sequences.clickElementWithText('@sequenceLink', sequences.props.seeingTheUsa);
The output of the command looks like:
✔ Selecting [data-qa=SequenceLink]: Seeing the USA
the line:
this.pause(500);
Is setting you up for some real painful test false positives and hard conversations if you're using this for actual QA. This is inherently flakey.
Yeah the pause wasn't necessary, removing from snippet
Well. You're still passing the responsibility up and if you use this method directly, you still might return from the method without clicking anything even if it shows up later.
Updated my original comment with the actual function I'm using now, which fails if no match is found.
Most helpful comment
For people finding this via search engines, you can achieve this using xpath:
browser.useXpath().click("//*[contains(text(), 'Something')]")