WebDriver with Java - click to open a link using xpath - java

I want to open a a link on a webpage. The link appears to be within a unordered list which resides within in a tag. The url to the web page is selftechy dot com. The tabs are home, about, selenium.
I attempted to open the link using driver.findElement(By.linkText("Selenium")); but page seems like lost its styling. I also tried with xpath method, but it doesn't work either. Please explain to me why it doesn't work and how should I modify the code to make it work properly. Thanks for your help.
HTML code fragment:
<body class="custom">
<div id="container">
<div id="page">
<ul class="menu">
<li class="tab tab-home current">Home</li>
<li class="tab tab-1">About</li>
<li class="tab tab-2">Selenium</li>
</ul>
webdriver code to open the link
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.junit.*;
import org.junit.Before;
import org.junit.After;
import org.openqa.selenium.*;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.Select;
public class selftechyTestng
{
private WebDriver driver;
private String baseUrl;
#Before
public void setUp() throws Exception
{
driver = new FirefoxDriver();
baseUrl = "http://selftechy.com/";
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
#Test
public void searchElements() throws Exception{
driver.get(baseUrl);
//use By.linkText method the page lost its styling
driver.findElement(By.linkText("Selenium"));
//use xpath method to open the link doesn't work either
List<WebElement> elements = driver.findElements(By.xpath("//div[#id=page]/*[3]")).click();
driver.findElement(By.xpath("//div[#id=page]/*[3]")).click();
}
}

Why do you search for the div and then the child element - Is there any particular reason? I don't see any advantage and certainly you are then not getting the a element which you actually want to click. In my opinion it is much simpler to use
driver.findElement(By.xpath("//a[#title = 'Selenium']")).click();
Using your approach you have to use
driver.findElement(By.xpath("//div[#id = 'page']/ul/li[3]/a")).click();

You can also use this xpath:
"//a[text()='Selenium']"
This will find the link with text = Selenium

Below code will open the link in new window and prints the title and url of the newly opened window.
String defaultwindow = "";
#Test(description="Main Page")
public void UserOnMainPage()
{
driver.get("http://yoururl.com");
defaultwindow = driver.getWindowHandle();
String selectAll = Keys.chord(Keys.SHIFT,Keys.RETURN);
driver.findElement(By.linkText("linkname")).sendKeys(selectAll);
printTitleandUrlofNewlyOpenedwindow();
}
private void printTitleandUrlofNewlyOpenedwindow()
{
Set<String> windowHandles1 = driver.getWindowHandles();
int size = windowHandles1.size();
System.out.println(size);
for (String string : windowHandles1)
{
driver.switchTo().window(string);
if(string.equals(defaultwindow))
{
System.out.println("On Main Window");
Reporter.log("On Main Window");
}
else
{
String title=driver.getTitle();
System.out.println(title);
Reporter.log(title);
String recipeUrl = driver.getCurrentUrl();
System.out.println(recipeUrl);
Reporter.log(recipeUrl);
}
}
driver.switchTo().window(defaultwindow);
}

Below code will open the link in new Tab.
String selectLinkOpeninNewTab = Keys.chord(Keys.CONTROL,Keys.RETURN);
driver.findElement(By.linkText("urlLink")).sendKeys(selectLinkOpeninNewTab);

Related

Cannot manage to click on a button using Xpath

hi i'm trying to click on a button using Xpath on chrome browser but from some reason the software does not click on it.
i used the devtools inspect in order to copy the Xpath to the findElement function.
that's the website: https://mynames.co.il/
i'm sorry that's in hebrew...
this photo shows the button ,i marked the button in blue
that's the steps file:
package stepDefinitions;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.WebDriverWait;
import cucumber.api.PendingException;
import cucumber.api.java.After;
import cucumber.api.java.Before;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
public class purchaseDomainSteps {
WebDriver driver;
#Before
public void setup() throws IOException {
System.setProperty("webdriver.chrome.driver", Paths.get(System.getProperty("user.dir")).toRealPath() + "\\src\\test\\java\\drivers\\chromedriver.exe");
this.driver = new ChromeDriver();
this.driver.manage().window().maximize();
this.driver.manage().timeouts().pageLoadTimeout(120, TimeUnit.SECONDS);
}
#After()
public void tearDown() {
this.driver.manage().deleteAllCookies();
this.driver.quit();
}
#Given("^I access https://mynames\\.co\\.il$")
public void i_access_https_mynames_co_il() throws Throwable {
driver.get("https://mynames.co.il/");
throw new PendingException();
}
#When("^I click on Login button\\.$")
public void i_click_on_Login_button() throws Throwable {
String path = "/html/body/div[1]/div/div/section[2]/div/div/div[2]/div/div/section/div/div/div[2]/div/div/div/div/div/a/span/span";
//WebDriverWait wait = new WebDriverWait(driver, 5);
driver.findElement(By.xpath(path)).click();
throw new PendingException();
}
that's the runner class:
package runners;
import org.junit.runner.RunWith;
import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;
#RunWith(Cucumber.class)
#CucumberOptions(features = { "src/test/java/featurefiles/" }, glue = {
"stepDefinitions" }, monochrome = true, tags = {},
plugin = { "pretty", "html:target/cucumber", "json:target/cucumber.json",
"com.cucumber.listener.ExtentCucumberFormatter:output/report.html" })
public class MainRunner {
}
Hey pls use this Xpath to click that button which you marked in blue colour line
//span[contains(text(),'כניסה')]
After I've check the website (https://mynames.co.il/):
<div class="elementor-button-wrapper">
<a href="https://dash.mynames.co.il/login" target="_blank" class="elementor-button-link elementor-button elementor-size-xs" role="button">
<span class="elementor-button-content-wrapper">
<span class="elementor-button-text">כניסה</span>
</span>
</a>
</div>
I recommend 2 options:
Use the link itself to redirect on login page
String targetPage = driver.findElement(By.xpath("/html/body/div[1]/div/div/section[2]/div/div/div[2]/div/div/section/div/div/div[2]/div/div/div/div/div/a")).getAttribute("href");
driver.navigate().to(targetPage);
(Maybe this is what you want) You click on href or force a href to act like button
driver.findElement(By.xpath("/html/body/div[1]/div/div/section[2]/div/div/div[2]/div/div/section/div/div/div[2]/div/div/div/div/div/a")).click();
The reason that your code is not working is because span that you assume as button, doesn't have any click action meanwhile the click action you hope for is on a href.
// this is just text with style inside span
<span class="elementor-button-text">כניסה</span>
Are you getting any Exception ? If yes, what exception is that ? If no, selenium clicking is happening but the application is not acknowledging the click. So try using javascript executor to perform click as below
WebElement ele = driver.findelement(By.xpath("//span[text()='כניסה']"));
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript("argument[0].click();",ele);
Even after using the above code, if it doesn't work, then check if you are referring to the right feature and class files in junit runner class cucumberOptions 'glue' and 'features'
One more important tip : I see absolute xpath in your script which will not work if there is a change in the DOM structure in future, So always go for relative xpath
As the element is a dynamic element so to click() on the element you need to induce WebDriverWait for the elementToBeClickable() and you can use either of the following Locator Strategies:
cssSelector:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("a.elementor-button-link.elementor-button.elementor-size-xs span.elementor-button-text"))).click();
xpath:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//span[#class='elementor-button-text' and text()='כניסה']"))).click();

