How to access the link by searching its text in Selenium WebDriver? - java

I have a HTML File hierarchy in tree structure in a web page
as shown in picture.
The HTML code is
<div class="rtMid rtSelected">
< span class="rtSp"/>
< img class="rtImg" alt="Automation" src="http://192.168.1.6/eprint_prod_3.8/images/StoreImages/close_folder.png"/>
< span class="rtIn" title="Automation">Automation (1)</span>
</div>
In Selenium WebDriver is there a way to click on the Automation (1) link by searching only the text I don't want to use XPath reason is the location will be changing so is there a way to find it by its text and click on it.

XPath is powerful, you found it's unreliable you are not using it right. Spend some time at XPath Tutorial please.
This is a simple solution to your question, but there could be many other things you need to think about. E.g. matching title and text, etc.
driver.findElement(By.xpath(".//span[text()='Automation (1)']")).click();
CSS selector is also powerful and faster, more readable than XPath. But in your case, it doesn't support find by text.

searching by title worked well
driver.findElement(By.xpath("//span[contains(#title,'Automation')]")).click();

2 Approaches
Approach 1:
By Class Name:
Here we are having class Name for the Text Automation (1) that is rtIn.
Perform driver.findElement(By.className("rtIn")).click();
Approach 2:
By CSS Selector of Parent and Class Name
CSS Selector of Parent:.rtSelected
WebElement element1 = driver.findElement(By.cssSelector(".rtSelected"))
element1.className("rtIn").click();
Approach 3:
By Direct CSS Selector:
1. .rtIn
2. .rtSelected > .rtIn
It is better to use the second CSS Selector
driver.findElement(By.cssSelector(".rtSelected > .rtIn")).click();

Related

How to locate ::before element in Selenium and get its contents?

screenshot.png
Hi All,
I am having a situation where a ::before in HTML code is pointing to asterisk (mandatory field) in HTML page. Please see attached screenshot.
HTML code:
<lightning-input-field class="customRequired abc">
::before
<lightning-picklist>
</lightning-picklist>
</lightning-input-field>
How to write xpath for ::before?
I think there is no straight forward solution instead use javascript :
querySelector takes css selectors
css_selector = 'lightning-input-field[class="customerRequired"]'
browser.execute_script("return window.getComputedStyle(document.querySelector('{}'),':before').getPropertyValue('content')".format(css_selector))

How can i click on this button with selenium

