Syntax error on selenium xpath expression - java

I'm building a selenium findElement by.xpath expression, very complex, and it appears there is a syntax error.
I don't really know XML language so I made mistake(s) obviously, could someone tell where are the mistake(s) ? :)
Thanks!
I have a list of projects on a web page, in each project there are sub-projects, I want a specific one, I know the name and the subName.
The html code is something like :
<table id="list_proj" class="table tablebas table-striped table-bordered">
<thead>
<tbody style="height:1em;overflow-y:scroll"></tbody>
<tbody style="height:1em;overflow-y:scroll"></tbody>
<tbody style="height:1em;overflow-y:scroll">
<tr class="caption">
<td class="app_name" style="background-color:#EFEFEF;" colspan="11">
<b>
Application SEVo
</b>
</td>
</tr>
<tr class="data"></tr>
<tr class="data"></tr>
<tr class="data">
<td title="Pas de commentaire !" style="text-align:left">
<img alt="MCO" src="/colibri/images/corner-dots.gif"></img>
MCO
</td>
<td>0.50</td>
<td></td>
<td colspan="2">
</tr>
<tr class="data">
</tbody>
<tbody style="height:1em;overflow-y:scroll"></tbody>
</table>
And my xpath expression :
driver.findElement(
By.xpath(
"((//a[contains(text(),'"+name+"')])[1]
.(ancestor::td[#class='caption'])[1]
.following-sibling::td[#class='data']
.descendant::(a[contains(text(),'"+subName+"')])[1])[1]"
));
Sorry for the mess ^^'

Use below xPath which is more better :-
//a[contains(.,'"+name+"')]/ancestor::tr/following::a[contains(.,'"+subName+"')]
for eg. :- //a[contains(.,'Application SEVo')]/ancestor::tr/following::a[contains(.,'MCO')]
Updated..
another one is :-
//a[contains(.,'"+name+"')]/following::a[contains(.,'"+subName+"')]
Hope it will help you..:)

I don't know xPath with selenium, but I think the syntax error should be in the line below
.descendant::(a[contains(text(),'"+subName+"')])[1])[1]
Should be
.descendant::(//a[contains(text(),'"+subName+"')])[1])[1]
? (note the "//a")

It should be something like:
//a[contains(text(),'"+name+"')]/ancestor::tr[#class='caption']/following-sibling::tr[#class='data']//a[contains(text(),'"+subName+"')]
Don't use index [1] everytime, If you are sure that only one element would be returned, there is no point of putting index in every descendant or ancestor call.

"((//a[contains(text(),'"+name+"')])[1]
.(ancestor::td[#class='caption'])[1]
.following-sibling::td[#class='data']
.descendant::(a[contains(text(),'"+subName+"')])[1])[1]"
There's so much wrong with this it's hard to know where to start. First, we don't know what's in the variables name and subName - if these strings contain single quotes then anything might happen (injection attack). Secondly, it seems to be using "." as a separator between steps in the path when it should use "/". Third, what follows an axis like "descendant::" must be a NodeTest, and that rules out a parenthesized expression.
I think there's a real problem in your approach. Writing a complex expression in a language you don't understand and then asking on SO what the syntax errors mean is not going to be a good way to make progress. (Once you've got rid of the syntax errors, will you then know what the XPath actually means?). Do some reading and learn the language properly; don't try to drive a car without taking driving lessons.

Related

How to resolve an ArrayIndexOutOfBoundsException in Netsuite Advanced PDF Template

I'm working on a template that will group results from a saved search building on these very helpful stackoverflow posts:
How to remove duplicate elements in a array using freemarker?
How can I group a list in an advanced pdf/html sheet in netsuite/freemarker?
The template I've created works fine for me, but when a different user tries to print with it they get an "unexpected error" from Netsuite, and when I logged into that user's account and tried to open the template and save it, I got this error:
The template cannot be saved due to the following errors:
Exception during template merging.com.netledger.templates.TemplateServiceException: Exception during template merging.java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 10
This other user has the same Netsuite admin role I do, and is using the same browser (Firefox). I even logged into her Netsuite account on my computer in Firefox and replicated the error, so it seems tied to her NS account(?).
My template is meant to simply group and add page breaks to the results of a saved search that returns salesperson commissions per transaction. Here is the code:
<body padding="0.5in 0.5in 0.5in 0.5in" size="Letter-landscape">
<#assign entitygroup = []>
<#list results as group><!--if the saved search results weren't sorted, they should have been be sorted here-->
<#assign groupID = group.formulatext> <!--"formulatext" is the sales rep or partner or dept, from the saved search-->
<#if entitygroup?seq_contains(groupID)><!-- do nothing / don't add it to the sequence-->
<#else><#assign entitygroup = entitygroup + [groupID]><!--add this entity to the sequence so it will be skipped next time -->
<table>
<tr><td colspan="9" style="font-weight:bold; font-size:12px;">${group.formulatext}</td></tr>
<tr>
<th style="width:10%;">${group.tranid#label}</th>
<th style="width:10%;">${group.trandate#label}</th>
<th style="width:10%;">${group.closedate#label}</th>
<th style="width:20%;">${group.companyname#label}</th>
<th align="right" style="width:10%;">${group.netamountnotax#label}</th>
<th align="right" style="width:10%;">${group.totalcostestimate#label}</th>
<th align="right" style="width:10%;">${group.tranestgrossprofit#label}</th>
<th align="right" style="width:10%;">${group.formulapercent#label}</th>
<th align="right" style="width:10%;">${group.formulacurrency#label}</th>
</tr>
<#assign total_tot = 0>
<#assign total_cost = 0>
<#assign total_profit = 0>
<#assign total_comm = 0>
<#list results as result>
<#if result.formulatext == groupID><!-- if the "entity" (rep, partner, dep) matches the current group-->
<tr>
<td style="width:10%;">${result.tranid}</td>
<td style="width:10%;">${result.trandate}</td>
<td style="width:10%;">${result.closedate}</td>
<td style="width:20%;">${result.companyname}</td>
<td align="right" style="width:10%;">${result.netamountnotax}</td>
<td align="right" style="width:10%;">${result.totalcostestimate}</td>
<td align="right" style="width:10%;">${result.tranestgrossprofit}</td>
<td align="right" style="width:10%;">${result.formulapercent}</td>
<td align="right" style="width:10%;">${result.formulacurrency}</td>
</tr>
<#assign total_tot = total_tot + result.netamountnotax>
<#assign total_cost = total_cost + result.totalcostestimate>
<#assign total_profit = total_profit + result.tranestgrossprofit>
<#assign total_comm = total_comm + result.formulacurrency>
</#if><!-- if the "entity" (rep, partner, dep) matches the current group-->
</#list><!--loop for the lines data-->
<tr style="font-weight:bold;">
<td> </td>
<td> </td>
<td> </td>
<td align="right"><strong>Totals:</strong></td>
<td align="right">${total_tot}</td>
<td align="right">${total_cost}</td>
<td align="right">${total_profit}</td>
<td> </td>
<td align="right">${total_comm}</td>
</tr>
</table>
<pbr />
</#if>
</#list><!-- loop for the "entity" grouping / goes back up to assign the next group-->
</body>
Any help is greatly appreciated, including taking a different approach to this problem!
[Additional info after more testing:]
As I've tried to run this down it seems that the way I'm doing my comments might have something to do with the out of bounds error, perhaps causing the template editor to think I've left out something so the query on the array had no results?
Logged in as the other admin user I deleted the entire body of my template, saved, then re-added it, and the error did not reoccur. Maybe the template engine reinterpreted my comments correctly (or as I intended)?
I've run into this error on another template now and re-did all of my comments in the freemarker way ("<#--") and again it stopped throwing the error, so that's a little more conclusive.
I hope this is helpful to somebody. I'm still working on these templates, so I'll update here if I get a more definitive answer.
Your error is likely because you are trying to save your template as an email template of some sort but are using N/render.TemplateRenderer and not N/render.mergeEmail.
I just store my custom templates as files to avoid validation errors on save.
Prior to saving I use https://try.freemarker.apache.org/ where running the template takes some time.
Unexpected errors generally mean a syntax error or some data that you are expecting isn't there. You might try logging your non-record data sources or have the user who is seeing the error try running your saved search directly to see if the UI reports issues accessing the data.
After working with this and another complex template I feel pretty confident that the inconsistent behavior I noted in my question was caused by using the wrong commenting tags: <!-- instead of <#--. Netsuite's template editor encourages the html-style comment by putting the text in a consistent brownish color (when using freemarker comments the text colors seem to ignore the comment tag completely) so it's a bit misleading. At least for my templates changing all the comments to the <#-- tag saved the day.

read td class from url using java

hello i need little help reading website content
i want to read
<tr>
<td class="text-center"><strong>This Month</strong></td>
<td class="text-center">1194</td>
<td class="text-center">22</td>
<td class="text-center">7</td>
</tr>
i make it like this but it always return nothing
if (url.toLowerCase().contains("top100arena.com") && line.contains("<strong>This Month</strong></td><td class=\"text-center\">"))
return Integer.valueOf(line.split(">")[1].replace("</td", "").replace(",", ""));
if you are considering using third-party libraries, jsoup is a good idea.
https://jsoup.org/
using css / xpath selectors, you can indicate the element you are interested in, e.g.
//tr/td[contains (strong,.)]
will find all bold entries, then we can get the parent for that element, and read all the elements
http://xpather.com/
https://devhints.io/xpath
jsoup: How to select the parent nodes, which have children satisfying a condition

Selenium WebDriver Java / JUnit - Getting table element

I have the following table:
<table>
<tbody>
<tr>
<td>
</td>
<td>
User1
</td>
</tr>
<tr>
<td>
</td>
<td>
User2
</td>
</tr>
</tbody>
</table>
I want to find the a-tag of the tr, where the data User2 is in the same row. I know that I can find an a-tag with partial link like findElement(By.partialLinkText("/ResetPassword/")); (the number 2 can change, so I canĀ“t use it as seperator). But I need to seperate it by User. Is there a solution like tr.td.text("User2") > findElement(By.partialLinkText("/ResetPassword/"));?
This XPath should do the trick for you. .//tr[td[normalize-space(text())='User2']]//a Just keep changing "User2" part with the desired user value.
Hi I was wondering if you could use the .getValue() statement with /#a at the end of the xpath to locate the attribute "a".
Main thing to do is find a bulletproof xpath to locate the User2 row once you have done that finding the value of "a" should be easy enough.
I hope this helps
U can try something like this(not sure though)-
List<WebElement> list=table.findElements(By.tagName("tr"));
List<WebElement> tdvalues=null;
for(WebElement web:list){
tdvalues=web.findElements(By.tagName("td"));
if(tdvalues.contains("User2")){
System.out.println(tdvalues.get(0).getText());//0th position contains the link
}
tdvalues.clear();
}

Regex to iterate over an table and extract the td information inside an div using java

Hello i know parsing HTML with regex is not efficient .But i need to do with regex i have no other option.
HTML
<div class="test">
<h2>what</h2>
<table cellpadding="0" cellspacing="0">
<tbody>
<tr>
<th>Example </th>
<td> ui </td>
</tr>
<tr>
<th>Sample </th>
<td>123 </td>
</tr>
</tbody>
</table>
</div>
I tried to do it using (?s)<div class="test">.*<td>(.*?)</td>.*</div> it extracts only the last value can any one tell me what is the issue?
Why only using Regular expression, how about some jquery??
$("div.test > td").each(function() {
var $this = $(this);
alert( $this.text() )
});
The * operator reads as much as is possible, so the first .* also swallows most of the text.
Try with .*?. The question mark reduces this behaviour and lets * only take as much as necessary, not as much as possible.
Otherwise please be more specific what parts you really want and which not.

how to implement this pattern using JSP

I'm new to using JSP and need to figure out how to do this. I'd appreciate any pointers on how to do this ?
I need to display images in this table-like structure. To simplify the problem,
A B C
D E F
G H I
where each of these elements are a part of the Set names in action class.
Set<String> names = new HashSet<String>(0);
names.add("A");
names.add("B");
names.add("C");
names.add("D");
names.add("E");
names.add("F");
names.add("G");
names.add("H");
names.add("I");
Its fairly trivial to do it in java, however, I am having a hard time to figure out, how do I ask the iterator to point to next element manually.
<s:iterator value="names">
<s:property/>
I'd now like to point iterator to point to next or run a nested iterator loop here.
</s:iterator>
You can use JSTL forEach loop. You can find a number of examples here.
You can easily accomplish it with JSTL:
<table>
<tr>
<c:forEach items="names" var="name" varStatus="i">
<c:if test="${!i.first && !i.last && i.index % 3 == 0}">
</tr>
<tr>
</c:if>
<td><c:out value="${name}" /></td>
</c:forEach>
</tr>
</table>
Doing so, a new line (</tr><tr>) will be added every 3 elements.
(not tested)
As CoolBeans said, you can use JSTL forEach loop.
If you'd like to see an example of that (alongside other good JSTL examples), check out JSTL Examples.
"Iterating over data structures" has some info and examples on what you're trying to do.

Categories