inline image alt attribute and getText() - selenium

I got something like this:
<div id=soandso>
Having a
<img src="cat.gif" alt="Meow">
always helps
</div>
I have no problems finding the div element, when I invoke getText() I would wish to receive "Having a Meow always helps", but instead I get the text without the alt (Meow) description.
I agree this is the expected behaviour, but this is not what I need.
How can I preferably inline the alt text or at least get the text chunks in sequence with the inline image to verify the proper placement of the image inside the text?

selenium-webdriver works that way in both scenarios,
considers "alt" as attribute of image tag and not as element text for Div.
Considers "Having a always helps" as innerText of Div element.
i would suggest....to extract the Div text and img (alt) text separately. if text follows a pattern, try to identify sequence after or before which image attribute will be displayed.
WebElement Div_elem=Driver.findElement(By.id("soandso"));
String Div_text = Div_elem.getText();
String img_text=Div_elem.findElement(By.tagName("img")).getAttribute("alt");
would be glad if it helps

I found a solution here: How to get text of an element in Selenium WebDriver (via the Python api) without including child element text?
His suggested solution:
def get_text_excluding_children(driver, element):
return driver.execute_script("""
return jQuery(arguments[0]).contents().filter(function() {
return this.nodeType == Node.TEXT_NODE;
}).text();
""", element)
The element passed to the function can be something obtained from the find_element...() methods (i.e. it can be a WebElement object).
basically suggests that you use jQuery to get the text within the div.

Related

Find xpath of element knowing a part of href attribute only selenium ide ui vision katalon recorder

I need to detect via xpath an element (image with href) but i know a part of href only
This is the html
<img src="//user/banners/16/08/1614708.gif" alt="AAA" data-tip="BBB" currentitem="false" class="" width="468" height="60">
I know the id 123456 (part of href)
I tried this xpath that recognize element with a part of href but working in text link only
xpath=//a[contains(#href, "123456")]
How can i detect the element using a part of href only ?
I need xpath only please.
You need get /img in //a where href attribute contains() or ends-with() your id
This is XPATH that you need. At least i would use this XPATH in this situation
//a[ends-with(#href, 'your-id-here')]/img
You can use regular expresions. Something like
driver.find_element_by_xpath("//input[starts-with (#name,'Tut')]")
or as you described
driver.find_element_by_xpath("//input[contains(#name,'sel')]").
Be awere of one thing, do not use double quotes, for the string you are searching as atribute value. Use a single quote like I previously described.

How does dot(.) in xpath to take multiple form in identifying an element and matching a text

I have the below dom structure:
<h3 class="popover-title">
<div class="popup-title">
<div class="title-txt">Associated Elements &nbsp(5)</div>
</div>
</h3>
I am trying to write an xpath which will identify the title "Associated Elements" under h3 tag.
When my xpath is
//div[contains(#class, popover)]//h3[contains(.,'Associated Elements')]
the element is identified.
However when my xpath is
//div[contains(#class, popover)]//h3[contains(text(),'Associated Elements')]
the element is not identified.
As per my understanding the dot(.) is a replacement for text(), but then why does it not identify the element when I use the text() function.
However, for another dom structure:
<h3 class="popover-title">
<a class="btn-popover" href="#">x</a>
"Associated Elements"
</h3>
The xpath :
//div[contains(#class, popover)]//h3[contains(text(),'Associated Elements')]
&
//div[contains(#class, popover)]//h3[contains(.,'Associated Elements')]
works fine.
Can someone please explain the behaviour of dot(.) under both these scenarios?
Is there a better way to write an xpath that holds good for both the exmaples? Please suggest.
As selenium is tagged so this answer would be based on xpath-1.0 and the associated XML Path Language (XPath) Version 1.0 specifications.
contains(string, string)
The function boolean contains(string, string) returns true if the first argument string contains the second argument string, and otherwise returns false. As an example:
//h3[contains(.,'Associated Elements')]
Text Nodes
Character data is grouped into text nodes. As much character data as possible is grouped into each text node. The string-value of a text node is the character data. A text node always has at least one character of data. In the below example, text() selects all text node children of the context node:
//h3[text()='Associated Elements']
In your usecase, within the HTML the text Associated Elements &nbsp(5) have which is alternatively referred to as a fixed space or hard space, NBSP (non-breaking space) used in programming to create a space in a line that cannot be broken by word wrap. Within HTML, allows you to create multiple spaces that are visible on a web page and not only in the source code.
Analyzing your code trials
Your first code trial with:
//h3[contains(.,'Associated Elements')]
locates the element as it successfully identifies with partial text Associated Elements
Your second code trial with:
//h3[contains(text(),'Associated Elements')]
fails as the element contains some more characters e.g. in addition to the text Associated Elements.
Reference
You can find a couple of relevant discussions in:
How to locate the button element using Selenium through Python
What does contains(., 'some text') refers to within xpath used in Selenium
While fetching all links,Ignore logout link from the loop and continue navigation in selenium java
The text() in contains(text(),'Associated Elements') is a selector that matches all of the text nodes that are children of the context node - it returns a node-set. That node-set is converted to string and passed to the contains() function.
text() isn't a function but a node test. It is used to select all text-node children of the context node. So, if the context node is an element named x, then text() selects all text-node children of x.
When you use contains(., 'Associated Elements') only an individual text node is passed to the function and it is able to uniquely match the text.
Note: copied and edited from this and this post.

Selenium XPath find element where second text child element contains certain text (use contains on array item)

