This is a sample code for the explicit wait:
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("xpath-here")));
I want to pass WebElement as a parameter in method and wait until that WebElement is located:
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.visibilityOfElementLocated(MyWebElement));
I am not sure whether such option is already there and can be done in a different way as in my case I am getting an exception as I am passing WebElement in place of By.xpath("") which is not the correct way.
You need to use the visibilityOf expected condition.
The code will be like:
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.visibilityOf(MyWebElement));
Hope it helps you!
Yes, you cannot pass the web element in place of XPath because the method 'visibilityOfElementLocated()' will accept only By locator.
Suppose, your method is like below :
public static void waitUntilLocated(WebDriver driver, int waitingTime, By locator) {
new WebDriverWait(driver, waitingTime).until(ExpectedConditions.visibilityOfElementLocated(locator));
}
Then You can store the By locator like below :
By someXPath = By.xpath("some xpath here");
Then you can pass 'By locator' to the method as a parameter
waitUntilLocated(driver, 30, someXPath);
Below is the whole code :
import java.net.URL;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class Test1 {
public static void waitUntilLocated(WebDriver driver, int waitingTime, By locator) {
new WebDriverWait(driver, waitingTime).until(ExpectedConditions.visibilityOfElementLocated(locator));
}
public static void main(String ...ali) throws Exception {
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setBrowserName("chrome");
WebDriver driver = new RemoteWebDriver(new URL("http://127.0.0.1:1234/wd/hub"), capabilities);
driver.get("http://www.google.com");
driver.findElement(By.name("q")).sendKeys("Alicse3"+Keys.ENTER);
// Checking element is located or not?
By someXPath = By.xpath("some xpath here");
waitUntilLocated(driver, 30, someXPath);
// Checking some other element
By someId = By.id("some id");
waitUntilLocated(driver, 30, someId);
}
}
Or you can do like below if you want to pass Web Element to the method and don't want to use 'visibilityOfElementLocated()' :
import java.net.URL;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class Test1 {
public static void waitUntilLocated(WebDriver driver, int waitingTime, WebElement element) {
new WebDriverWait(driver, waitingTime).until(ExpectedConditions.visibilityOf(element));
}
public static void main(String ...ali) throws Exception {
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setBrowserName("chrome");
WebDriver driver = new RemoteWebDriver(new URL("http://127.0.0.1:1234/wd/hub"), capabilities);
driver.get("http://www.google.com");
driver.findElement(By.name("q")).sendKeys("Alicse3"+Keys.ENTER);
// Checking element is located or not?
WebElement element = driver.findElement(By.xpath("Some XPath"));
waitUntilLocated(driver, 30, element);
// Checking some other element
element = driver.findElement(By.id("Some ID"));
waitUntilLocated(driver, 30, element);
}
}
I hope it helps...
Related
package Pages;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
public class HomePage {
WebDriver driver;
public HomePage() {
System.setProperty ("webdriver.chrome.driver", "D:\\Desktop\\Selenium\\chromedriver.exe");
this.driver = new ChromeDriver ();
PageFactory.initElements (driver, this);
}
#FindBy(xpath = "//*[#id='MenuContent']/a[2]")
WebElement signInButton;
public void signInButtonClick() {
signInButton.click();
}
}
and this is the main method:
import Pages.HomePage;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) {
System.setProperty ("webdriver.chrome.driver", "D:\\Desktop\\Selenium\\chromedriver.exe");
WebDriver driver = new ChromeDriver ();
driver.manage ().timeouts ().implicitlyWait (10, TimeUnit.SECONDS);
driver.manage ().window ().maximize ();
driver.get ("https://petstore.octoperf.com/actions/Catalog.action");
HomePage homePage = new HomePage ();
homePage.signInButtonClick ();
}
}
i am trying to get a locator (CSS or XPATH or really anything by this point) for a specific link and i cant manage no matter what I try.
this is the link in question:
Sign In
I have tried to find locators for a[text()='Sign In']
after I run the main method the process does not execute and this are the errors:
*** Element info: {Using=xpath, value=//*[#id='MenuContent']/a[2]}
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:78)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
at org.openqa.selenium.remote.http.W3CHttpResponseCodec.createException(W3CHttpResponseCodec.java:187)
at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:122)
at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:49)
at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:158)
at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:83)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:552)
at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:323)
at org.openqa.selenium.remote.RemoteWebDriver.findElementByXPath(RemoteWebDriver.java:428)
at org.openqa.selenium.By$ByXPath.findElement(By.java:353)
at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:315)
at org.openqa.selenium.support.pagefactory.DefaultElementLocator.findElement(DefaultElementLocator.java:69)
at org.openqa.selenium.support.pagefactory.internal.LocatingElementHandler.invoke(LocatingElementHandler.java:38)
at jdk.proxy2/jdk.proxy2.$Proxy4.click(Unknown Source)
at Pages.HomePage.signInButtonClick(HomePage.java:23)
at Main.main(Main.java:17)
There are few things incorrect here.
Driver is getting initialized 2 times which should not be correct.
Path to geckodriver seems incorrect as well.
I am adding the correct code below but have used chromedriver instead of geckodriver. It is working with the below code.
package sample;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
public class HomePage {
WebDriver driver;
public HomePage() {
System.setProperty ("webdriver.chrome.driver", "/Users/riteshpc/Documents/eclipse-workspace/Drivers/chromedriver");
this.driver = new ChromeDriver();
PageFactory.initElements (driver, this);
}
#FindBy(xpath = "//a[text()='Sign In']")
WebElement signInButton;
public void signInButtonClick() {
signInButton.click();
}
}
package sample;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.WebDriver;
public class Main {
public static void main(String[] args) {
HomePage homePage = new HomePage();
WebDriver driver = homePage.driver;
driver.manage().timeouts().implicitlyWait (10, TimeUnit.SECONDS);
driver.manage().window().maximize();
driver.get("https://petstore.octoperf.com/actions/Catalog.action");
homePage.signInButtonClick();
}
}
To copy your driver location, you can simply go to the driver's folder location in your eclipse and right click the driver and from properties you can copy path.
I have added the screenshot below.
There are a few things that need to be corrected.
You are creating 2 drivers, one in main and one in HomePage. You should create driver from your main and pass that instance into HomePage through the constructor.
Your first XPath, as you posted it, is not valid. a[text()='Sign In'] should be //a[text()='Sign In'].
The creator of Selenium has stated that PageFactory and implicit waits are a bad practice and should not be used. Instead use the Page Object Model and WebDriverWait.
I rewritten your code and tested it and it successfully clicks the Sign In link.
Main.java
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import Pages.HomePage;
public class Main {
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver", "D:\\Desktop\\Selenium\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://petstore.octoperf.com/actions/Catalog.action");
HomePage homePage = new HomePage(driver);
homePage.signInButtonClick();
}
}
HomePage.java
package Pages;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
public class HomePage {
WebDriver driver;
private By signInButton = By.xpath("//a[text()='Sign In']");
public HomePage(WebDriver driver) {
this.driver = driver;
}
public void signInButtonClick() {
driver.findElement(signInButton).click();
}
}
I'm having major issue trying to select menu two elements on a dropdown.I've tried xpaths, link texts and css selector but it wont select either the password button or logout button.
Xpaths used for Password button: "//*[#id='app']/header/div[3]/nav/ul/li/a"
CSS used for Logout button: ["data-logged-in-log-out-button"]
XPath used for Logout button: "//*[#id='app']/header/div[3]/nav/ul/a"
The error im getting for the select password is:
org.openqa.selenium.WebDriverException: unknown error: Element ... is not clickable at point (989, 233).
Other element would receive the click: ...
Please try with the below XPath along with the explicit wait condition.
XPath:
//*[contains(text(),'Log out')]
Can you please try -
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 A {
public static void main(String[] args) {
WebDriver driver = new ChromeDriver();
driver.get("url here");
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.elementToBeClickable(By.linkText("Log Out")));
driver.findElement(By.linkText("Log Out")).click();;
}
}
If it still doesn't work, please try -
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class A {
public static void main(String[] args) {
WebDriver driver = new ChromeDriver();
driver.get("url here");
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].click();", driver.findElement(By.linkText("Log Out")));
}
}
I am facing a very strange problem. I am trying to open facebook>click on forgotten account link> then opening it in a new tab> click on two textboxes.
My code is :
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class OpenLinkInNewTabTest {
public static void main(String[] args) throws Exception {
System.setProperty("webdriver.chrome.driver", "<path>\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("http://www.facebook.com");
String ParentWindowHandle = driver.getWindowHandle();
WebElement w = driver.findElement(By.linkText("Forgotten account?"));
new Actions(driver)
.keyDown(Keys.CONTROL)
.keyDown(Keys.SHIFT)
.click(w)
.keyUp(Keys.SHIFT)
.keyUp(Keys.CONTROL)
.perform();
new Actions(driver)
.sendKeys(Keys.CONTROL + "w")
.perform();
// ArrayList<String> tabs = new ArrayList<String> (driver.getWindowHandles());
//
// driver.switchTo().window(tabs.get(1));
// WebElement fn = (new WebDriverWait(driver, 20))
// .until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#identify_email")));
// System.out.println(driver.getTitle());
// fn.sendKeys("abcdejf:");
for(String winHandle : driver.getWindowHandles()){
driver.switchTo().window(winHandle);
if(driver.getTitle().contains("Forgotten Password ")){
Thread.sleep(5000);
driver.findElement(By.cssSelector("#identify_email")).sendKeys("adf");
driver.findElement(By.name("email")).sendKeys("ASF");
driver.close();
driver.switchTo().window(ParentWindowHandle);
break;
}
}
driver.findElement(By.name("email")).sendKeys("ASF");
}
}
However, I am unable to send value to
driver.findElement(By.cssSelector("#identify_email")).sendKeys("adf");
The element looks like:
<input id="identify_email" class="inputtext" name="email" autofocus="1" type="text">
If I write a similar code like:
System.setProperty("webdriver.chrome.driver","path\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("http://www.facebook.com");
driver.findElement(By.linkText("Forgotten account?")).click();
driver.findElement(By.name("email")).sendKeys("ASF");
driver.findElement(By.cssSelector("#identify_email")).sendKeys("adf");
It is able to click both the elements properly.
I am not seeing any element not found exception too while running it. Please help me to debug this issue.
Thanks.
UPDATE:
Running this code sometimes show
Exception in thread "main" org.openqa.selenium.InvalidElementStateException: invalid element state
(Session info: chrome=56.0.2924.87)
Wait for this element:
WebDriverWait wait = new WebDriverWait(driver, 10);
String email = "you#domain.com";
WebElement emailInputField = wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#identify_email")));
JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("arguments[0].setAttribute('value', ' " + email + "')", emailInputField);
break;
Clicking activates this element.
package Chrome_Packg;
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.interactions.Actions;
public class testFirefox_DragDrop {
public static void main(String[] args) throws InterruptedException {
WebDriver driver=new FirefoxDriver();
driver.get("http://jqueryui.com/droppable/");
WebElement drag=driver.findElement(By.xpath("/html/body/div[1]"));//drag element
WebElement drop=driver.findElement(By.xpath("/html/body/div[2]"));//drop element
Actions action=new Actions(driver);
Thread.sleep(3000);
action.dragAndDrop(drag, drop).perform();
}
}
After executing the code, using Run as java application, in output I am getting nothing.
Here is the code snippet for the same website that you are trying on and you can also find the example here selenium Drag and Drop example
driver = new FirefoxDriver();
driver.manage().window().maximize();
driver.navigate().to("http://jqueryui.com/droppable/");
//Wait for the frame to be available and switch to it
WebDriverWait wait = new WebDriverWait(driver, 5);
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.cssSelector(".demo-frame")));
WebElement Sourcelocator = driver.findElement(By.cssSelector(".ui-draggable"));
WebElement Destinationlocator = driver.findElement(By.cssSelector(".ui-droppable"));
dragAndDrop(Sourcelocator,Destinationlocator);
String actualText=driver.findElement(By.cssSelector("#droppable>p")).getText();
Assert.assertEquals(actualText, "Dropped!");
Using an example from Selenium Wedriver Practical Guide (to login in and create a test post on Wordpress), I encounter the above mentioned error.
Here is the PageObject that I am using:
package com.PageObjects;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.How;
import org.openqa.selenium.support.PageFactory;
/**
* Created by JTester on 3/9/2016.
*/
public class AdminLoginPage {
WebDriver driver;
#FindBy(how=How.ID, id="user_login")
WebElement email;
#FindBy(how=How.ID, id="user_pass")
WebElement pwd;
#FindBy(how=How.ID, id="wp-submit")
WebElement submit;
public AdminLoginPage(WebDriver driver){
this.driver = driver;
driver.get("http://mysite.wordpress.com/wp-admin/");
}
public void login(){
email.sendKeys("myEmailAddress#yahoo.com");
pwd.sendKeys("myPasswd");
submit.click();
}
}
And here is the test class:
package com.features.trial;
import com.PageObjects.AdminLoginPage;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
/**
* Created by JTester on 3/9/2016.
*/
public class TestAddNewPost {
public static void main(String... args) {
WebDriver driver = new FirefoxDriver();
//login to wordpress admin
AdminLoginPage admLoginPage = new AdminLoginPage(driver);
admLoginPage.login();
//go to AllPosts page
driver.get("http://mysite.wordpress.com/wp-admin/edit.php");
//add a new post
WebElement addNewPost = driver.findElement(By.linkText("Add New"));
addNewPost.click();
//add new post's content
driver.switchTo().frame("content_ifr");
WebElement postBody = driver.findElement(By.id("tinymce"));
postBody.sendKeys("This is my description.");
driver.switchTo().defaultContent();
WebElement title = driver.findElement(By.id("title"));
title.sendKeys("This is my first post");
//publish my post
WebElement publish = driver.findElement(By.id("publish"));
publish.click();
}
}
Since I am new to Selenium and Page Objects, could anyone explain why it is throwing the following error:
Exception in thread "main" java.lang.NullPointerException
at com.PageObjects.AdminLoginPage.login(AdminLoginPage.java:29)
at com.features.trial.TestAddNewPost.main(TestAddNewPost.java:17)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Process finished with exit code 1
Many thanks..
ps: After looking at a lot of code examples on the web, I think I need to use PageFactory to instantiate my elements but not sure if this is true, and if it is, how do I go about it using my example code.
Debugger Screenshot :
AdminLoginPage should have been initialized using PageFactory.
import org.openqa.selenium.support.PageFactory;
public AdminLoginPage(WebDriver driver){
PageFactory.initElements(driver, this); //add this
this.driver = driver;
driver.get("http://mysite.wordpress.com/wp-admin/");
}
Add the following code:
AdminLoginPage loginPage = PageFactory.initElements(driver,AdminLoginPage.class);
loginPage.login();
to the TestAddNewPost class, instead of using the existing code:
AdminLoginPage admLoginPage = new AdminLoginPage(driver);
admLoginPage.login();