Cant locate by xpath because its the Xpath is always changing - python-3.x

I Tried to locate the input element below (also in the picture), by its content:
<input _ngcontent-c39="" autocomplete="off" class="remove-input-styling mat-input-element mat-form-field-autofill-control cdk-text-field-autofill-monitored ng-pristine ng-valid ng-touched" matinput="" readonly="true" ng-reflect-owl-date-time="[object Object]" ng-reflect-min="Thu Jun 20 2019 09:38:58 GMT+0" ng-reflect-select-mode="range" ng-reflect-readonly="" ng-reflect-dt-picker="[object Object]" aria-haspopup="true" min="2019-06-20T06:38:58.206Z" id="mat-input-23" aria-invalid="false" aria-required="false">
1.Tried that -
self.driver.find_element_by_xpath("//input[contains(.,'remove-input-styling mat-input-element mat-form-field-autofill-control cdk-text-field-autofill-monitored ng-pristine ng-valid ng-touched')]")
and
Tried that -
WebDriverWait(self.driver, 30).until(EC.presence_of_element_located((By.XPATH, "//input[#class='remove-input-styling mat-input-element mat-form-field-autofill-control cdk-text-field-autofill-monitored ng-untouched ng-pristine ng-valid'][contains(.,' ')]")))
This is the executing line:
self.driver.execute_script("arguments[0].click();", self.date_element)
Both ways I tried about didn't find the x-path

Have you tried this Xpath?
//input[contains(#id,'mat-input')]

Related

ElementNotInteractableException while using selenium and python

