I need to check one of three radio buttons. I tried this code:
//input[#type='radio']/following-sibling::*[contains(., 'Inne akcje')]
but I think it's wrong way.
<label class="HoldersInLineLabel">Rodzaj akcji</label>
<input type="radio" ng-model="holdersModel.OperationType" class="prettifiedIeCheckbox ng-valid ng-dirty" value="P" name="01H">
"Przekazanie"
<input type="radio" ng-model="holdersModel.OperationType" value="D" class="prettifiedIeCheckbox ng-valid ng-dirty" name="01I">
"Dekretacja"
<input type="radio" ng-model="holdersModel.OperationType" value="O" class="prettifiedIeCheckbox ng-valid ng-dirty" name="01J">
"Inne akcje"
<span class="k-widget k-dropdown k-header ng-pristine ng-valid" unselectable="on" role="listbox" aria-haspopup="true" aria-expanded="false"...></span>
The following XPath expression will get just the input element you want:
//input[#type='radio'][following-sibling::text()[position()=1][contains(., 'Inne akcje')]]
That returns this element:
<input type="radio" ng-model="holdersModel.OperationType" value="O"
class="prettifiedIeCheckbox ng-valid ng-dirty" name="01J" />
The key differences from your original XPath expression are:
Don’t use the syntax input[#type='radio']/following-sibling…; instead use //input[#type='radio'][following-sibling….
Don’t use following-sibling::*; instead use following-sibling::text() (because in this context * means “any element“; so if you want that text node instead, you have to explicitly indicate it by using text() instead)
Do use [position()=1] in following-sibling::*[position()=1] to indicate that you want the first following sibling.
Xpath seems to get more complicated and would be hard to maintain in long term in this case. Names seem to be unique for these radio buttons. Are they not static? If they are, then you can just use name as selector. If you really want to use xpath, then try something concise like
.//input[contains(#name, '01J') and text() = 'Inne akcje']
I agree with nilesh about XPath. Here's how I would do this using CSS Selectors.
WebElement przekazanie = driver.findElement(By.cssSelector("input[value='P']"));
WebElement dekretacja = driver.findElement(By.cssSelector("input[value='D']"));
WebElement inneAkcje = driver.findElement(By.cssSelector("input[value='O']"));
// pick the one you want to click and .click() it
przekazanie.click();
Related
I tried
driver.find_element(By.XPATH, "//input[#value='option1']").click
But Error message generated
Note:
value attributes is not supported by find_element
ID is not available as an attribute
Below is the HTML code
label _ngcontent-c12="" class="custom-control custom-radio"
input _ngcontent-c12="" class="custom-control-input input-md input-rectangle ng-dirty ng-valid ng-touched" formcontrolname="radioBtns" name="radioBtns" nbinput="" type="radio" value="option1"
span _ngcontent-c12="" class="custom-control-description">
You'd better use find_element_by_css_selector function.
driver.find_element_by_css_selector("input[value='option1']").click()
Hope it could help.
Query 1:
I would request you to please help me on getting xpath for submit button. Absolute path starts with Select file and *.
<div id="bg">
<label id="label" style=" font-family: Segoe UI;color:#2e2e2e; font-size:12px; float:left; padding-top:8px;">
Select File <span id="spanhide" class="red">*</span></label>
<div style="margin-left:105px;"><input type="file" name="filUploadIcon" id="filUploadIcon" class="txt-box" onchange="FileUpload_OnChange(this,event);" style="width:180px;">
<input type="submit" name="btnUploadcancel" value="" onclick="return check();" id="btnUploadcancel" title="Upload" class="upload_pop"></div>
<input name="textFileName" type="text" id="textFileName" style="display:none;">
<input type="hidden" name="hdnframeID" id="hdnframeID">
<input type="hidden" name="hdnlbl" id="hdnlbl">
</div>
Query 2:
How to write xpath to skip few nodes in between. Please help. Also let me know adding // or * in between to skip nodes.
Ex: Above HTML
//*div[#id="bg"]/skip elements before input type submit node/input [#type="submit"]
Use the below xpath to target the precedence nodes that include the label with the string "Select File" and the embedded span that contains '*'.
//div[contains(#id, 'bg')]/label[contains(text(), 'Select File')]/span[contains(text(), '*')]
Then add on the below line to return to the parent node label to the span tag.
/parent::label
Then add on the below to get to the sibling div tag of the label tag, which contains the input tag with a type of submit.
/following-sibling::div/input[#type='submit']
So the xpath in its entirety should look like this:
//div[contains(#id, 'bg')]/label[contains(text(), 'Select File')]/span[contains(text(), '*')]/parent::label/following-sibling::div/input[#type='submit']
You can use below xpath.
//div[#id='bg']//input[#name='btnUploadcancel']
Strongly suggest to go through this to learn more on xpath 1.0 which will answer all your questions in OP.
Please what locator do i use for the below. I have tried Xpath and CSS Selector but no luck.
<input type="password"
class="input-block-level ng-dirty ng-valid ng-valid-required"
placeholder="Password" ng-model="password" ng-trim="false"
required="" ng-disabled="isLogging"
ng-hide="changePassword" autocomplete="off">
As per the HTML you can use either of the following solution:
CSS_SELECTOR:
"input.input-block-level.ng-dirty.ng-valid.ng-valid-required[ng-model='password']"
XPATH:
"//input[#class='input-block-level ng-dirty ng-valid ng-valid-required' and #ng-model='password']"
Note: The element is an Angular element, ensure that you interact with the element inducing WebDriverwait.
For style class ng-dirty ng-valid ng-valid-required are inserted automatically by angular compiler after angular complete compile the source code. So your locator should not rely on these style class.
1) Using Java as script language
driver.findElement(By.cssSelector("input[placeholder='Password']"))
// or
driver.findElement(By.xpath("//input[#placeholder='Password']"))
2) Using python as script language
dirver.find_element_by_css_selector("input[placeholder='Password']")
// or
driver.find_element_by_xpath("//input[#placeholder='Password']")
Looking for a generic way to find text before an input field to know what to fill in the field. Using xpath, css selector or any other way possible.
<div>
<span>Full Name</span>
<input name="xddadN">
</div>
<div>
<span>Email</span>
<input name="xedadN">
</div>
Or
<div>
<div><label>Full Name</label></div>
<div><input name="xddadN"></div>
<div><label>Email</label></div>
<div><input name="xedadN"></
</div>
Or
<div>
<label>Full Name<br>
<span><input name="xddadN"></span>
</label>
</div>
<div>
<label>Full Name<br>
<span><input name="xddadN"></span>
</label>
</div>
You can try below XPath expression to get preceding text node:
//input/preceding::*[1]
or more specific for Full Name
//input[#name="xddadN"]/preceding::*[1]
and Email:
//input[#name="xedadN"]/preceding::*[1]
For full name use this Xpath : //input[#name='xddadN']/preceding-sibling::span
code :
String fullName = driver.findElement(By.Xpath(//input[#name='xddadN']/preceding-sibling::span)).getText();
String Email = driver.findElement(By.Xpath(//input[#name='xedadN']/preceding-sibling::span)).getText();
You haven't mentioned any Selenium Language Binding Art so I will be using Java for the example.
First the Answer
Yes, you can use a generic way to find text before an input field as follows :
As per the HTML :
<div>
<span>Full Name</span>
<input name="xddadN">
</div>
<div>
<span>Email</span>
<input name="xedadN">
</div>
To retrieve the text Full Name from the <span> tag with respect to the <input> tag you can use :
String myText = driver.findElement(By.xpath("//input[#name='xddadN']//preceding::*[1]")).getAttribute("innerHTML");
Now the Pitfall
Without any visibility to your usecase in my opinion the generic way would be a pitfall which will induce much chaos and uncertanity for the following reasons :
As per the xpath we are straightway jumping into the previous element, a small change in the HTML DOM (e.g. inclusion of a <span> tag) will make your Testcases to Fail.
In general, while constructing a Locator Strategy through css-selectors or xpath it will be benificial to include the <tagName> to optimize the element search process. If <tagName> are not included your Tests will require more time to locate the elements and perform action on them. In this process you are compromising some of the advantages of Test Automation.
Conclusion
Hence as a conclusion as per the Best Practices always include the <tagName> while constructing a Locator Strategy through css-selectors or xpath.
How to locate the element below in Selenium?
<input id="mainForm:field_LayFact450505264_16032015_145612--Order-ServiceClass_R" class="iceSelInpTxtTxt fieldTxt" type="text" value="" style="width: 150px;" onmousedown="this.focus();" onfocus="setFocus(this.id);svOnFocus(formOf(this), this, event, false);" onblur="setFocus('');svOnBlur(formOf(this), this, event);" name="mainForm:field_LayFact450505264_16032015_145612--Order-ServiceClass_R" autocomplete="off">
I tried with ends-with, it did not work.
You can use the below
WebElement inputClass = driver.findElement(By.className("iceSelInpTxtTxt fieldTxt"));
WebElement Element = driver.findElement(By.xpath("Try any Below xpaths"))
If your input id is unique then use below xpath
//input[#id='mainForm:field_LayFact450505264_16032015_145612--Order-ServiceClass_R']
OR
//input[#name='mainForm:field_LayFact450505264_16032015_145612--Order-ServiceClass_R']
OR if the combination of both of id and name make them unique then use below xpath
//input[#name='mainForm:field_LayFact450505264_16032015_145612--Order-ServiceClass_R' and #id='mainForm:field_LayFact450505264_16032015_145612--Order-ServiceClass_R']
OR
//input[#class='iceSelInpTxtTxt fieldTxt']
Hope it will help you :)