How to write xpath which has ::before and ::after (selenium) - selenium

Line 1 ->
<input _ngcontent-huh-c120="" name="options" id="line" type="radio"
ng-reflect-name="options" ng-reflect-model="0" ng-reflect-value="0" class="ng-untouched ng-valid ng-dirty" xpath="1">
Line 2-> ::before
Line 3-> ::after
I am trying to click on a radio button called line. I have 3 lines in html line 1,2 & 3. When I hover over all 3 lines all of them has exact same xpath
so its getting confuse on which xpath to select.
I tried //*[#id='line'] but its not working.

You can differentiate using xpath indexing, like below :
for first this should work.
(//*[#id='line'])[1]
for second this should work.
(//*[#id='line'])[2]
and so on..

Related

select radio button in selenium using python

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.

Xpath for Submit button with precedence nodes select file and *

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.

instead of xpath what can i select from the below code

Please help me to find locator in this case as id is dynamic and it changes every time when I refresh the page.
type="text" also I will not be able to use because, for the next fields, eveything is same from the down code except, the label changes from the "first name" to the "last name" and so on.
So I should be selecting something in terms of the first name which is mentioned in the label tag below.
Please anyone can help me in this case.
<input class="md-input-element ng-valid ng-dirty ng-touched" id="md-
input-4-input" spellcheck="false" type="text">
<!--template bindings={}-->
<label class="md-input-placeholder md-float md-empty" for="md-input-
4-input">First name * <!--template bindings={}--></label>
You can use preceding-sibling or following-sibling feature from xpath. As per code mentioned above your xpath should be like this:
//input[#type='text'][following-sibling::label[contains(text(),'First name')]]
But I think in html label should be first then input, if that is case please try below one:
//input[#type='text'][preceding-sibling::label[contains(text(),'First name')]]
you can get the css selector from the class (can't do by className if it has spaces in the class name so use css, put a "." at the beginning and replace any spaces with a ".")
#FindBy(css = ".md-input-element.ng-valid.ng-dirty.ng-touched")
private WebElement elementMDInputTouched;
#FindBy(css = ".md-input-placeholder.md-float.md-empty")
private WebElement elementMDInputEmpty;

How to 'click' a radio button -> xPath needed

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();

How to write xpath in selenium webdriver for below HTML expressions?

I wrote xpath for below HTML code i.e. displayed below
1. //a[#text()='Life Insurance']
2. //span[#text()='Apply now']
But I got element not found exception. If I used Absolute xpath processor then It's working and I wrote own xpath then it thrown exception.
Please tell me how to write it.
Below are the HTML code for which I need xpath.
1.<a class="mainlink" href="https://leads.hdfcbank.com/applications/webforms/apply/HDFC_Life_Click2Protect/index.aspx?promocode=P4_hp_AppNow_LI" target="" rel="nofollow width=375 height=213">Life Insurance</a>
2." <div class="menutext"> <span class="mainlink">Apply now</span> <img class="pointer" alt="Pointer" src="/assets/images/nav_pointer.png" style="display: none;"> </div> "
Try these
For 1
//a[text()='Life Insurance']
For 2
//span[text()='Apply now']
You have to remove '#' in your code.
(or)
You can also use:
//a[contains(text(),'Life Insurance')]
For 2
//span[contains(text(),'Apply now')]