Specifying multiple conditions in xpath - java

I want to select all the tags with <td class='blob-code blob-code-addition'> and <td class='blob-code blob-code-deletion'> . So I am trying to include or condition here between the two predicates. It does not work. However, if I include only one of the two classes it works . What is the problem here? Something is wrong with the syntax.
By getChanges = By.xpath("//td[#class='blob-code blob-code-addition'] or //td[#class='blob-code blob-code-deletion']");

You want to specify that like the following:
//td[contains(#class,'deletion') or contains(#class,'addition')]
or
//td[contains(#class,'blob-code blob-code-addition') or contains(#class,'blob-code blob-code-deletion')]
If you want to do a tag independent search then you can simply use
//*[contains(#class,'blob-code blob-code-addition') or contains(#class,'blob-code blob-code-deletion')]
From your answer it looks like you are trying to concatenate two different xpaths
However, contians() is not mandatory here. You also can do without this
//*[(#class='blob-code blob-code-addition') or (#class='blob-code blob-code-deletion')]

what works for me is below expression using "|" character inside my expression-
By element = driver.findElement(By.xpath("//button[#clas='xyz'] | //button[#clas='abc']"))
I used above expression for JAVA + Selenium + Maven project

using pom:
#FindBy(xpath ="//span[contains(#class,'vui-menuitem-label-text') and normalize-space(.) = 'Clone']")

To select all the tags with:
<td class="blob-code blob-code-addition">
<td class="blob-code blob-code-deletion">
You can use either of the following Locator Strategies:
Using xpath through class attribute with or clause:
//td[#class='blob-code blob-code-addition' or #class='blob-code blob-code-deletion']
Using xpath through single class attribute with or clause:
//td[contains(#class,'blob-code-addition') or contains(#class,'blob-code-deletion')]
Using xpath through partial class attribute with or clause:
//td[contains(#class,'addition') or contains(#class,'deletion')]

For writing Multiple Xpath in one element selenium
driver.find_elements(By.XPATH, '//div[#class="any-content"]//p|//h3|//figure')
You can write many tags by using "|" modulo.

Related

Selenium div attributes keep changing, how can I find this element?

I am trying to find an element with Selenium and Java, the problem is that the element's id, class, and name always increment so I am not able to find it with selenium. Below is what I am currently trying:
WebElement field = driver.findElement(By.xpath("//input[contains(#linkText, 'Broadcast copy')]"));
In my html file these are the attributes that keeps changing:
id="files[%2Fopt%240%2Frules%2F%2F000102%2.xml][%2Fcluster%2Fname]"
name="files[%2Fopt%240%2Frules%2F%2F000102%2.xml][%2Fcluster%2Fname]"
value="copy (Cluster 102)"
Entire html
<tbody>
<tr class='rowOdd'>
<td><b>Name</b></td>
<td> <input type='text' data-validation='required validate-name-unique validate-name-not-empty' size='65' id='files[%2Fopt%240%2Frules%2F%2F000102%2Fcluster.xml][%2Fcluster%2Fname]' name='files[%2Fopt%240%2Frules%2F%2F000102%2Fcluster.xml][%2Fcluster%2Fname]' value='copy (Cluster 102)' /> </td>
These always increment and I have no access to the html file to change anything. So my question is how can I find this input element? Thanks in advance.
UPDATE
I get the error:
Unable to locate element:{"method":"id", "selector":"files[.*][.*]"}
I believe the xpath you are using is incorrect. Use
//input[contains(text(), 'Broadcast copy')]
instead of
//input[contains(#linkText, 'Broadcast copy')]
According to the html you have provide the following should work as well
//body[contains(.,'Name')]//input
Try this..
In case "copy (Cluster" text in value attribute is not changing, then you can try below xpath:-
//body[contains(.,'Name')]//input[contains(#value,'copy (Cluster')]
Since the attributes of id, class, and css were constantly changing, 'data-validation' was one that stayed the same all the time. So the code below worked for me.
driver.findElement(By.xpath("//input[#data-validation='required validate-name-unique validate-name-not-empty']"));

