Adding a public class to click using xpath with Java Selenium - java

I am trying to create a public class to click an item on a webpage with selenium by just passing it the xpath and driver I'm using. I want to be able to just do:
ClickByXpath(driver, "/html/body/div/div[3]/form/div[2]/div[2]/div[1]/div[1]/div[3]/div/div[3]/div/input[1]");
Here's the code I'm using, but it's complaining that the method xpath string is not applicable:
package TestPackage;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
public class Question {
public static void main(String[] args) throws Exception {
// The Firefox driver supports javascript
WebDriver driver = new FirefoxDriver();
// Go to google
driver.get("http://www.google.com");
//click in the searchbox
ClickByXpath(driver, "/html/body/div/div[3]/form/div[2]/div[2]/div[1]/div[1]/div[3]/div/div[3]/div/input[1]");
}
public static void ClickByXpath(WebDriver [] driverUsed , String[] XPath_to_click) throws Exception {
driverUsed.findElement(By.xpath(XPath_to_click)).click();
}
}

You are passing a String:
ClickByXpath(driver, "/html/body/div/div[3]/form/div[2]/div[2]/div[1]/div[1]/div[3]/div/div[3]/div/input[1]");
But you method signature says that you should pass a String Array:
public static void ClickByXpath(WebDriver [] driverUsed , String[] XPath_to_click)
Same problem with your driver! If you change the signature and remove the Arrays, you should be good:
public static void ClickByXpath(WebDriver driverUsed , String XPath_to_click)
Please note that this has nothing to do with Selenium, this is (very?) basic Java programming. You should consider getting some help with learning at least basics of programming first.

Related

Can I make the WebDrivers as global variables in Java

I want to create a class where I set all the common actions of the WebDrivers such as: waitExplicit, findElement, click. But if I create a method then I have to create the WebDriver and WebDriverWait over and over on each method of the class, I already tried having a class for the Drivers, but when I call the methods, they just create instances over and over, so multiple windows open, I tried this way, but still cannot get to it:
public class AutomationActions{
static LoadProperties prop = new LoadProperties(); //This class has the System.setProperty for the driver
prop.getSysProp(); //***This is the issue, how can I solve this?****
WebDriver driver = new ChromeDriver(); //this will not work without the one above working
WebDriverWait wait = new WebDriverWait(driver, 30);//this will not work without the one above working
public void waitForPageToLoad() throws Exception {
ExpectedCondition<Boolean> pageLoadCondition = new
ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
return ((JavascriptExecutor)driver).executeScript("return document.readyState").equals("complete");
}
};
// WebDriverWait wait = new WebDriverWait(driver, 30); // I want to avoid having to set this in every method
wait.until(pageLoadCondition); //this is supposed to replace the line of code above
}
I don't really work on Java much any more, I've written our framework in C# but I put together some quick classes in Java to show you how I set things up. I use page object model and I recommend you do too so I've written this example using page object model. I've written a simple test that uses Dave Haeffner's (one of the Selenium contributors) demo site, http://the-internet.herokuapp.com.
The basic concepts are:
There is a class BaseTest that holds things that correspond to tests, e.g. setting up the driver at the start of the test, quitting the driver at the end of the test, etc. All of your tests will inherit from BaseTest
There is a class BasePage that holds things that correspond to generic methods for finding elements, clicking on elements, etc. Each of your tests inherit from BasePage. (This is what I think the main part of your question is asking about).
To follow the page object model, each page (or part of a page) is its own class and holds all locators and actions done on that page. For example, a simple login page would have the locators for username, password, and the login button. It would also hold a method Login() that takes a String username and a String password, enters those in the appropriate fields and clicks the Login button.
The final class of this example is a sample test aptly named SampleTest.
You shouldn't have any FindElements() or related calls in your tests, all those should be in the appropriate page object.
This is using TestNG as the unit test library. Use it or JUnit, your preference but if you use JUnit, you will need to change the asserts and the annotations.
Under 'src', I create a folder for page objects, 'PageObjects', and a folder for tests, 'Tests'. Here's what the files look like on disk.
\src
\PageObjects
BasePage.java
DropdownListPage.java
\Tests
BaseTest.java
SampleTest.java
BasePage.java
package PageObjects;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class BasePage
{
private WebDriver driver;
private final int shortWait = 10;
public BasePage(WebDriver _driver)
{
driver = _driver;
}
public void ClickElement(By locator)
{
new WebDriverWait(driver, shortWait).until(ExpectedConditions.elementToBeClickable(locator)).click();
}
public WebElement FindElement(By locator)
{
return new WebDriverWait(driver, shortWait).until(ExpectedConditions.presenceOfElementLocated(locator));
}
// add more methods
}
DropdownListPage.java
package PageObjects;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.ui.Select;
public class DropdownListPage extends BasePage
{
private final By dropdownListLocator = By.id("dropdown");
public DropdownListPage(WebDriver _driver)
{
super(_driver);
}
public String GetSelectedOption()
{
return new Select(FindElement(dropdownListLocator)).getFirstSelectedOption().getText();
}
public void SelectOptionByIndex(int index)
{
new Select(FindElement(dropdownListLocator)).selectByIndex(index);
}
}
BaseTest.java
package Tests;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
public class BaseTest
{
public WebDriver driver;
public WebDriver GetChromeDriver()
{
System.setProperty("webdriver.chrome.driver", "C:\\Path\\To\\Chrome\\Driver\\chromedriver.exe");
return new ChromeDriver();
}
#BeforeTest
public void Setup()
{
driver = GetChromeDriver();
driver.manage().window().maximize();
driver.get("http://the-internet.herokuapp.com/dropdown");
}
#AfterTest
public void Teardown()
{
driver.close();
}
}
SampleTest.java
package Tests;
import org.testng.Assert;
import org.testng.annotations.Test;
import PageObjects.DropdownListPage;
public class SampleTest extends BaseTest
{
#Test
public void SampleTestCase()
{
DropdownListPage dropdownListPage = new DropdownListPage(driver);
dropdownListPage.SelectOptionByIndex(1);
Assert.assertEquals(dropdownListPage.GetSelectedOption(), "Option 1", "Verify first option was selected");
}
}
You will need to create a project that contains Selenium for Java and TestNG. Download them and put them on your build path. Create the folder structure as described above and create each of these classes and copy/paste the contents into them. Now all you need to do is run SampleTest as a TestNG Test and it should go.
The test creates a new Chromedriver instance, navigates to the sample page, selects the first option in the dropdown, asserts that the dropdown text is correct, and then quits the driver.
That should get you started. There's a lot of info crammed into the above wall of text, let me know if you have some questions.

