html items share same xpath in robot - html

I would like to read a sibling of a text in my html code.
This text can be once or more times in my html
using inspector, this works:
xpath://*[angular-parent//div[text()='Text to find']/following-sibling::div//angular-child//span]
but when I try to read from html:
${value} Get text ${signal}
it only give me the first value. How can I get all of them?

With the assumption that you desire a list of values, I created the below example that uses the Get Text keyword but can easily be adapted to suit your needs:
*** Settings ***
Library SeleniumLibrary
Library Collections
*** Test Cases ***
Get Multiple Element Values
Open Browser https://www.w3schools.com/default.asp chrome
#{webelements} Get WebElements xpath://a[#class='w3-bar-item w3-button']
#{webelements_text} Create List
:FOR ${webelement} IN #{webelements}
\ ${text} Get Text ${webelement}
\ Append To List ${webelements_text} ${text}
Log List ${webelements_text}
[Teardown] Close Browser

Related

finding xpath for an element just below the <body> tag

I need to find xpath for an element which is not associated with any html tags .Please refer attachment for reference.
I tried to find it using driver.findElement(By.xpath("/html/body/"));
but its not working, I need to find text as shown below in image
0 records found
through Xpath or any alternative way
The text you are interested in is not a part of any element. It is a text node. Selenium doesn't allow you to select a textNode and text node are not actionable also.
So you can get either the page source and check for the presence of 0 records found. If that what you need to validate. Or you need to get the text using regex
(\d+) record found
Depending on the language you use you will run that pattern through and get the number from the text
Edit-1
Below is a sample code which extract google results, you can customize it to your page
ChromeDriver driver = new ChromeDriver();
driver.get("https://www.google.com");
driver.findElement(By.name("q")).sendKeys("tarun lalwani");
driver.findElement(By.name("btnK")).click();
String pageData = driver.getPageSource();
Pattern pattern = Pattern.compile("About ([0-9,]+) results");
Matcher matcher = pattern.matcher(pageData);
matcher.find();
System.out.println("Results: " + matcher.group(1));

Display text as html markup

I have a problem which is probably trivially easy but I can't seem to get it working. Using this post, I do a search using Regex in a text string to convert any links into html markup, but when it comes to display on the page it just displays like this:
this is link
<a href='http://www.google.com'>http://www.google.com</a>
In the view I have:
<p>#news.Body</p>
edit: great my question is now displaying how I want. So now to the actual question, how do I get the page displaying an actual link instead of the code when displayed to the user.
Use `` around your variable (e.g.)
Use "{}" icon in toolbar to insert code
Indent your code by one empty line, 4 spaces and leading empty line
E.g.:
Like this
You can edit this answer to see raw output

Not able to select a text using selenium

I have a readymade code and i'm trying to write tests for it using selenium. This is how my code looks like in element tab of chrome:
<table id="xyz">
<tbody>
<tr>...</tr>
"
I am not able to retrieve this text.
"
</tbody>
</table>
Doing this $x("//*[contains(text(),'I am not able to retrieve this text')]"); in console tab of chrome shows no results. I'm able to get text by this command if the text is defined in a div, span etc. (Also case sensitivity is not a problem).
In code that text is appended in tbody using jQuery('tbody').append( abc() ); and abc() function returns this text in this way pqr.html();
Now my questions is what xpath expression should i write to grab this text? And i am looking for a pure xpath expression i.e no java functions etc.
contains() expects singular value as the first parameter. An HTML element may have more than one text nodes children in it, in which case, your attempted XPath will evaluates only the first text node. According to the sample HTML posted, the first text node of <tbody> which will be evaluated consists of newline and some spaces, hence your XPath didn't consider <tbody> a match and returned no result.
To avoid the problem explained above, use contains() in predicate for individual text nodes like the following :
//*[text()[contains(.,'I am not able to retrieve this text')]]
or this way if you want to return the text node itself instead of the parent element :
//*/text()[contains(.,'I am not able to retrieve this text')]
That table element is probably within a frame. To access contents within a frame you need to first switch to it. You can use the "switch to" method in selenium. Refer this answer and this one.
For the same reason it is not working in the Chrome Dev Tools console. In the console tab, there is dropdown containing a list of frames. Make sure you select the correct frame in which the specific element exist and then execute your XPath.