How to write self-closing element tags using XMLStreamWriter

I am trying to write a XML element tag that has to look like this :
<case type="" player=""/>
My code is :
doc.writeStartElement("case");
doc.writeAttribute("type", type);
doc.writeAttribute("player", "");
doc.writeEndElement();
But, as I expected, a closing tag is added at the end, so it looks like this :
<case type="" player=""></case>
I am trying to write a self closing element tag, but cannot find how.
Does anyone know how to do that ?
Use writeEmptyElement().
But you should be aware that both forms are semantically equivalent, so any requirement that differentiates them should be viewed with suspicion.
BY writing writeEndElement(); you are asking the library to close case for you,
instead you should not invoke it and invoke writeEndDocument() instead.

webDriver cssSelector based on inner child attribute

here is some sample code and what I am trying to do:
<dl id="parentId">
<dt>
<a someattr="whatIwant"/>
</dt>
<dt>
<a someattr="whatIwantNextTime"/>
</dt>
</dl
I am trying to select the a element with someattr="whatIwant". this is my current cssselector:
"dl[id='parentId']>a[someattr='whatIwant']"
as well as:
"dl[id='parentId']>dt>a[someattr='whatIwant']"
Unfortunately, neither of these work; I appear to be following the w3schools template correctly, however I get element cannot be found exceptions when I try to run this, or illegal string exception if I add the '>dt>'. Does anyone have any insight on how to do this?
Thanks.
EDIT: You are using the direct descendant selector strategy (>) this only works if the element is a direct child. If you want a descenant of, use ()
dl#parentId a[someattr='whatIwant']
Also, assuming that your whatIwant is unique, then this selector will work perfectly..
Even further, you can do:
dl#parentId > td:nth-child(X) > a
where X is 1, 2, 3 (the index of the <dt /> that you want.
Also make sure that you are using the By.cssSelector strategy and nothing else if you are specifying CSS selectors.
So apparently I didn't do enough research, as I just figured this out 5 minutes after posting. The descendent selector ' ' works perfectly, which is:
"dl[id='parentId'] a[someattr='whatIwant']"

JAVA DOM: duplicated attributes

I'm using the DOM library for JAVA and some entries XHTML encounter this problem:
[Fatal Error] tree.xml:238:185: Attribute "itemprop" was already specified for element "span".
This is the XHTML part with problems:
<span class='fn' itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person' itemprop='name'>Rodrigo</span>
Exists some option to allow duplicate attributes in DOM?
Thanks!
My understanding is that the Microdata specification only allows one itemprop per HTML element, meaning that the DOM library you're using is properly marking it as invalid markup. If you want to specify multiple values, they need to be space-separated, like this:
<span class='fn' itemprop='author name' itemscope='itemscope' itemtype='http://schema.org/Person'>Rodrigo</span>
Incidentally, the class attribute works the same way.

Using variables in #{select} tag attributes

I have a page in my app with a dynamically-generated form, in which I need a number of <select> elements. Since I don't know in advance how many there will be, I need to put an ID number in the name attribute of each <select>. I'm trying to use the built-in #{select} tag (documentation here) like so:
#{ select 'select_' + ${IDnum}}
...options, etc...
#{/select}
When I do that I get a MissingMethodException:
No signature of method: Template_1009.$() is applicable for argument types:
(Template_1009$_run_closure1_closure2_closure3) values:
[Template_1009$_run_closure1_closure2_closure3#ad2388] Possible solutions:
_(java.lang.String), is(java.lang.Object), run(), run(), any(), get(java.lang.String).
When I instead do:
#{ select 'select_${IDnum}'}
the page renders correctly, but the select element renders like this in view-source:
<select name="select_${IDnum}" size="1" >
So, how do I get the value of ${IDnum} into the name attribute? I can do this with normal HTML <select> tags, but I'll need to write some Javascript to emulate Play's value:${x} functionality that I really don't want to bother with.
Thanks!
Try this :
#{select 'select_'+IDNum}

Categories