Can we achieve parent child relationship with CssSelectors in Selenium - selenium

Is parent child relationship valid for cssSelector as well in selenium
Example-
This X-path is valid:
driver.findElement(By.xpath("//div[#class='gb_ke gb_i gb_Kg gb_Ag']/div[2]/a")).click();
But this cssSelector is not:
driver.findElement(By.cssSelector("div[class*='gb_ke gb_i gb_Kg gb_Ag']/div[2]/a")).click();
It gives the error:
An invalid or illegal selector was specified

CSS selectors and XPath selectors have a different syntax.
Your xpath is By.xpath("//div[#class='gb_ke gb_i gb_Kg gb_Ag']/div[2]/a")
and you should update your CSS accordingly, e.g.
CSS By.cssSelector("div[class*='gb_ke gb_i gb_Kg gb_Ag'] div:nth-child(2) a")

To start with xpath and css-selectors follows different syntax.
The equivalent cssSelector locator for the xpath:
driver.findElement(By.xpath("//div[#class='gb_ke gb_i gb_Kg gb_Ag']/div[2]/a")).click();
Can be either of the following as per the prevalent HTML DOM:
driver.findElement(By.cssSelector("div.gb_ke.gb_i.gb_Kg.gb_Ag > div:nth-of-type(2) > a")).click();
Or
driver.findElement(By.cssSelector("div.gb_ke.gb_i.gb_Kg.gb_Ag > div:nth-child(2) > a")).click();

Related

Replace xpath element for a shorter one or a CSS selector selenium

i am using Selenium and i would like to replace xpath to get a list of this elements.
So far this xpath works, but i think is is unsophisticated. I think is better change for a CSSselector or shorter xpath, but i am not able to gat the same result.
Thanks
Below xpath will work
"//div[#id='igTreeProjectTree']//li[starts-with(#data-path, '0_0_')]"
Because I think data-path is unique in all elements
Try this CSS-selector:
'#igTreeProjectTree li.ui-igtree-node-nochildren'
For the xpath:
//*[#id='igTreeProjectTree']/ul/li/ul/li/ul/li
The equivalent css-selectors will be:
#igTreeProjectTree > ul > li > ul > li > ul > li
A more canonical Locator Strategy would be:
#igTreeProjectTree ul[data-depth='2'] > li.ui-igtree-node-nochildren[data-path='0_0_0']

Unable to find CSS selector by :contains()

Unable to find CSS selector using :contains().
I have followed the instructions from https://www.browserstack.com/guide/css-selectors-in-selenium
at #5 – Inner text
but still, no result is shown, Can someone please help me/Tell me how to find Web element using text, CSS only
Here is Sample Dom
<ul id='id'>
<li class='class'>
<a class='class_class2' href="/Myaccount/summary">"Summary"</a>
<li class='class'>
<a class='class_class2' href="/Myaccount/Profile">"Profile"</a>
</ul>
Here : a:contains('Summary')
https://developer.mozilla.org/en-US/docs/Web/CSS/Reference
https://stackoverflow.com/a/4781167/6793637
Contains: is no longer available
you should use xpath to find elements using innerText
xpath:
//a[contains(text(),"Summary")]
You can get exact match as
//a[text()="Summary"]
The :contains pseudo-class isn't in the CSS Spec and is not supported by either Firefox or Chrome (even outside WebDriver).
You can find a couple of relevant detailed discussion in:
selenium.common.exceptions.InvalidSelectorException with "span:contains('string')"
Finding link using text in CSS Selector is not working
Alternative
To locate the element with text as Summary you can use either of the following css-selectors:
Using first-child:
ul#id li:first-child > a
Using nth-child():
ul#id > li:nth-child(1) > a
tl; dr
References:
CSS selector :contains doesn't work with Selenium 2.0a7
css pseudo-class :contains() no longer allows anchors

Difference between contains and equals in XPath - selenium