How can i click on this button with selenium ?
<a class="_42ft _4jy0 rfloat _ohf _4jy4 _517h _51sy" role="button" href="" ajaxify="/nux/wizard/step/?action=skip" rel="async-post" id="u_9_8">İleri</a>
Something I wish I would have figured out earlier was how to create my own advanced CSS selectors here is the page that taught me, it will work in all cases assuming your element is visible in the DOM.
https://www.smashingmagazine.com/2009/08/taming-advanced-css-selectors/
For your given element you could write this many ways
Generic form
tag[attribute='ATTRIBUTE_VALUE']
For your example
a[id='u_9_8']
or
a[class='_42ft _4jy0 rfloat _ohf _4jy4 _517h _51sy']
or
a[rel='async-post']
Now all these selectors will only be useful if the attribute is unique. But take a look at that article there are many tricks you can use to make CSS selectors work for you.
By using xpath with contains text you can click on the element(below is the answer)
driver.findElement(By.xpath("//a[contains(text(),'Ileri')]")).click();
Try it and let me know if it works for you
Try any of these below mentioned code.
Using id locator
driver.findElement(By.id("u_9_8")).click();
Using xpath locator
driver.findElement(By.xpath("//a[text()= 'İleri']").click();
Explanation:- Use text method along with <a>tag.
driver.findElement(By.xpath("//a[#role='button'][text()= 'İleri']").click();
Explanation:- Use role attribute and text method along with <a> tag.
Please add the wait conditions before you are going to click
Element clicking Via linkText :
webDriver.findElement(By.linkText("İleri")).click();
Element clicking Via id :
webDriver.findElement(By.id("u_9_8")).click();
Element clicking Via cssSelector :
1.webDriver.findElement(By.cssSelector("._42ft._4jy0.rfloat._ohf._4jy4._517h._51sy")).click();
2.webDriver.findElement(By.cssSelector("a[class='_42ft _4jy0 rfloat _ohf _4jy4 _517h _51sy']")).click();
Element clicking Via javaScript :
((JavascriptExecutor) driver).executeScript("arguments[0].click();", webElement);
Here you need to pass the element locator instead of webElement.
We can see ID attribute tag so we can use ID "u_9_8" to click on the button.
use the below code.
driver.findelement(By.id("u_9_8")).click();
I think you should be able to use the id
driver.findElement(By.id("u_9_8")).click();
Give it a shot

#FindAll Is Kind of Slow When Trying to Locate Multiple Elements

I have a page that is localized and the "Create Account" WebElement can be English, Chinese or Japanese. I am using Selenium, Java and TestNG framework to run a test to click on this element. However, the slow performance when using this #FindAll to identify the page makes me wonder if there are any better way to do this.
The element from Inspect element while "English" locale is selected:
<div class="form-group">
<a translate="create-account" class="pointer ng-scope" ng-click="vm.createAccount()">Create Account</a>
</div>
My FindAll declaration:
#FindAll({
#FindBy(linkText="Create Account"),
#FindBy(linkText="创建账号"),
#FindBy(linkText="アカウントを作成")
})
private List<WebElement> createAccount;
As a baseline to compare, if I use the #FindAll above, it takes about 15 seconds before Webdriver clicks on the link. If I use just #FindBy, it takes about 2-3 seconds. However, #FindBy does not work for me as I need to be able to locate the correct locale to click on the link.
You could use a single css selector like:
a[ng-click*='createAccount']
Or one of the xpaths:
//a[contains(#ng-click, 'createAccount')]
//a[contains(text(), 'Create Account') or contains(text(), '创建账号') or contains(text(), 'アカウントを作成')]
For css if you pass part of the attribute value then it should be [#attributeName*='part_of_attribute_value']
Please take a look here to view a basic list of css rules w3schools css selectors
Thanks #lauda for helping out and the link to w3 css selectors.
I actually found two more ways that I can identify this link using css:
#FindBy(css="a[translate='create-account']")
private WebElement CreateAccount;
and
#FindBy (css="a.pointer.ng-scope")
private WebElement CreateAccount;
However, not sure why the original solution that lauda posted did not work for me though.
a[ng-click*='createAccount']

How to convert selenium webdriver xpath value into css

The current code has long HTML Xpath values that need to be converted & shortened to a css value:
driver.findElement(By.xpath("html/body/div[1]/div/div[2]/div/form/div[3]/div[2]/button")).click();
driver.findElement(By.xpath("html/body/div[1]/div/div[2]/div/form/div[3]/div[2]/button")).click();
You could possibly have chosen a better xpath expression than this one above. What you have done (without looking at the actual HTML code) is you have written down the complete xpath, is it possible to make it shorter / more robust?
Consider the following example:
<html itemscope itemtype="http://schema.org/QAPage">
<body class = "question-page new-topbar">
<div id="notify-container"></div>
<div id="topbar-wrapper"></div>
<button id="button1"></button>
</body>
</html>
You want to click on button1, you can find it using the complete xpath:
driver.findElement(By.xpath("html/body/div/div/button")).click()
or you can find it using xpath along this element's other attributes, in this case, its id.
driver.findElement(By.xpath("//button[#id='button1']")).click()
or as you wanted, you can use CSS selector:
driver.findElement(By.cssSelector('button[id='button1']')).click()
If you want us to help you with converting your xpath into css selector, you will need to copy and paste your html code in your question as well. Without looking at the actual code, we can not be 100% sure.
You may find the following link useful when trying to convert xpath into css selector.
https://www.simple-talk.com/dotnet/.net-framework/xpath,-css,-dom-and-selenium-the-rosetta-stone/

Java jsoup selecting links

I am trying to develop web scraper, I can extract all the links from a page, but I want to get some specific ones, I checked but I could not manage it as I dont have good knowledge in HTML
You can use the CSS selector presented in the snippet below:
doc.select("div.indepth-content > div.content > ul.indepth-list a")
On the screenshot, it seems you're using Chrome browser. If so, next time you can ask it to generate the CSS query for you:
Right click on the element you target
Click on "Inspect" (a node should appear selected)
Right click on this node then select Copy entry and Copy selector sub-entry
=> The CSS selector is copied in the clipboard
Please note that Chrome tends to generate (very) long CSS queries. Also, it can't generate CSS selectors for matching multiple elements.
However, if you type CTRL + F while the DevTools pane is opened and Elements tab selected, you can type a CSS selector and browse among the matched elements.
For more details, you can have look at the following resources:
JSoup CSS selector tutorial
JSoup CSS selector full syntax
How to generate CSS selectors with Chrome Developer Tools?
Element divcontent = doc.select("div.content").first();
Element ul = divcontent.select("ul.indepth-list").first();
ul.select("a[href]");
Written without editor so i can't remember if the syntax is correct.

Categories