Jsoup Could not parse query

I'm converting the xpath to Jsoup
below is my xpath (which is used in my selenium webdriver)
String number = driver.findElement(By.xpath("//span[#data-dojo-attach-point='subNumber']")).getText();
equivalent jsoup
String number = doc.select(" >span >data-dojo-attach-point=subNumber").text();
System.out.println(number);
While executing getting below error
Could not parse query 'data-dojo-attach-point=subNumber': unexpected token at '=subNumber'
HTML:
<div class="subHeaders">
<div class="subHeaderItem">
<h5 class="smallGray">Number</h5>
<span data-dojo-attach-point="subNumber">94607506</span>
</div>
</div>
can anyone help this.
This is the way you could retrieve that data with selectFirst​(String cssQuery) and then html():
TestClass:
import java.io.IOException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class TestA {
public static void main(String[] args) throws IOException {
//this is where chromedriver.exe should be
String driverPath = "yourDriverPath";
System.setProperty("webdriver.chrome.driver", driverPath);
WebDriver driver = new ChromeDriver(); ;
driver.get("YourURL");
WebDriverWait wait = new WebDriverWait(driver, 15);
String cssSelector = "span[data-dojo-attach-point=subNumber]";
wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(cssSelector)));
Document doc = Jsoup.connect("YourURL").get();
Element subNumber = doc.selectFirst(cssSelector);
System.out.println(subNumber.html());
}
}
Output:
94607506
Note: I've tried the above in my laptop and it's working.
Use this CSS Selector.
div.subHeaders > div.subHeaderItem > span
String number = doc.select("div.subHeaders > div.subHeaderItem > span").text();
If the page has loaded then you will get the text. Use "Try Jsoup" to verify if you are able to get the text.
Click on this link. Click "Fetch URL" and input the URL of the page you are trying to parse and click "Fetch". Let me know if you are able to get the value.
If you don't mind posting the URL here, post the URL here. We will help you.

