I,m using XMLunit for comparing XMLs.i have xmls as below.
<e>
<accounts>
<number>56482</number>
<name>ererr</name>
</accounts>
</e>
<indicator>
<e>
<name>name1</name>
<value>value1<value>
</e>
<e>
<name>name2</name>
<value>value2<value>
</e>
</indicators>
as in above xml, I need to write different element selector conditions for different e i.e I need to write a separate element selector condition for //e
and different element selector condition for //indicator/e. right now im using below code
ElementSelectors.conditionalBuilder()
.whenElementIsNamed("e").thenUse(ElementSelectors.byXPath("//indicator/e/name",ElementSelectors.byNameAndText))
.elseUse(ElementSelectors.byName)
.build();
but this condition best suited for //indicator/e. I need to have a separate condition like
ElementSelectors.conditionalBuilder()
.whenElementIsNamed("e").thenUse(ElementSelectors.byXPath("//e/number",ElementSelectors.byNameAndText))
.elseUse(ElementSelectors.byName)
.build();
I'm struck here and please suggest me on overcoming this issue.
The conditional builder offers a more generic when which accepts a Predicate<? super Element> so you can code up more specific conditions like
when(e => "e".equals(e.getNodeName())
&& "indicator".equals(e.getParentNode().getNodeName()))
of course you better add some null-checks and error handling, but you get the idea.
Related
Consider this xpath which should always return one element.
//div[#id='MyDiv123']/div[contains(#class, 'super')]
Assume that we won't add anymore divs whose class is super. Given that info, I don't think that it is a good idea to use /div[contains(#class, 'super')]because the xpath will break if div[contains(#class, 'super')] is placed inside another element.
Shouldn't we be using //div[contains(#class, 'super')] instead ?
I don't like using XPaths for locators that can be written as a CSS selector. I think it's much simpler as
#MyDiv123 > div.super
or just
div.super
if it's unique on the page.
XPath contains() is a string match. All the elements below will match your XPath locator but none of them will match the CSS selectors above.
<div class="super-duper" ...>
<div class="superior" ...>
<div class="abcsuperdef" ...>
... you get the idea...
There is no defined Best Practices while writing xpaths. It all boils down to how effective xpath can be written.
I don't see any issue with the xpath as :
//div[#id='MyDiv123']/div[contains(#class, 'super')]
Of-coarse there ca be some improvements as follows :
As an enduser you won't be sure how the class attribute super impacts the HTML or which elements have this attribute. So in that case to identify the WebElement uniquely it would be wise to include the ancestor <div> tag with id as MyDiv123.
But it doesn't looks like the classname super can be dynamic. Hence you can avoid the keyword contains within the xpath and rewrite it as :
//div[#id='MyDiv123']/div[#class='super']
Is there a way to do the following in Moqui?
Say I have a list of parent categories (or classifications etc.)... Taking Request categories:
<entity-find entity-name="mantle.request.RequestCategory" list="parentCategoryList">
<econdition field-name="parentCategoryId" operator="is-null" />
</entity-find>
And I want to use 'parentCategoryList' to produce a sub-list for EACH parent category, to display separate form-lists on screen:
Something like:
<iterate list="parentCategoryList" entry="thisCategory" >
<entity-find entity-name="mantle.request.RequestCategory" list="categoryList">
<econdition field-name="parentCategoryId" from="thisCategory.requestCategoryId" />
</entity-find>
<!-- I include the following only to give an idea of what I am trying to do.
It is incorrect and incomplete -->
<script>listOfLists.add(categoryList)</script>
</iterate>
Then use that 'listOfLists' to iterate a form-list, supplying the form-list 'name' and 'list' sequentially for each list in the list. (I know you can't use iterate outside of actions, and you can't use forms inside of actions.)
I may well be thinking about this in the wrong way.
You can iterate within the screen.widgets element, just use section-iterate. There are limitations to how much you can nest these (the current template macros for XML Screens/Forms only support so much), but you can do quite a bit. There are example of this in SimpleScreens, like the OrderDetail.xml screen iterating over order parts.
Dear Selenium Webdriver 2 Experts,
I am new to this framework and need your advice on some XPath related questions on the following webpage XHTML snippet:
<dl class="cN-featDetails">
<dt class="propertytype">Property type</dt>
<!-- line 3 --> <dd id="ctl00_ctl00_Content_Content_SrchResLst_rptResult_ctl04_lstTemplate_ddPropertyType" class="propertytype type-house" title="Property type: House">House</dd>
<!-- line 3a --> <!-- or class="propertytype type-townhouse"--->
.......
<div class="main-wrap">
<div class="s-prodDetails">
<a id="ctl00_ctl00_Content_Content_SrchResLst_rptResult_ctl04_lstTemplate_hypMainThumb" class="photo contain" href="/Property/For-Sale/House/LA/St Gabriel/?adid=2009938763">img id="ctl00_ctl00_Content_Content_SrchResLst_rptResult_ctl04_lstTemplate_imgMainThumb" title="44 Crown Street, St Gabriel" src="http://images.abc.com/img/2012814/2778/2009938763_1_PM.JPG?mod=121010-210000" alt="Main photo of 44 Crown Street, St Gabriel - More Details" style="border-width:0px;" /></a>
<div class="description">
<h4><span id="ctl00_ctl00_Content_Content_SrchResLst_rptResult_ctl04_lstTemplate_lblPrice">Offers Over $900,000 </span></h4>
<h5>SOLD BY WAISE YUSOFZAI</h5><p>CHARACTER FAMILY HOME... Filled with warmth and charm, is a very well maintained family home in a quiet level street. Be...</p>
</div>
<a id="ctl00_ctl00_Content_Content_SrchResLst_rptResult_ctl04_lstTemplate_hypMoreDetails" class="button" href="/Property/For-Sale/House/LA/St Gabriel/?adid=2009938763">More Details</a>
<dl id="ctl00_ctl00_Content_Content_SrchResLst_rptResult_ctl04_lstTemplate_dlAgent" class="agent">
<!-- line 19 --> <dt>Advertiser</dt>
<!-- line 20 --> <dd class="contain">
<!-- line 20a --> <!-- or class="" -->
<img id="ctl00_ctl00_Content_Content_SrchResLst_rptResult_ctl04_lstTemplate_imgAgencyLogo" title="Carmen Jones Realty" src="http://images.abc.com/img/Agencys/2778/searchlogo_2778.GIF" style="border-width:0px;" />
</dd>
</dl>
</div>
( a ) How to test whether an element exist or not? e.g. either line 3 or 3a exist but not both. The findElement() method will cause an exception which is what I am trying avoid. Another option is
use findElements() before checking whether its collection list result is empty or not. This approach seems to be a long winded way of doing it. Are there any other simpler way to validate the existence
of an element without the risk of causing an exception? The following statements did not work or cause exception:
WebElement resultsDiv = driver.findElement(By.xpath("/html/body/form/div[3]/div[2]/div[1]/h1/em"));
// If results have been returned, the results are displayed in a drop down.
if (resultsDiv.isDisplayed()) {
break;
}
( b ) Is there a simple way to validate the existence of either of the elements by incorporating boolean operator, and regex, as part of the findElement() or findElements()? This would significantly reduce
the number of finds as well as simplifying the search.
( c ) Is it possible to use XPath syntax when searching Element by TagName. e.g. driver.findElement(By.tagName("/div[#class='report']/result"));
( d ) Is it possible to use regex in XPath search such as driver.findElement(By.xpath("//div[#class='main-wrap']/dl[#class='agent']/dd[#class='' OR #class='contain']")) for line 20 - 20a?
( e ) How to reference the immediate following node? e.g. Assuming the current node is Advertiser on line 19, how to lookup title of which is under , where its class name
can have a value of "contain" or nothing "". There could potentially be multiple tags within on line 18.
I have use XPath on XML document in the past but would like to expand the ability to locate elements within Webdriver 2.
Any assistance would be very greatful.
Thanks a lot,
Jack
considering the answer given by Zarkonnen, i'd add to (a) point
public boolean isElementPresent(By selector)
{
return driver.findElements(selector).size()>0;
}
this method i use for verifying that element is present on the page.
you can also involve isDisplayed() method that can work in pair with isElement is present:
driver.findElement(By locator).isDisplayed()
Returning back to your source:
Suppose we want to verify wheter 'More details' links is present on the page or not.
String cssMoreDetails = "a[id='ctl00_ctl00_Content_Content_SrchResLst_rptResult_ctl04_lstTemplate_hypMoreDetails']";
//and you simply call the described above method
isElementPresent(By.cssSelector(cssMoreDetails));
//if you found xPath then it be
isElementPresent(By.xpath("//*..."));
And always try to verify found web elements' locators in firepath
In that way you can get xPath of the elment automatically. See the screen attached.
(a) & (d): You can use the | XPath operator to specify two alternate paths in the same expression.
(c): You can't use XPath in byTagName, but you can use // to look for any descendant of a given node.
(e): You can use XPath axes like parent and following-sibling to select all nodes relative to a given node.
I hope these pointers are helpful. I also recommend the excellent Selenium Locator Rosetta Stone (PDF) as a reference on how to construct XPaths.
I have a jsp page with the tags:
<logic:iterate id="var" ...
....
<bean:write name="var" property="p1" ...
etc.
And I need, on each iteration, to generate a href composed from the various bean's properties. I even need to URLEncode some of them so the link works.
Something like
<logic:iterate id="var" ...
....
<html:link action="otheraction.do?_X_
<bean:write name="var" property="p1" ...
etc
where X is generated by collecting the bean's properties; something like
String X="p1="+URLEncode(p1)+"&p2="+SimpleDateFormatof(p2)+"&p3="+p3;
How can I do that ?
Thanks in advance.
Better to make one POJO class.
1. Assign all your values to the object in Action which is being called before your jsp page comes in the picture.
2. Keep the object of POJO to request attribute.
3. Get the value from request attribtue on JSP using <bean:write> tag.
A set of forms (using Zend_Form) that I have been working on were causing me some headaches trying to figure out what was wrong with my XML configuration, as I kept getting unexpected HTML output for a particular INPUT element. It was supposed to be getting a default value, but nothing appeared.
It appears that the following 2 pieces of XML are not equal when used to instantiate Zend_Form:
Snippet #1:
<form>
<elements>
<test type="hidden">
<options ignore="true" value="foo"/>
</test>
</elements>
</form>
Snippet #2:
<form>
<elements>
<test type="hidden">
<options ignore="true">
<value>foo</value>
</options>
</test>
</elements>
</form>
The type of the element doesn't appear to make a difference, so it doesn't appear to be related to hidden fields.
Is this expected or not?
As it was rather quiet on here, I took a look further into the source code and documentation.
On line 259 of Zend_Config_Xml, the SimpleXMLElement object attributes are converted to a string, resulting in:
options Object of: SimpleXMLElement
#attributes Array [2]
label (string:7) I can't see this because
value (string:21) something happens to this
becoming
options (string:21) something happens to this
So, I hunted through the documentation only to find that "value" is a reserved keyword when used as an attribute in an XML file that is loaded into Zend_Config_Xml:
Example #2 Using Tag Attributes in Zend_Config_Xml
"..Zend_Config_Xml also supports two
additional ways of defining nodes in
the configuration. Both make use of
attributes. Since the extends and the
value attributes are reserved keywords
(the latter one by the second way of
using attributes), they may not be
used..."
Thus, it would appear to be "expected" according to the documentation.
I'm not entirely happy that this is a good idea though, considering "value" is an attribute of form elements.
Don't worry about this. The reserved keywords were moved to their own namespace, and the previous attributes were depricated. In Zend Framework 2.0 the non-namespaced attributes will be removed so you can use them again.