Hey All I gave a question regarding xpath locator in selenium.
I have a test that if I use the next code:
locator = By.xpath("//div[#class='ant-notification-notice ant-notification-notice-closable ng-trigger ng-trigger-notificationMotion']");`
everything is working since I user "class="
However if I change it and use contains :
locator = By.xpath("//div[contains(#class, 'ant-notification-notice ant-notification-notice-closable ng-trigger ng-trigger-notificationMotion')]");
I get
ERROR: no such element: Unable to locate element: {"method":"xpath","selector":"//div[contains(#class, 'ant-notification-notice ant-notification-notice-closable ng-trigger ng-trigger-notificationMotion')]"}
I do not understand what is the difference, and why If I use contains it not find.
The xpath as:
//div[#class='ant-notification-notice ant-notification-notice-closable ng-trigger ng-trigger-notificationMotion']
is checking #class attribute values lexically for the string:
ant-notification-notice ant-notification-notice-closable ng-trigger ng-trigger-notificationMotion
Where as xpath as:
//div[contains(#class, 'ant-notification-notice ant-notification-notice-closable ng-trigger ng-trigger-notificationMotion')]
is checking the substring ant-notification-notice ant-notification-notice-closable ng-trigger ng-trigger-notificationMotion within the #class attribute value.
I feel it would be a better idea to restrict the #class attributes as follows:
//div[contains(#class, 'ant-notification-notice') and contains(#class, 'ant-notification-notice-closable')][contains(#class, 'ng-trigger') and contains(#class, 'ng-trigger-notificationMotion')]
You can find a relevant discussion in Why does google-chrome-devtools identifies less number of elements through XPath then number of elements identified through CssSelector

How to locate child nodes having attribute xpath="1" and xpath="2"

I'm trying to locate a web element that have two child nodes as:
<div _ngcontent-c2="" class=" " title="Twelve (Start date is 31| 0 user)" xpath="1"></div>
<div _ngcontent-c2="" class=" " title="Twelve (Start date is 31| 0 user)" xpath="2"></div>
I tried //div[contains(#title,'Twelve (Start date is 31| 0 user)')][1] to get the first element but didn't work for me.
xpath="1"
xpath="1" attribute is the reference of xpath v1.0
xpath="2"
xpath="2" attribute is the reference of xpath v2.0
For the record Selenium supports XPath v1.0 only.
A bit more of the outerHTML including the parent tag would have helped us to construct a more canonical answer. Moreover the information about the Language Binding you are using is also missing. However to locate the first element you need to induce WebDriverWait for the desired visibilityOfElementLocated() and you can use the following can use the following xpath:
Java:
WebElement element = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[contains(#title,'Start date is 31') and #xpath='1']")));
Python:
element = WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//div[contains(#title,'Start date is 31') and #xpath='1']")))
Here you can find a detailed discussion on What are the differences between versions of XPath (1.0, 2.0, 3.1)
You can try with CSS:
div[xpath='1']
div[xpath='2']

How to create an XPath for this, suitable for Selenium?

Please help me to create the Xpath for the following. I am using Selenium webdriver and have only IE browser. Following is the HTML:
<A
title=""
href="javascript:Plg({u:'/epace/starintfc.html?module=RUN_EVENT',p:0,nw:'0'});"
p="eagle/pace/pace"
la=""
ml="%09NULL%09PLUGIN%09%2fepace%2fstarintfc.html%3fmodule%3dRUN_EVENT%09%09%09%09%09%09%09%09%09%09"
t="Plugin" gh="" g="Data Steward"
pc="Eagle/PACE/PACE Components"
ivname=""
><IMG id=Item.Img
class=link
src="/tpe/modules/site/img/menu_plugin.gif">Run An Event</A>
As I prefer CSS over xPath because of it's simplicity, I will provide both the CSS and xPath solution:
Remember that you want to get the attribute of the elements that have the most specificity. The answers below are the best of my ability, to determine which have the most specificity. (see here if you want to learn more about CSS and specificity of elements)
If you are trying to select the first <a> element...
CSS:
a[href*='RUN_EVENT']
xPath:
//a[contains(#href, 'RUN_EVENT')]
If you are trying to select the <img> that is inside of the <a> tag...
CSS:
a[href*='RUN_EVENT'] > img
xPath:
//a[contains(#href, 'RUN_EVENT')]/img
My guess is that you want the first one since it's a link, and I assume you want to invoke a click on it.