Why does Selenium testing website not work on more than one page?

The first part of the code work will work. But the second part doesn't work, and no error appears, and I don't know where the problem is. So please help.
First part is the login page, and the second part is home page.
package Test;
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.chrome.ChromeDriver;
public class test {
public static void main(String[] args) throws InterruptedException {
WebDriver driver;
System.setProperty("webdriver.gecko.driver",
"E:\\Quality\\drivers\\geckodriver.exe");
driver =new FirefoxDriver();
driver.get("https://www.linkedin.com/uas/login");
// first part//
driver.findElement(By.xpath("//*[#id=\"session_key-login\"]")).click();
driver.findElement(By.xpath("//[#id=\"session_keylogin\"]")).sendKeys("Email");
driver.findElement(By.xpath("//*[#id=\"session_password-login\"]")).click();
driver.findElement(By.xpath("//*[#id=\"session_password-login\"]")).sendKeys("*******");
driver.findElement(By.xpath("//*[#id=\"btn-primary\"]")).click();
// second part//
WebElement test = null ;
test.findElement(By.xpath("/html/body/div[5]/div[5]/aside/div/header")).click();
}
}
You have putted a wrong id for xpath of email textbox.
You should use session_key-login instead of session_keylogin.
Just use the below revised code where you're using sendKeys() method:
driver.findElement(By.xpath("//*[#id=\"session_key-login\"]")).sendKeys("Email");
2nd part Solution
Skip WebElement declaration, thus comment the line //WebElement test = null;
Use the line using driver object
driver.findElement(By.xpath("/html/body/div[5]/div[5]/aside/div/header")).click();
You can also use xpath //*[#id=\"msg-overlay\"]/div/header
thus for the revised code is:
driver.findElement(By.xpath("//*[#id=\"msg-overlay\"]/div/header")).click();

Java selenium how to open a link from google search results?