Create an NCX file with Notepad++ and Regular expression

I have a HTML Table of Contents page containing list of book chapters with hyperlinks:
Multimedia Implementation<br/>
Table of Contents<br/>
About the Author<br/>
About the Technical Reviewers<br/>
Acknowledgments<br/>
Part I: Introduction and Overview<br/>
Chapter 1. Technical Overview<br/>
...
I want create NCX file for a Kindle book which must contain details as follows:
<navPoint id="n1" playOrder="1">
<navLabel>
<text>Multimedia Implementation</text>
</navLabel>
<content src="final/main.html"/>
</navPoint>
<navPoint id="n2" playOrder="2">
<navLabel>
<text>Table of Contents</text>
</navLabel>
<content src="final/toc.html"/>
</navPoint>
<navPoint id="n3" playOrder="3">
<navLabel>
<text>About the Author</text>
</navLabel>
<content src="final/pref01.html"/>
</navPoint>
...
I'm using Notepad++: is it possible automate this process with regular expression?
You cannot do everything using regex.. you can split the problem into two parts..
generate strings like <navPoint id="n1" playOrder="1"> using program logic (increment variable)
remaining you can do with regex
Use the following regex to match:
<a\shref="([^"]*)">([^<]*)<\/a><br\/>
And replace with:
(generated string)<navLabel>\n<text>\2</text>\n<content src="\1"/>\n</navPoint>
See DEMO
Yes, it is possibly to replace the links with <navpoint> tags. The only thing I found no solution for is the incremental numbering of the <navpoint> attributes id and playOrder...
The following regex will do most of the work:
/^<a[^>]*href="([^"]+)"[^>]*([^<]+).*$/gm
substitute with:
<navpoint id="n" playOrder="">\n<navLabel><text>$2</text></navLabel>\n<content src="$1" />\n</navpoint>\n
Regex details
/^<a .. only parse lines that start with an `<a` tag
.*href=" .. find the first occurance of `href="`
([^"]+) .. capture the text and stop when a " is found
"[^>]*> .. find the end of the <a> tag
([^<]+) .. capture the text and stop when a < is found (i.e. the </a> tag)
.*$/ .. continue to end of the line
gm .. search the whole string and parse each line individually
More detailled (but also more confusing) explanation is here:
https://regex101.com/r/gA0yJ2/1
This link also demonstrates how the regex is working. You can test changes there if you like

Emmet - Wrap with Abbreviation - Token that represents the wrapped text i.e. {original text}

I'm attempting to convert a list of URLs into HTML links as lazily as possible:
www.annaandsally.com.au
www.babylush.com.au
www.babysgotstyle.com.au
... etc
Using wrap in abbreviation, I'd like to do something like: a[href="http://${1}/"]*
The expanded abbreviation would result in:
www.annaandsally.com.au
www.babylush.com.au
www.babysgotstyle.com.au
... etc
The missing piece of the puzzle is an abbreviation token that represents the text being wrapped.
Any idea if this can be done?
If they are already on their own lines (which in the question, they look like they are), a simple Find and Replace with RegEx turned on will work. The Params are as follows:
Find What:
(.+)
Replace With:
$1
Before
After
Sergey from Emmet was kind enough to point me in the right direction. The $# token contains the original content:
a[href="http://$#/"]*>{$#}
By specifying $# as the href attribute, the original content is no longer 'wrapped' and must be be reinserted via {$#}.
http://docs.emmet.io/actions/wrap-with-abbreviation/#controlling-output-position