Getting text following a label in XPath - java

I am trying to do some tests using Selenium and I am facing some problems. Suppose I have the following:
<div class="itemize-row">
<p class="subText">
<span class="item-label">Card Color:</span> Mandarin
<span class="item-label">Colored Mug:</span> Red
</p>
</div>
Could anybody tell me how to retrieve data "Red" using XPath or CSS?

This XPath,
//span[#class='item-label' and .='Colored Mug:']/following-sibling::text()[1]
will return "Red" as requested.
Generally speaking, yes, but in Selenium, you cannot point to the text
nodes. XPath expressions have to point to "elements". – alecxe
Ok, to account for Selenium limitations, this XPath,
substring-after(//span[#class='item-label' and .='Colored Mug:']/.., 'Colored Mug:')
which takes advantage of the fact that your target is at the end of the string value of the parent of the label, will also return "Red" as requested.

Related

How to check href of an element found using xpath contains text()

I'm trying to find an element by the text it contains, then check that that element also has a link to a particular place. I'm using selenium/java.
I'm trying to find elements by text when I can to minimise how many changes I will need to make if the UI is updated (reduce test maintenance costs).
I've tried the following, but the assert fails as the getAttribute ends up being null.
WebElement newsHeadlineTemplate = driver.findElement(By.xpath("//*[contains(text(), 'News Headline')]"));
Assert.assertEquals("Template not clickable", "/news/create/new", newsHeadlineTemplate.getAttribute("href"));
HTML for element I'm trying to find/use:
<div class="columns">
<div class="column is-one-third">
<p>News Headline</p>
</div>
</div>
I'm still fairly new to selenium so any help is very much appreciated.
Your XPath selector is a little bit wrong, you're matching <p> tag and you need to match the <a> tag which is the following-sibling for the <p> tag.
So you need to amend your expression to look like:
//p[text()='News Headline']/following-sibling::a
More information:
XPath Tutorial
XPath Axes
XPath Operators & Functions

How to get Css selector when using java?

I am having trouble in selecting a selector when I am trying to select it as a 'css-selector'
I have this selector:
<div role="button" class="jss300 jss299" tabindex="-1">
<span class="jss313">system-all</span></div>
</div>
and I am trying to get the css-selector from it, I tried this way:
"div[class~='system-paloaltonetworks']"
and my need is to get the text from the selector, in this case I want to get "system-paloaltonetworks" into string variable.
hope now the question is clear.
"system-paloaltonetworks" is the element text, not the class attribute (the class is jss313). You can't locate it with cssSelector you need to use xpath (you should also notice the element has span tag, not div)
driver.findElement(By.xpath("//span[text()='system-paloaltonetworks']"));
You are using class~= but aren't comparing with the class...
You try: driver.findElement(By.xpath("//*[#class='jss313']"));

getText(), JavascriptExecutor, innerText, textContent only returning null from a read only field

Critical UPDATE:
It appears that, when we reach the page by using Selenium, the read only fields never loads. It's a document.jsp page which loads. But when we reach the page manually, we get that data. I am using ChromeDriver. I think that explains why I am unable to retrieve the read only fields while using Selenium. If anyone knows of a work around, please let me know.
UPDATE: Since writing this question I have tried innerText again with CSS but it returns " " instead of "Bronze". So it looks like I am able to retrieve something. But it's . How can I get "Bronze"
I am trying to retrieve the text from the field of a read only element using ChromDriver. Below is the HTML code. I want to retrieve the String "Bronze"
<div class="column label-left" style="width:25%">
<div class="form-item clearfix null" id="attr_wrapper_1_offerType_t">
<label class="form-label" for="offerType_t" style="width: 130px"><span style="padding-right: 5px">Offer Type:</span></label>
<div class="form-element field-wrapper" id="field_wrapper_1_offerType_t" style="padding-left:130px">
<div class="field" message=""><span class="readonly-wrapper" id="readonly_1_offerType_t">New Business</span></div>
<div id="msg_1_offerType_t" class="error-hover" data-action-message="" message=""></div>
</div>
</div>
<div class="form-item clearfix null" id="attr_wrapper_1_dealClass_t">
<label class="form-label" for="dealClass_t" style="width: 130px"><span style="padding-right: 5px">Deal Class:</span></label>
<div class="form-element field-wrapper" id="field_wrapper_1_dealClass_t" style="padding-left:130px">
<div class="field" message=""><span class="readonly-wrapper" id="readonly_1_dealClass_t">Bronze</span></div>
<div id="msg_1_dealClass_t" class="error-hover" data-action-message="" message=""></div>
</div>
</div>
<div class="form-item clearfix attr-spacer" style="height: 25px;"></div>
<div class="form-item clearfix attr-spacer" style="height: 25px;"></div>
</div>
I am using id="readonly_1_dealClass_t" but it returns null.
I have also tried xpath="//span[contains(#id,"dealClass")]". It returns null too.
First of all, getText() on id, xpath, CSS all of them returns null. Then I tried all the below options.
I have also tried using JavascriptExecutor and retrieving the text(), but it doesn't help either.
I have also tried innerText and textContent for the above id but without success.
I have waits for 60 seconds until element is visible. It returns true. Which means its visible. But it just refuses to retrieve the string "Bronze".
I also tried getAttribute("value") too. Without success obviously.
I also thought I could use the id="field_wrapper_1_dealClass_t" and use innerText on it. Still no success. That one just returns a lot of whitespace.
What else can I try to retrieve the string "Bronze"?
PS: I don't have issues with Firefox. Chrome just refuses to go ahead. And business need is to stick with only Chrome right now. So I have to get this working in Chrome. Please help.
I hope I have been clear and I hope I have furnished enough HTML code.
UPDATE:
This returns [] for value, ie blank.
final String script = "return arguments[0].getAttribute('innerHTML')";
WebElement randomRow = driver.findElement(By.xpath("(//div[#class='field']/span)[21]"));
String value = (String) ((JavascriptExecutor) driver).executeScript(script, randomRow);
UPDATE 2:
This returns [ ] too:
String myText = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//span[#class='readonly-wrapper' and starts-with(#id,'readonly_') and contains(#id,'_dealClass_t')]"))).getAttribute("innerHTML");
As per the HTML you have shared to retrieve the String Bronze you have to induce WebDriverWait for the visibility of the element as follows :
String myText = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//span[#class='readonly-wrapper' and starts-with(#id,'readonly_') and contains(#id,'_dealClass_t')]"))).getAttribute("innerHTML");
I think you'll be able to get that using below by fetching 'innerHTML' attribute:
final String script = "return arguments[0].getAttribute('innerHTML')";
WebElement randomRow = driver.findElement(By.xpath("(//div[#class='field']/span)[21]"));
String value = (String) ((JavascriptExecutor) driver).executeScript(script, randomRow);
So, after several trial and error runs it turns out that the page does not load completely when logging into it using Selenium. I copied the URL which opens using Selenium and compared it with the one which opens manually. They were different. The part after formCreate right after document.jsp was completely different for the Selenium loaded page. So, to avoid too much complications, I used driver.get("url") with the "url" being the actual URL and then let it open. This loaded the fields correctly and I was able to do the validations.

How to extract string from HTML by XPath into Java?

I'm writing some automated tests with Cucumber and Selenium. Currently, I'm trying to write a function to select the passed date in a calendar picker. I need to use the current year that is displayed in the calendar when it pops up to determine some logic.
However, I can't for the life of me figure out the correct syntax to get the value of the current year into Java to work with it further. The first div is the reliably non-ambiguous tag by which I navigate to the calendar that I need to work with, I can even somehow select the year(in this case "2017") in the browser dev console, but I can't pass it into Java.
Relevant HTML:
<ib-selector class="float-rg fblock40" ng-if="!hideYearSelector" initial-label="dateYear" next-handler="nextYear()" prev-handler="prevYear()">
<div class="calendar-month-year">
<span class="arrow-cal-left" ng-click="prevHandler()" role="button" tabindex="0">
</span> 2017
<span class="arrow-cal-right" ng-click="nextHandler()" role="button" tabindex="0">
</span>
</div>
</ib-selector>
Latest attempt at extracting the year:
String currentYear = driver.findElement(By.xpath("//ib-selector[#initial-label='dateYear']/div/text()")).getAttribute("data");
Exception it generates:
org.openqa.selenium.InvalidSelectorException: invalid selector: The result of the xpath expression "//ib-selector[#initial-label='dateYear']/div/text()" is: [object Text]. It should be an element.
with xpath (assuming that your's path is OK, as HTML in exmple actually is not relevant):
String text = driver.findElement(By.xpath("//ib-selector[#initial-label='dateYear']/div")).getText()
or if you want to use element:
WebElement el = driver.findElement(By.xPath("//ib-selector[#initial-label='dateYear']/div"));
String text = el.getText();
here is path relevant to HTML from the example:
String text = driver.findElement(By.cssSelector(".calendar-month-year")).getText()
Try to remove the "/text()" part in your xpath expression.

Select by "name" in JSoup

I have multiple div's in a webpage URL that I have to parse which have the same class name but different names with no id's.
for eg.
<div class="answer" style="display: block;" name="yyy" oldblock="block" jQuery1317140119108="11">
and
<div class="answer" style="display: block;" name="xxx" oldblock="block" jQuery1317140119108="11">
I want to select data and parse from only one of the div's say namely (name="yyy") (the content inside the div's are <href> links which differ for each class.
I've looked up the selector syntax in the Jsoup webpage but can't get a way to work around it. Can you please help me with this or let me know if I'm missing something?
Use the [attributename=attributevalue] selector.
Elements xxxDivs = document.select("div.answer[name=xxx]");
// ...
Elements yyyDivs = document.select("div.answer[name=yyy]");
// ...

Categories