I am new to automation testing in Selenium and i am doing some basic automation testing such as searching for something in Google and then clicking on a link which is required from the search results.
The code below, which i have produced works up until i get to the testing method. I am unable to select a link from the Google search page but i am not being shown any errors on my console. So i setup a thread on this particular line and it mentioned it could find the link name however the link name is used in the html code as i have checked on Google inspect.
Am i missing something obvious? I am relatively new to Selenium so any help is appreciated. Also i have tried mirroring some code from this users response "How to click a link by text in Selenium web driver java" but no luck!
Thanks
package com.demo.testcases;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class MyFirstTestScript {
private static WebDriver driver;
public static void main (String[] args) {
SetUp();
testing();
}
// TODO Auto-generated method stub
#setup
public static void SetUp () {
driver = new FirefoxDriver();
driver.get("http://www.google.co.uk");
System.setProperty("webdriver.gecko.driver", "usr/local/bin/geckodriver");
driver.findElement(By.name("q")).sendKeys("BBC" + Keys.ENTER);
}
#Test
public static void testing() {
driver.findElement(By.partialLinkText("BBC - Home")).click();
}
}
Once you obtain the search results for the text BBC on Google Home Page next to click() on the link containing the text BBC - Home you can use the following code block :
List <WebElement> my_list = driver.findElements(By.xpath("//div[#id='rso']//div[#class='rc']/h3[#class='r']/a"));
for (WebElement item:my_list)
{
if(item.getAttribute("innerHTML").contains("BBC - Home"))
item.click();
}
You can use this code:
public class MyFirstTestScript {
private static WebDriver driver;
private static WebDriverWait wait;
public static void main (String[] args) {
SetUp();
testing();
}
#setup
public static void SetUp () {
System.setProperty("webdriver.gecko.driver", "usr/local/bin/geckodriver");
driver = new FirefoxDriver();
wait = new WebDriverWait(driver,50);
driver.manage().window().maximize();
driver.get("http://www.google.co.uk");
wait.until(ExpectedConditions.elementToBeClickable(By.name("q")));
driver.findElement(By.name("q")).sendKeys("BBC" + Keys.ENTER);
}
#Test
public static void testing(){
wait.until(ExpectedConditions.visibilityOf(driver.findElement(By.linkText("BBC - Homepage"))));
driver.findElement(By.linkText("BBC - Homepage")).click();
}

Selenium cannot find element on website (chrome/Java)

Trying to test/learn selenium to login
the error - Exception in thread "main" org.openqa.selenium.ElementNotVisibleException: element not visible
package com.indeed.tests;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
public class test1 {
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver",
"C:\\Users\\****\\Desktop\\neww\\trainingfiles\\chromedriver.exe.exe");
WebDriver driver = new ChromeDriver();
driver.get("http://www.neopets.com/login/index.phtml");
driver.findElement(By.name("username")).sendKeys("test1");
}
private static void sleep(int i) {
}
}
I had a look at that web page. The problem is that there are two input fields with the name "username". One of them is not visible. Probably Selenium is getting that one. What you should do is:
List<WebElement> elements = driver.findElements(...);
and then get the second one (or the first, whatever), then try:
elements.get(1).sendKeys(...);

creating user defined function for selenium webdriver

I want to create some user defined functions for my webdriver automation code. I tried it, but resulted in failure.
the following is my code
public class snapdeal {
WebDriver driver= new FirefoxDriver();
#Test
public void test() {
// I want open browser in function 1
driver.get("http://amazon.in");
driver.manage().window().maximize();
// Function 2 for searching
driver.findElement(By.xpath("//li[#id='nav_cat_2'")).click();
driver.findElement(By.id("twotabsearchtextbox")).sendKeys("Shoes");
driver.findElement(By.xpath("//input[#class='nav-submit-input']")).click();
driver.findElement(By.xpath("//h2[#class='a-size-medium s-inline s-access-title a-text-normal' and contains(text(), \"Fbt Men's 8876 Casual Shoes\")]")).click();
}
}
How ca i write two functions inside the class?
You were probably trying to nest methods inside test() . It is not possible.
You can use this code below which calls the respective methods in the test(). It works as expected:
public class snapdeal {
static WebDriver driver= new FirefoxDriver();
#Test
public void test() {
//Method1 for Opening Browser.
openBrowser();
// Method2 for searching
searchElement();
}
public static void openBrowser(){
driver.get("http://amazon.in");
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
}
public static void searchElement(){
driver.findElement(By.xpath("//li[#id='nav_cat_2']")).click();
driver.findElement(By.id("twotabsearchtextbox")).sendKeys("Shoes");
driver.findElement(By.xpath("//input[#class='nav-submit-input']")).click();
driver.findElement(By.xpath("//h2[#class='a-size-medium s-inline s-access-title a-text-normal' and contains(text(), \"Fbt Men's 8876 Casual Shoes\")]")).click();
}
}
I think this is like a Hello World for Selenium for you, you could make use defined methods in Java using Junit with the following annotations which can be found here
But as per norms we usually have a #Before method in Junit or #BeforeTest method in testng for setting up the webdriver and the url of AUT, also in your code a couple of xpaths were wrong which were causing the error, Please find below the correct working code with comments:
import java.util.concurrent.TimeUnit;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.safari.SafariDriver;
public class snapdeal {
public WebDriver driver;
#Before
public void setUP()
{
// I want open browser in function 1
driver= new SafariDriver();
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
driver.get("http://amazon.in");
driver.manage().window().maximize();
}
#Test
public void test() {
// Function 2 for searching
//driver.findElement(By.xpath("//li[#id='nav_cat_2")).click(); //element not needed
driver.findElement(By.id("twotabsearchtextbox")).sendKeys("Shoes");
driver.findElement(By.xpath("//input[#class='nav-submit-input']")).click();
driver.findElement(By.xpath("//*[#title=\"Fbt Men's 8876 Casual Shoes\"]//h2")).click();
}
}
The above code works as desired.
Creating user defined function have two different scope
1) Create function with piece of code and call that function whenever u needed it (Which is done above)
2) Second one creating a custom function wrt each controls like edit boxes , radiobutton , check boxes - etc , so by creating this functions u can make better feasible of your automation framework

Categories