I am trying to automate login to a website (http://www.primecbdatabase.com/). It's source code is as follows
<p><label for="username">User ID</label> <input type="text" name="user_id" value="" onchange="javascript:replcodeid()"; size="6" maxlength="50"></p>
<p><label for="Password">Password</label><input type="password" name="password" id="password" value="" size="6" onkeypress="return SplChar1(event);" onchange="javascript:replcodepwd()" maxlength="16" ></p>
<p class="btn" style="margin-bottom:0;"><a onmouseover="self.status='PRIME Database';return true" href="javascript:submit1()"><img src="images_NSE/login-btn1.png"></a></p>
<p class="password">Forgot Password?</p>
It works correctly when dealing with the username input as shown below
inputElement = driver.find_element_by_name('user_id')
inputElement.send_keys(username)
But when I am trying to do the same for password (as shown below) it throws the ElementNotInteractableException. Looks like I am having trouble with send_keys to transfer the password to the input box.
inputElement = driver.find_element_by_name('password')
inputElement.send_keys(password)
I tried changing find_element_by_name to find_element_by_id, it still doesn't work. Kindly help me with it.
You need to click on the textbox before type.
driver.find_element_by_id("password").click()
driver.find_element_by_id("password").send_keys("123")
I have tried and am able to type a password using a script.

How to select "Form webElement" in which the class changes?

<div _ngcontent-ucs-c11 class="order__form--name"> ==$0
<label _ngcontent-ucs-c11 class="order__form--label">Symbol</label>
<!---->
<input _ngcontent-ucs-c11 class="form-control form-control-sm ng-untouched ng-pristine ng-invalid" formcontrolname="symbol" type="text" typeahead-editable="false" typeaheadoptionfield="symbolName"typeaheadoptionslimit="50">
<!---->
<!---->
</div>
I'm trying to send_Keys in selenium (python) but am unable to locate the text Web Element. I tried locating by class and xpath:
drive.find_element_by_class_name("form-control form-control-sm ng-pristine ng-invalid ng-star-inserted ng-touched")
driver.find_element_by_xpath("//input[#class='form-control form-control-sm ng-untouched ng-pristine ng-invalid')]")
The class changes from "form-control form-control-sm ng-pristine ng-invalid ng-star-inserted ng-touched" to "form-control form-control-sm ng-untouched ng-pristine ng-invalid ng-star-inserted".
I'm not sure if this is significant but, in addition to this the "_ngcontent-ucs-c11" also changed to "_ngcontent-uji-c7" and might change again to something else.
Also, is it anyway related to typeahead-editable="false" attribute inside input?
For the dynamic element you can use regular expresions.
driver.find_element_by_xpath("//input[contains(#name,'sel')]")
or
driver.find_element_by_xpath("//input[starts-with (#name,'Tut')]")
or
driver.find_element_by_xpath("//input[ends-with (#name,'nium')]")
Pick one that suits in your case(you will use (#class,'Tut')). And read more on https://www.tutorialspoint.com/how-to-use-regular-expressions-in-xpath-in-selenium-with-python

element not clickable for radio options

I am trying to find all elements by using find_element_by_xpath. In the below web elements, I am looking for these three elements separetely:
1. <label for="hw-log-mode-none" class="ng-binding">None</label>
2. <label for="hw-log-mode-session" class="ng-binding">Per-Session</label>
3. <label for="hw-log-mode-mapping" class="ng-binding">Per-Mapping</label>
<div class="field ng-scope" ng-if="!isTransparentMode && showNatPool && !policy.isIPv6" ng-show="policy.action == 'accept' && policy.nat == 'enable'">
<label class="ng-binding">Hardware Logging Mode</label>
<div>
<div class="radio-group">
<input type="radio" id="hw-log-mode-none" value="none" ng-model="policy['hw-logging-mode']" class="ng-pristine ng-untouched ng-valid" name="670">
<label for="hw-log-mode-none" class="ng-binding">None</label>
<input type="radio" id="hw-log-mode-session" value="session" ng-model="policy['hw-logging-mode']" class="ng-valid ng-dirty ng-touched" name="671" style="">
<label for="hw-log-mode-session" class="ng-binding">Per-Session</label>
<input type="radio" id="hw-log-mode-mapping" value="mapping" ng-model="policy['hw-logging-mode']" class="ng-valid ng-dirty ng-touched ng-valid-parse" name="672" style="">
<label for="hw-log-mode-mapping" class="ng-binding">Per-Mapping</label>
</div>
</div>
</div>
I can find element #1 and #2 in above list. But when I try to find element #3 using the same way:
elem = driver.find_element_by_xpath("//label[#for='hw-log-mode-mapping']")
I got this error:
Message: element click intercepted: Element ... is not
clickable at point (707, 508). Other element would receive the click:
... (Session info: chrome=77.0.3865.90)
You could try clicking the element using Javascript and see if that works around the error.
elem = driver.find_element_by_xpath("//label[#for='hw-log-mode-mapping']")
driver.execute_script("arguments[0].click();", elem)
If that doesn't work, you could try clicking the input element itself.
elem = driver.find_element_by_xpath("//input[#id='hw-log-mode-mapping']")
driver.execute_script("arguments[0].click();", elem)
Try this, Get list of all the elements as they have same class name as follow:
List<WebElement> elements = driver.findElements(By.xpath(".//label[#class='ng-binding']"));
Now create a method to select the radio options as follow:
public void selectRadioOption(String option){
if(option.equals("None"))
elements.get(0).click();
else if(option.equals("Per-Session"))
elements.get(1).click();
else if(option.equals("Per-Mapping"))
elements.get(2).click();
}
Call this method, pass the option whichever you want to select.
Hope it works for you. You should not find 3 different xpath if you can work with one.

how to select a option on a web page drop down list using selenium with python

I wanted to select the value "LK" in the drop down list on my web page. please help.
i tried to slect by xpath as follows
driver.find_element_by_xpath("//select[contains(text(), 'GLOBAL')]").click()
driver.find_element_by_xpath("//span[contains(text(), 'LK')]/..").click()
but i get following error:
selenium.common.exceptions.ElementNotVisibleException: Message: element not interactable
Below is the web element code im trying to fetch:
<select style="border-radius: 3px;" ng-model="selectedRcc.value" ng-options="item for item in ['LK', 'US', 'GLOBAL']" class="ng-pristine ng-valid ng-touched" tabindex="0" aria-invalid="false">
<option value="0" label="LK">LK</option>
<option value="1" label="US">US</option>
<option value="2" selected="selected" label="GLOBAL">GLOBAL</option>
</select>
Use the below xpath
//select[#class='ng-pristine ng-valid ng-touched']/option[.='LK']
Code:
driver.find_element_by_xpath("//select[#class='ng-pristine ng-valid ng-touched']/option[.='LK']").click()
When you have select element it always good to use selenium select class to select item from drop down menu.
select=Select(driver.find_element_by_xpath("//select[#class='ng-pristine ng-valid ng-touched']"))
select.select_by_visible_text('GLOBAL')
select.select_by_visible_text('LK')
OR you can use index.
select=Select(driver.find_element_by_xpath("//select[#class='ng-pristine ng-valid ng-touched']"))
select.select_by_index(0) #LK
select.select_by_index(2) #GLOBAL
To use above code you need to have following imports.
from selenium.webdriver.support.select import Select

Accessibility issue with p:select

Using primefaces 5.1, i'm testing my app with WCAG validator and the following code is breaking a guideline:
<p:outputLabel for="selectHowMuch" value="Do you feel edgy lately ?" />
<p:selectOneMenu id="selectHowMuch" value="Yes">
<f:selectItem itemLabel="Argggg" itemValue="3" />
<f:selectItem itemLabel="Yes" itemValue="2" />
<f:selectItem itemLabel="hmmm" itemValue="1" />
<f:selectItem itemLabel="NO!" itemValue="0" />
</p:selectOneMenu>
the broken guideline is
Success Criteria 1.3.1 Info and Relationships (A) Check 91: select
element missing an associated label.
Repair: Add a label element that surrounds the control's label. Set
the for attribute on the label element to the same value as the id
attribute of the control. And/or add a title attribute to the input
element. And/or create a label element that contains the input
element.
Error Line 1, Column 16711:
<select id="_testapp_WAR_testapp001SNAPSHOT_:j_idt3:selectHowMuch_input"
Note that the p:outputLabel actually did help (if i remove it, i get more errors), but it looks like it's not covering the <select> _input label
I also noticed that the same happens for other select components.
Any ideas to get around this ?
Edit: here's my generated code:
<label id="_tutorial_WAR_tutorial001SNAPSHOT_:j_idt3:j_idt62" class="ui-outputlabel ui-widget"
for="_tutorial_WAR_tutorial001SNAPSHOT_:j_idt3:selectHowMuch_focus">Do you feel edgy lately ?</label>
<div id="_tutorial_WAR_tutorial001SNAPSHOT_:j_idt3:selectHowMuch" class="ui-selectonemenu ui-widget ui-state-default ui-corner-all">
<div class="ui-helper-hidden-accessible">
<input
id="_tutorial_WAR_tutorial001SNAPSHOT_:j_idt3:selectHowMuch_focus"
name="_tutorial_WAR_tutorial001SNAPSHOT_:j_idt3:selectHowMuch_focus"
type="text" autocomplete="off" />
</div>
<div class="ui-helper-hidden-accessible">
<select
id="_tutorial_WAR_tutorial001SNAPSHOT_:j_idt3:selectHowMuch_input"
name="_tutorial_WAR_tutorial001SNAPSHOT_:j_idt3:selectHowMuch_input"
tabindex="-1"><option value="3">Argggg</option>
<option value="2">Yes</option>
<option value="1">hmmm</option>
<option value="0">NO!</option></select>
</div>
<label
id="_tutorial_WAR_tutorial001SNAPSHOT_:j_idt3:selectHowMuch_label"
class="ui-selectonemenu-label ui-inputfield ui-corner-all"> </label>
<div
class="ui-selectonemenu-trigger ui-state-default ui-corner-right">
<span class="ui-icon ui-icon-triangle-1-s ui-c"></span>
</div>
<div
id="_tutorial_WAR_tutorial001SNAPSHOT_:j_idt3:selectHowMuch_panel"
class="ui-selectonemenu-panel ui-widget-content ui-corner-all ui-helper-hidden ui-shadow">
<div class="ui-selectonemenu-items-wrapper"
style="height: auto">
<ul
class="ui-selectonemenu-items ui-selectonemenu-list ui-widget-content ui-widget ui-corner-all ui-helper-reset">
<li
class="ui-selectonemenu-item ui-selectonemenu-list-item ui-corner-all"
data-label="Argggg">Argggg</li>
<li
class="ui-selectonemenu-item ui-selectonemenu-list-item ui-corner-all"
data-label="Yes">Yes</li>
<li
class="ui-selectonemenu-item ui-selectonemenu-list-item ui-corner-all"
data-label="hmmm">hmmm</li>
<li
class="ui-selectonemenu-item ui-selectonemenu-list-item ui-corner-all"
data-label="NO!">NO!</li>
</ul>
</div>
</div>
</div>
<script id="_tutorial_WAR_tutorial001SNAPSHOT_:j_idt3:selectHowMuch_s"
type="text/javascript">$(function(){PrimeFaces.cw("SelectOneMenu","widget__tutorial_WAR_tutorial001SNAPSHOT__j_idt3_selectHowMuch",{id:"_tutorial_WAR_tutorial001SNAPSHOT_:j_idt3:selectHowMuch",widgetVar:"widget__tutorial_WAR_tutorial001SNAPSHOT__j_idt3_selectHowMuch"})});</script>
Sorry, i have to contrast with the last answer...
In your example, this select does not have an associated label
<select
id="_tutorial_WAR_tutorial001SNAPSHOT_:j_idt3:selectHowMuch_input"
name="_tutorial_WAR_tutorial001SNAPSHOT_:j_idt3:selectHowMuch_input"
tabindex="-1"><option value="3">Argggg</option>
<option value="2">Yes</option>
<option value="1">hmmm</option>
<option value="0">NO!</option></select>
There is one label after it who might have been thought for it, but it does not have a for attribute and does not contain the select tag.
<label
id="_tutorial_WAR_tutorial001SNAPSHOT_:j_idt3:selectHowMuch_label"
class="ui-selectonemenu-label ui-inputfield ui-corner-all"> </label>
As I understand, both the input and the select are generated for this one field and only one label is correctly associated with the input. This looks like a bug in primefaces, and you should ask their staff to make some corrections...
Also there would be more correction to do, because the first label should be associated with the select element, and the input element be invisible to screenreaders if I correctly understand.
There is nothing wrong with your markup per se. It conforms to one of the accepted techniques.
http://www.w3.org/TR/2015/NOTE-WCAG20-TECHS-20150226/H44#H44-ex1
Although that example shows use with an <input> element, it is equally valid with a <select> element.
This looks like a bug in your validator. I suggest trying FireEyes http://www.deque.com/products/fireeyes/fireeyes-installation/

Resources