How to Select Dropdown which does not have a Name or ID in Selenium

I can't select the dropdown which has no attribute associated with it. Below HTML code, can see there is a select tag but no id or name with it. How do I select that tag in Selenium?
<!DOCTYPE html>
<html>
<body>
<select>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="opel">Opel</option>
<option value="audi">Audi</option>
</select>
</body>
</html>
Below is the website where that dropdown is located.
Website: https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_select
I have tried from the root of the document, following-sibling, etc., but nothing worked out.
I get NOSUCHELEMENT EXCEPTION
That is the reason, I am posting a question here.
Following is my code,
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.Select;
public class X
{
public static void main(String[] args) throws InterruptedException {
System.setProperty("webdriver.chrome.driver", "D:\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_select");
WebElement element= driver.findElement(By.xpath("/html/body/select"));
Select s = new Select(element);
s.selectByValue("saab");
}
}
Actually here the problem is, your element is in iFrame So first you need to find correct iFrame i.e with the name iframeResult in your page and switch into it.
Then you can locate same dropdown with tagname itself:
Use following code and let me know if there any issue
driver.get("https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_select");
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
driver.switchTo().frame("iframeResult");
WebElement element = driver.findElement(By.tagName("select"));
Select select = new Select(element);
select.selectByIndex(1);
First of all, click on your element to expand dropdown:
s.click()
Next try one of methods below:
s.selectByValue("saab")
s.selectByVisibleText("saab")
s.selectByIndex(1)
Your code is half correct, first of all you have to switch to frame and then try to select value from drop down . Your correct code should be like this:
public class X
{
public static void main(String[] args) throws InterruptedException {
System.setProperty("webdriver.chrome.driver", "D:\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_select");
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
driver.switchTo().frame("iframeResult");
WebElement dropdownBrands = driver.findElement(By.xpath("/html/body/select"));
Select s = new Select(dropdownBrands);
s.selectByVisibleText("Saab");
}
}

Unable to locate element radio botton in Selenium webdriver

