I've been trying to test a web application that generates html id's with a random value in the middle. For instance: attribute_new_12493044135_name
The attribute defines the class of object that I want to find and the "name" is the unique part of this string. The problem is that I don't have Xpath 2.0 and thus can't use ends-with on the script.
Can anyone help? I've tried to use Selenium Webdriver and IDE, and couldn't find an answer.
You are indeed correct you can not use the ends-with function if you do not have access to the Xpath 2.0 library. But you do have access to all the Xpath 1.0 functions. http://www.edankert.com/xpathfunctions.html
You have two functions you can use to xpath to your element.
contains(): //*[contains(#id, 'name')]
substring(): //*[substring(#id, string-length(#id)-3)="name"]
The 3 in string-length is the number of characters of your locator minus 1. ie 'name' has 4 characters so 4 - 1 = 3
Good Luck!
Also using a combination of css locators instead of the XPath will work:
[id*=attribute_new_][id*=_name]
OR:
[id^=attribute_new_][id$=_name]
Here's what the signs mean:
"^" - prefixes / starts with
"$" - suffixes / ends with
"*" - substrings / contains
Related
On multiple environments of the app which we are testing, the ID of one element is different. I have this div ID
CoredataForm:sec2_natural:grid1:left_section_natural:profession:selectProfession_auto_complete_force:ajax
Bold marked parts of the id, is the part which is same for all the environments.
How should I write xpath expression which would fit to all of them?
I used this
xpath="//div[starts-with(#id,'CoredataForm:sec2_natural:grid1:left_section_natural:profession:selectProfession') and ends-with(#id,'ajax')]"
but it doesn't work. Maybe another question: how can I use contains() function with multiple wildcards?
Your XPath might not work if your tool supports XPath1.0 only cause fn:ends-with is not available in XPath1.0
You can try to replace ends-with with contains in your XPath as
"//div[starts-with(#id,'CoredataForm:sec2_natural:grid1:left_section_natural:profession:selectProfession') and contains(#id,'ajax')]"
Selenium supports only XPath 1, but as JaSON says, ends-with is only available in XPath 2 and later versions.
However, it's possible to check that a string ends with another string using just the XPath 1 functions substring and string-length. The substring function returns a substring starting at a particular character location. The first character in the string has position 0, so substring('abc', 1)='bc'
If a string $s1 ends with another string$s2, then the following is true:
substring($s1, string-length($s1) - string-length($s2)) = $s2
So this expression should work for you (broken into multiple lines, for readability):
//div[
starts-with(
#id,
'CoredataForm:sec2_natural:grid1:left_section_natural:profession:selectProfession'
)
and
substring(
#id,
string-length(#id) - string-length('ajax')
) = 'ajax'
]
My Text in UI is "Resend in 48 sec" in which "48" is a timer which is dynamic so I want to crate an Xpath using the contains and Inside Contains I am using Regex but still unable to find the Element
//*[contains(#content-desc,"Resend in .*?[0-9a-zA-Z]*[0-9][0-9a-zA-Z].* sec")]
Selenium is still using XPath 1.0, which was defined over 20 years ago and has no support for regular expressions.
You can use this XPath instead:
//*[contains(#content-desc,"Resend in") and(contains(#content-desc,"sec"))]
Now you can get this element, get it's content-desc attribute value and then validate the content of that attribute
You may wanna do this instead :
String regEx = ".*?[0-9a-zA-Z]*[0-9][0-9a-zA-Z].*";
driver.findElement(By.xpath("//*[contains(#content-desc,'Resend in') + '"+regEx+"' + and(contains(#content-desc, 'sec')) ]"));
I'm trying to learn more about how Selenium works with VBA and I'm trying to do somethings about the trendings behaviors of ecommerce nowadays.
In this case, I don't know how works the FindelementByclass when it has special characters like _ or - inside, because it always gives me empty result and I need to identify it because I want to go through every class called as it.
<span class="minificha__sku ng-binding">Cód TG: AS0-322</span>
space in class means it has two classes,
class="minificha__sku ng-binding"
means it has "minificha__sku" and "ng-binding" , so use xpath or css instead of byclass or use either of the two class not two
css:
span[class="minificha__sku ng-binding"]
xpath
//span[#class="minificha__sku ng-binding"]
To identify the element you can use either of the following Locator Strategies:
Using FindElementByClassName I:
bot.FindElementByClassName("minificha__sku")
Using FindElementByClassName II:
bot.FindElementByClassName("ng-binding")
Using FindElementByCss:
bot.FindElementByCss("span.minificha__sku.ng-binding")
Using FindElementByXPath:
bot.FindElementByXPath("//span[#class='minificha__sku ng-binding']")
I am using XPath to find exact value:
//h5[#class='familyName productFamilyName'][contains(text(),'Dozers ')]
but it was failing because in my application there are 2 elements with text values "Dozers " and "Dozers wheel" which is come under same class.
I can't use id locators,because it is dynamically generating in my application like //div[#id="482"]/div/div[1]/h5.
Please suggest me any solution.
If you want to match element with exact innerHTML value just use
//h5[#class='familyName productFamilyName'][text()='Dozers')]
or
//h5[#class='familyName productFamilyName'][text()='Dozers wheel')]
Depending on HTML structure you might need to use [.='Dozers'] or
[normalize-space(.)='Dozers'] instead of [text()='Dozers']
I have multiple ok buttons in my application in the combinations: OK, ok, oK and Ok. How can i write a single #findby expression to identify all of them with the one webelement.
Code example
<button type="button">OK</button>
Here is the other solution in pure xpath 1.0 using xpath functions.
//button[contains('OK,ok,Ok,oK',text())][string-length('OK')=2]
or
//button[contains('OK,ok,Ok,oK',text())][string-length(text())=string-length('OK')]
Edit: Simple approach using translate
//button[translate(text(),'ok','OK')='OK']
You can specify matching text with xpath:
//button[text()='OK']
In your case, to match them all:
//button[text()='OK' or text()='oK' or text()='ok' or text()='Ok']