How to locate element based on text()/contains criteria in Cypress.io - css-selectors

I need to locate an element/ verify presense of an element, based on the Text inside element, using something like:
//div[contains(text(),'<My intended text>')]
As Cypress.io do not support the XPATh yet, then how to locate it using alternate locators.
There seems to be lot of discussions around cssselectors :contains & when tried div:contains('<My intended text>') it failed to locate the element.
Given the fact that both XPATH & CSSLocators have good performance on modern browsers.
Kindly advise. Thanks

so you are looking for the parent which holds 'My intended text'?
You can do so by using:
cy.contains('My intended text')
and that's how you selected the element. Now you can use for example .click() to click on the element which holds 'My intended text'

Related

Which locator to use? I am using xpath but it is not working

Which locator to use for my code?
I tried using Xpath but for some reason xpath is not working.
xpath:
//*[#id="ext-gen25"]/table/tbody/tr[1]/td[2]/a
driver.findElement(By.xpath("//*[#id='ext-gen25']/table/tbody/tr[1]/td[2]/a")).click();
Data Manager [eXchange]
By clicking on that hyperlink the system should navigate to X module.
If this Data Manager [eXchange] text is unique you could stick to it and omit the parent table:
//a[text()='Data Manager [eXchange]']
Demo:
If you need to match the link for the specific row it is more tricky but still possible, you will need to share your table code so we could come up with the right expression, an example one would be something like:
//table/tr/td[count(//table/tr/th[.='the header you're looking for']/preceding-sibling::th) + 1]/a[text()='Data Manager [eXchange]']
References:
XPath Tutorial
XPath Axes
XPath Operators & Functions
Also be aware of Table class which is a part of HtmlElements framework, it makes working with tables much easier

Appium: Element is not interactable error is getting displayed while tapping on the checkbox

Tried: xpath= //*[#id="mktoCheckbox_52362_0"],
Console Error: Element is not interactable.
Tried: Xpath= //[#id="mktoForm_2768"]/div[10]/div[1]/div[2]/div[2]/label,
console error: Element is not interactable.
Tried: xpath= //*[text()='I agree to the '],
clicking on 'License Agreement' link and open pdf file in other tab.
Applied all the above xpath but still got no result. Please provide some solution to this problem.
Assuming you're trying to automate this page: https://info.couchbase.com/couchbase_server_mobile.html
If you want to open the license agreement in a new tab - the relevant XPath would be
//a[text()='License Agreement']
If you want to tick the checkbox associated with the license agreement you need this one:
//input[#name='termsandConditions']
In both case it's better to use Explicit Wait to ensure that the element is clickable prior to attempting to interact with it via i.e. ExpectedConditions.elementToBeClickable() function
Going forward if you're working on mobile automation you can consider using Appium Studio which provides Copy Unique XPath feature, it can make your life easier when it comes to defining an element locator

Unable to find visible field nil that is not disabled

