I would like to type in the date as following: 2015/05/05 in to that field. the idea is to use the ends-with command. So far the following didn't work
//input[ends-with(#id,'_ExecutionDate')and contains(.,'ExecutionDate')][#class='emphasis']
//div[ends-with(#id,'_ExecutionDate')and contains(.,'ExecutionDate')][#class='emphasis']
Here is a XPATH from Selenium's Select option:
xpath=(//input[#id='44d02654-39b3-447e-904d-8d3c7ca016b6.ExecutionDate'])[3]
Her is an xpath from Firebug:
.//*[#id='44d02654-39b3-447e-904d-8d3c7ca016b6.ExecutionDate']
Here is a code:
<div class="pull-right" data-bind="visible: view.isIndividual"><!-- ko foreach: signingParties -->
<a id="44d02654-39b3-447e-904d-8d3c7ca016b6.ExecutionDate" class="emphasis" style="margin-right:5px" data-bind="visible: !$root.locked(), click: $root.transferOfLand.view.editExecutionDates, valName: 'ExecutionDate', text: view.executionDateDisplay()" href="#" name="44d02654-39b3-447e-904d-8d3c7ca016b6.ExecutionDate" data-val="LandTransferDocument.Transferor.0.SigningParty.ExecutionDate">Add Execution Date...</a>
<span id="44d02654-39b3-447e-904d-8d3c7ca016b6.ExecutionDate" style="margin-right: 5px; display: none;" data-bind="visible: $root.locked(), valName: 'ExecutionDate', text: view.executionDateDisplayReadOnly()" name="44d02654-39b3-447e-904d-8d3c7ca016b6.ExecutionDate" data-val="LandTransferDocument.Transferor.0.SigningParty.ExecutionDate">No Execution Date</span>
ends-with() is a part of XPath 2.0 and, hence, cannot be used here, see details at:
Xpath error with not() and ends-with()
Instead, use contains():
//input[contains(#id,'ExecutionDate')]
Alternatively, there is an ends-with CSS selector:
input[id$=ExecutionDate]
Related
I am trying to select
<div ng-click="select('expert')" class="select-exp__item select-exp__item_active" ng-class="{'select-exp__item_active': 'expert'===selected}" style="">
I have tried a few things
driver.find_element_by_css_selector("div[ng-click='select('expert')']").click()
driver.find_element_by_class_name('select-exp__item-title').click()
WebDriverWait(driver, 10).until(EC.element_to_be_clickable(By.XPATH("//div[#class='select-exp__item select-exp__item_active']").click()
WebDriverWait(driver, 10).until(EC.element_to_be_clickable(By.XPATH("//div[#class='select-exp__item select-exp__item_active' and contains(#ng-click, 'select('expert')')]").click()
...but I get the same error each time:
InvalidSelectorException: Message: invalid selector: An invalid or illegal selector was specified
Grateful for any guidance, have googled "selenium ng-click" extensively without much luck and still learning Selenium, thank you.
Here's the full HTML:
<div class="agmodal__wrapper agmodal onboarding-wrapper ng-scope agmodal__wrapper--visible" ng-controller="OnboardingController as ctrl" ng-class="{'agmodal__wrapper--visible': ctrl.shown}" tabindex="-1" style="">
<div class="onboarding">
<div class="onboarding__body">
<!-- ngIf: ctrl.onboardingService.step === 1 --><section class="select-exp step ng-scope" ng-if="ctrl.onboardingService.step === 1" style="">
<div class="select-exp__header step__header">
<div class="select-exp__title step__title">Welcome to AMZScout PRO Extension</div>
<div class="select-exp__desc step__desc">
PRO Extension helps you find the perfect product to sell on Amazon
</div>
</div>
<div class="select-exp__body">
<div class="select-exp__body-title">
Select your experience level with Amazon</div>
<div class="select-exp__body-desc">
We will adjust the amount of pop up tips and certain parameters based on your experience. You will be able
to
change this choice later in the Settings.</div>
<div class="select-exp__items">
<div ng-click="select('beginner')" class="select-exp__item" ng-class="{'select-exp__item_active': 'beginner'===selected}">
<div class="select-exp__item-title">Beginner</div>
<div class="select-exp__item-desc">If you are new to Amazon research, you’ll see vital parameters that
will help you choose a great
product quickly. Great for learning.</div>
</div>
<div ng-click="select('expert')" class="select-exp__item select-exp__item_active" ng-class="{'select-exp__item_active': 'expert'===selected}" style="">
<div class="select-exp__item-title">Expert</div>
<div class="select-exp__item-desc">As an expert, you’ll see the full data and be able to fine-tune your
research.</div>
</div>
</div>
</div>
This error message...
InvalidSelectorException: Message: invalid selector: An invalid or illegal selector was specified
...implies that the selector which you have used isn't a valid selector expression.
Analysis
As per your first code trial:
driver.find_element_by_css_selector("div[ng-click='select('expert')']").click()
( and ) have a special effect when used within a css-selectors. So the expression stands invalid. You need to escape the characters.
Solution
As the desired element is an Angular element you need to use WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div.select-exp__item.select-exp__item_active[ng-click=\"select('expert')\"]"))).click()
XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[#class='select-exp__item select-exp__item_active' and #ng-click=\"select('expert')\"]"))).click()
Try located the element with css selector like this:
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'div.select-exp__item.select-exp__item_active'))).click()
You are wrong in using WebdriverWait, your code:
WebDriverWait(driver, 10).until(EC.element_to_be_clickable(By("value").click()
It's should like this pattern:
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By, 'value'))).click()
Explicit Waits
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.
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')]
Example HTML below. I want to locate the elements which contains the text Person Attributes and Age.
<div id="ext-gen210" class="x-tool x-tool-toggle"></div>
<span id="ext-gen214" class="x-panel-header-text">Person Attributes</span>
</div>
<div id="ext-comp-1071" class=" DDView ListView" style="height: auto;">
<p class="dragItem "><i class="icon-Gen"></i>Age</p>
</div>
Note: I am looking for a solution without using xpath or id or className as they might change with every new release of my website.
I tried to locate them using
'name' --> By.name("Person Attributes") and By.name("Age") but both failed.
By.name would check for the name attribute. What you need is to check the text of an element using By.xpath:
By.xpath('//div[span/text() = "Person Attributes"]')
Or, you can also check that an id element starts with ext-gen:
By.xpath('//div[starts-with(#id, "ext-gen")]')
I want to get text "Entered code is already exists" using selenium webdriver , I tried using id="code_error" but no use
HTML code is as follows :
<div class="leftsection">
<div class="form-element">
<fieldset>
<label><span class="required">*</span>Code:</label>
<input type="text" maxlength="6" value="" id="code" name="code" style="border: 1px solid rgb(178, 178, 178);">
</fieldset>
<span role="alert" class="errormsg" id="code_error">Entered Code already exists</span>
</div>
i used xpath , id, cssselecor but it returns NULL.
Have a look at the below code..works perfectly
options=driver.find_elements_by_class_name("errormsg")
for i in options:
print i.text
when selenium can parse JavaScript, you can use this:
var text = document.getElementById('sbucode_error').innerHTML;
Please use Selenium Ide to check whether id=code_error selector pointing to your element then use the below mentioned code to get text from that.
driver.findElement(By.id("code_error")).getText();
String text = driver.findElementById("code_error").getText(); should do the trick for you :)