The page contains a multi-select dropdown (similar to the one below)
The html code looks like the below:
<div class="button-and-dropdown-div>
<button class="Multi-Select-Button">multi-select button</button>
<div class="dropdown-containing-options>
<label class="dropdown-item">
<input class="checkbox">
"
Name
"
</label>
<label class="dropdown-item">
<input class="checkbox">
"
Address
"
</label>
</div>
After testing in firefox developer tools, I was finally able to figure out the xPath needed in order to get the text for a certain label ...
The below XPath statement will return the the text "Phone"
$x("(//label[#class='dropdown-item'])[4]/text()[2]")
The label contains multiple text items (although it looks like there is just one text object when looking at the UI) in the label element. There are actually two text elements within each label element. The first is always empty, the second contains the actual text (as shown in the below image when observing the element through the Firefox developer tool's console window):
Question:
How do I modify the XPath shown above in order to use in Selenium's FindElement?
Driver.FindElement(By.XPath("?"));
I know how to use the contains tool, but apparently not with more complex XPath statements. I was pretty sure one of the below would work but they did not (develop tool complain of a syntax error):
$x("(//label[#class='dropdown-item' and text()[2][contains(., 'Name')]]")
$x("(//label[#class='dropdown-item' and contains(text()[2], 'Name')]")
I am using the 'contains' in order to avoid white-space conflicts.
Additional for learning purposes (good for XPath debugging):
just in case anyone comes across this who is new to XPath, I wanted to show what the data structure of these label objects looked like. You can explore the data structure of objects within your webpage by using the Firefox Console window within the developer tools (F12). As you can see, the label element contains three sub-items; text which is empty, then the inpput checkbox, then some more text which has the actual text in it (not ideal). In the picture below, you can see the part of the webpage that corresponds to the label data structure.
If you are looking to find the element that contains "Name" given the HTML above, you can use
//label[#class='dropdown-item'][contains(.,'Name')]
So finally got it to work. The Firefox developer environment was correct when it stated there was a syntax problem with the XPath strings.
The following XPath string finally returned the desired result:
$x("//label[#class='dropdown-item' and contains(text()[2], 'Name')]")

How to extract the text from a child node which is within a <div> tag through Selenium and WebDriver?

I need to get the value 107801307 that is inside a specific Div but there are several other Divs in the path before getting into that DIV I need. Can anyone help?
Below is the image with the information that I need to extract from the DIV.
As per the HTML you have provided, to extract the text 107801307 you can use the following solution:
Java:
String myText = driver.findElement(By.xpath("//b[#class='label_tratamento'][contains(.,'Ban Claro')]//following::span[1]").getAttribute("innerHTML");
Python:
myText = driver.find_element_by_xpath("//b[#class='label_tratamento'][contains(.,'Ban Claro')]//following::span[1]").get_attribute("innerHTML")
Research xpath locators to find the specific element you want.
Assuming you were using Java, the code would be:
webdriver.findElement(By.xpath("//b[text()='Ban Claro']/following::span").getText();
or
webdriver.findElement(By.xpath("//b[#class='label_tratamento']/following::span").getText();
Use:
driver.findElement(By.xpath(("XPATH OF DIV HERE")[Index of the div where span is. Example: 4)/span)).getText();

how to locate element with selenium webdriver for below html

I have an issue clicking on the below HTML:
<div id="P7d2205a39cb24114b60b80b3c14cc45b_1_26iT0C0x0" style="word-wrap:break-word;white-space:pre-wrap;font-weight:500;" class="Ab73b430b430a49ebb0a0e8a49c8d71af3"><a tabindex="1" style="cursor:pointer;" onclick="var rp=$get('ctl00_ContentPlaceHolder1_ReportViewer1_ctl10_ReportControl');if(rp&&rp.control)rp.control.InvokeReportAction('Toggle','26iT0C0x0');return false;" onkeypress="if(event.keyCode == 13 || event.which == 13){var rp=$get('ctl00_ContentPlaceHolder1_ReportViewer1_ctl10_ReportControl');if(rp&&rp.control)rp.control.InvokeReportAction('Toggle','26iT0C0x0');}return false;"><img border="0" src="/Reserved.ReportViewerWebControl.axd?OpType=Resource&Version=10.0.30319.1&Name=Microsoft.ReportingServices.Rendering.HtmlRenderer.RendererResources.TogglePlus.gif" alt="+"></a> 2013</div>
I have used the below script to click anchor inside a div tag. For the above html code it is not fixed only end part of id example "26iT0C0x0" is fixed. The script that I have used is:
WebElement e1=wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//div[ends-with(#id,'26iT0C0x0')]/a")));
e1.click();
You can use the 'contains' method within an xpath lookup:
driver.findElement(By.xpath("//div[contains(#id,'26iT0C0x0')]")
I would recommend you to consider CSS selector alternative as CSS working faster, than xpath.
So 'contains' in attribute in CSS stands for '*=', for example
if we want to find attribute by 'CSS' ending in this: <htmlTag A="blablaCSS" > we need do the following:
String CSSselector="htmlTag[A*=CSS]";
and you get this element searched.
So considering your example CSS selector be like:
String cssSearched="div[id*=26iT0C0x0] a";
also try to click not on link - a
but on parent div as well:
String cssSearched="div[id*=26iT0C0x0]";
driver.findElement(By.cssSelector(cssSearched));
hope this works for you.
As Mark Rwolands already mentioned: the xpath-Function 'ends-with()' isn't supported in Selenium 2.
Also, if you maybe consider to use chromeDriver in the future, I would recommend clicking the image, not the anchor, see:
https://sites.google.com/a/chromium.org/chromedriver/help/clicking-issues
edit:
Also your IDs are looking generated. I wouldn't count on them for a stable test-environment.