I am a newbie trying to learn automation using the tool Selenium. I am trying to automate this website -
http://newtours.demoaut.com/
where I login and try to access this radio button (one way, round way )for flight finder.
But i am getting the error Unable to locate the element.
Tried the following.
Tried to locate the element using Xpath obtained from firebug.
Used the following Xpath composed from the html code to locate the radio button
//*[#type='radio']//*[#value='oneway']
//*[contains(#type,'radio')]
//*[contains(text(),'oneway']
//input[#type='radio' AND #value='oneway']
Also tried CSS selector to locate the element.
driver.findElement(By.cssSelector("input[type=radio][value=oneway]"))
Tried adding wait times using implicit wait and thread.sleep
The HTML script for the radio button as obtained from firebug is -
input type="radio" checked="" value="roundtrip" name="tripType"
Round Trip
input type="radio" value="oneway" name="tripType"
One Way
Given below is my code -
package gurutrial2;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.Assert;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
public class gurutrial2
{
public static WebDriver driver;
#BeforeTest
public final void preTest() {
System.setProperty("webdriver.firefox.marionette", "C:/Users/serajendran/Downloads/geckodriver-0.10.0 (1)");
DesiredCapabilities capabilities = DesiredCapabilities.firefox();
capabilities.setCapability("marionette", true);
driver = new FirefoxDriver(capabilities);
driver.get("http://newtours.demoaut.com/");
driver.manage().window().maximize();
System.out.println(driver.getTitle());
Assert.assertEquals("Welcome: Mercury Tours", driver.getTitle());
}
#Test
public final void login() {
driver.findElement(By.name("userName")).sendKeys("invalidUN");
driver.findElement(By.name("password")).sendKeys("invalidPW");
driver.findElement(By.name("login")).click();
System.out.println("login in progress");
}
#Test
public final void flightFinder() {
WebDriverWait wait = new WebDriverWait(driver, 30);
WebElement oneWayRadioButton = wait.until(ExpectedConditions.elementToBeClickable(By.linkText("oneway")));
oneWayRadioButton.click();
System.out.println("Clicked One Way");
}
}
Any help would be deeply appreciated.
//*[#type='radio']//*[#value='oneway'] - you're looking for an element of type radio and value oneway.. this xpath look for an element of type radio that has a child element with value oneway.
//*[contains(#type,'radio')] - you'll get multiple results for this
//*[contains(text(),'oneway'] - the text is not oneway, only the value attribute is oneway, the text contains 'One Way'
//input[#type='radio' AND #value='oneway'] - this should work if you change 'AND' to 'and'
Following solution worked for me on the newtour site -
driver.findElement(By.cssSelector("input[value='oneway']")).click();
Actually the problem is in your test Methods
In TestNG the execution of #Test methods is in alphabetic order by default. So in your code flightFinder() method executing before login() So even you are using right locator to click on radio button, It will show the exception.
Solution:
Maintains your method name in alphabetic order
Use priority under #Test annotation for the methods e.g. - #Test(priority = 1)
Create dependency test e.g. -
#Test()
public final void login()
{
//code
}
#Test(dependsOnMethods={"login"})
public final void flightFinder()
{
//code
}
Update your code as below and try -
#Test
public final void doLogin() {
driver.findElement(By.name("userName")).sendKeys("invalidUN");
driver.findElement(By.name("password")).sendKeys("invalidPW");
driver.findElement(By.name("login")).click();
System.out.println("login in progress");
}
#Test()
public final void flightFinder() {
driver.findElement(By.xpath("//input[#type='radio' and #value='oneway']")).click();
System.out.println("Clicked One Way");
}

How to differentiate between image link and href link in selenium webdriver?

I am trying to get the name of the links of wikipedia home page in selenium webdriver . In the home page there is a table at the bottom which contains the link of wikipedia sister projects like Media-wiki, meta wiki etc . But after running the code I am getting 24 links. But in the webpage there are only 12 links. My suspicion is it is taking the links of images also.
package tcsWebmail;
import java.io.File;
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
public class WikiPediaLinks {
public static void main(String[] args) {
WebDriver driver = new FirefoxDriver();
driver.get("https://en.wikipedia.org/wiki/Main_Page");
System.out.println(driver.getTitle());
WebElement Block=driver.findElement(By.xpath("//*[#id='mp-sister']/table//a[not(img)]"));
List<WebElement> Links= Block.findElements((By.tagName("a")));
System.out.println("Printing the no of items in block");
int i=0;
for ( i=0;i<Links.size();i++){
System.out.println(Links.get(i).getText());
}
System.out.println("The no of items are"+Links.size());
driver.quit();
}
}
Your XPath includes images as you suspect. In order to get a that don't contain a descendant img, you can to use XPath below:
//*[#id='mp-sister']/table//a[not(img)]
or
//*[#id='mp-sister']/table//a[not(descendant::*[local-name() = 'img'])]
See code below:
List<WebElement> Links= driver.findElements(By.xpath("//*[#id='mp-sister']/table//a[not(img)]"));
In for loop put another condition to check to validate imgage (img) or link (href)
List<WebElement> Links= Block.findElements((By.tagName("a")));
System.out.println("Printing the no of items in block");
for ( int i=0;i<Links.size();i++)
{
if(Links.get(i).getAttribute("href").contains("http://")
{System.out.println(Links.get(i).getText());
}
driver.quit();
}
}

Categories

Resources