I'm not sure what I'm doing wrong here as I'm totally new to capybara. I can find an element with
all('.mold_table_input').last
#<Capybara::Node::Element tag="input" path="/html/body/md-content/section/md-content/md-tabs/md-tabs-content-wrapper/md-tab-content/div/div/div/md-card/md-card-content/div/form/md-content/table/tbody/tr[1]/td[1]/input">
but when I try all('.mold_table_input').last.fill_in(with: '02') I get the following error
Capybara::ElementNotFound: Unable to find visible field nil that is not disabled within #<Capybara::Node::Element tag="input" path="/html/body/md-content/section/md-content/md-tabs/md-tabs-content-wrapper/md-tab-content/div/div/div/md-card/md-card-content/div/form/md-content/table/tbody/tr[3]/td[12]/input">
I'm using angularjs on my front end. Also when I check the visibility like all('.mold_table_input').last.visible? it returns true
What version of Capybara are you using? I’m guessing < 3.7 since that’s where the ability to call fill_in on the element to be modified was added. Prior to 3.7 it would only attempt to find a valid descendant to work on. Even in 3.7+ using fill_in like you are attempting to isn’t recommended when you have a simple unique locator since it adds overhead for no reason. In this case you’re dealing with a unique element locator (element id should be unique on a HTML page) so you have no need to be using ‘all(...).last` and should just do
fill_in ‘mold_table_input’, with: ‘02’
On a related note, if you do ever need to locate an element for more complicated interaction you really should prefer find over all when you have elements that can be located uniquely. Not only will find be faster, but all has a few subtle limitations on dynamic pages.
I don't know the detail just posting to help others the following line did the trick
find('.mold_table_input', match: :first).set('06')
I was able to set the value of input field by finding first and use of set rather than fill_in

How can I access the selector field of a By object?

I'm using Java, Selenium Webdriver in Eclipse.
I wrote a helper method to wait for an element present, scroll to it, wait for the element to be visible and click it. Here's what I have:
protected void waitScrollWaitClick(By by, String scroll)
{
wait.until(ExpectedConditions.presenceOfElementLocated(by));
getJse().executeScript("$('.mCustomScrollbar#" + scroll + "').mCustomScrollbar('scrollTo',document.querySelector(\"" + by.selector + "\"), {scrollInertia:0})");
wait.until(ExpectedConditions.visibilityOfElementLocated(by));
getDriver().findElement(by).click();
Now the issue I'm having is in that second line in the method. I am passing a By object. This works for the conventional Webdriver methods on lines 1,3,4. But since we are using a custom scrollbar for our web app, I need to use that JavascriptExecutor class (the getJse()) to scroll on the proper div #id (thus passing in the 'scroll' argument). To use that JSE I just need the CSS selector, not the whole By object. If I add a breakpoint and look, the By object contains a 'selector' field that has what I want (in Eclipse there's a red square icon with an 'F' on it), but I can't seem to access it. I tried with the "by.selector" in the code above, but that is a compile error.
How can use that selector field? I'm not Java expert, so maybe I'm missing something obvious. I guess I don't understand why I can stop on a breakpoint, see the By object I created in the Variables tab, expand the By object and see the 'selector' field I want, but just can't access it.
The easy answer is that you cannot get the CSS selector from a By type, or even WebElement type. This is because the WebElements themselves are found by the By class. In case the By specified was a xpath there would be no way to populate the CSS selector.
The long answer specifically for your issue, to get the CSS Selector would be to create it using Javascript. An example would be Florent B.'s answer here. However, I didn't tried myself and I have no idea if it works for all cases.
Now, to address the general issue, instead of using document.querySelector use document.getElementById in case your element has an id.
Or by using document.evaluate to get your element by xpath. You can find an example in the answer posted here.

Contains an element with the target?

Is there any way only using CSS (no script) to check if an element such as a table contains another element such as with the target? I know that you can use the :target pseudo class for elements with the target, but I need the ability to select an element which contains the element with the target. If there's any way to using the :contains pseudo class to check if an element contains the target that'd be useful, however I've tried it a few different ways with no success. I know there isn't a parent selector which rules out looking for the parent of the element with the target URI. The only possible ways I can think of are using :contains and I don't think that'll even work with anything but text. If anyone knows some sort of trick or other selector that'd solve this issue, help would be appreciated.
First guess:
I'm having a hard time understanding your question, so my answer is offered on the assumption that your question is something like this:
Is there any way to style the parent of a targeted element?
And the answer is no, css works by cascading down the hierarchy, it can't cascade up; have a read of the following questions/answers for further details:
CSS Parent/Ancestor Selector
Is there a CSS parent selector?
Complex CSS selector for parent of active child
(There are others, if you search for 'css parent selectors')
Second guess:
If your question is:
can I find links that target other sections of the same page?
Then yes, you can (with css3 and/or using jQuery):
a[href*='#'] { /* css */ }
$("a[href*='#']") // jQuery selector
The href*='#' part is an attribute-selector, that searches the 'href' attribute for any occurrence1 of the quoted string '#' (the # being used to target same-page links).
If you're able to revise your question to make it more clear what you'd like us to help you with, then I'll be more than happy to try and be more use to you, but as it is I can only guess. Which is pretty much useless. =(
Footnotes:
Other options are:
starts with, eg: a[href^='http://'] which selects all links whose href begin with 'http://', and
ends with, eg: a[href$='.pdf'], which selects all links that end with the filetype .pdf.

Resources