Actions class - click(WebElement ele) function does not clicks - selenium

I am trying to use the click(WebElement) method of the Actions class to click on an element on the google homepage. The code runs successfully but the click event is not trigerred.
package p1;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.WebElement;
public class ClickLink
{
static WebDriver driver;
public static void main(String[] args)
{
try
{
driver = new FirefoxDriver();
driver.manage().window().maximize();
driver.get("http://www.google.com/");
WebElement icon = driver.findElement(By.xpath(".//*[#id='gbwa']/div[1]/a"));
Actions ob = new Actions(driver);
ob.click(icon);
System.out.println("Link Clicked !!");
Thread.sleep(10000);
driver.close();
}
catch(Exception e)
{
System.out.println("Exception occurred : "+e);
driver.close();
}
}
}
Here is the result when the above script is executed : [link]
However, when the same element is clicked using the click() method of the WebElement interface, then the click is trigerred.
package p1;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.WebElement;
public class ClickLink
{
static WebDriver driver;
public static void main(String[] args)
{
try
{
driver = new FirefoxDriver();
driver.manage().window().maximize();
driver.get("http://www.google.com/");
WebElement icon = driver.findElement(By.xpath(".//*[#id='gbwa']/div[1]/a"));
icon.click();
System.out.println("Link Clicked !!");
Thread.sleep(10000);
driver.close();
}
catch(Exception e)
{
System.out.println("Exception occurred : "+e);
driver.close();
}
}
}
Here is the result when the above script is executed : [link]
Please let me know the reason as to why the click event is not trigerred and resolution for the same.

You have made a simple mistake of not building and performing the Action.
Note that you have created an instance of Actions class ob. As the name signifies the Actions class defines a set of sequential actions to be performed. So you have to build() your actions to create a single Action and then perform() the action.
The below code should work!!
WebElement icon = driver.findElement(By.xpath(".//*[#id='gbwa']/div[1]/a"));
Actions ob = new Actions(driver);
ob.click(icon);
Action action = ob.build();
action.perform();
If you look at the code given below to first move to the icon element and then click the element would better explain the Actions class.
Actions ob = new Actions(driver);
ob.moveToElement(icon);
ob.click(icon);
Action action = ob.build();
action.perform();

Here is what you need to do:
ob.click(icon).build().perform();
also you can do this:
ob.moveToElement(icon).click().build().perform();

In web automation, this issue keeps coming. Reasons can be multiple. Let's see them one by one :
Actions class not properly utilized :
Link to Official documentation
As the method documentation says,
Call perform() at the end of the method chain to actually perform the actions.
The general way to achieve click using Actions class is below :
actionsObj.moveToElement(element1).click().build().perform()
If Actions class fails , sometimes the reason can be that you receive below exception :
ElementNotInteractableException [object HTMLSpanElement] has no size and location
That can mean two things :
a. Element has not properly rendered: Solution for this is just to use implicit /explicit wait
Implicit wait :
driver.manage().timeouts().implicitlyWait(50, TimeUnit.SECONDS);
Explicit wait :
WebDriverWait wait=new WebDriverWait(driver, 20);
element1 = wait.until(ExpectedConditions.elementToBeClickable(By.className("fa-stack-1x")));
b. Element has rendered but it is not in the visible part of the screen: Solution is just to scroll till the element. Based on the version of Selenium it can be handled in different ways but I will provide a solution that works in all versions :
JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("arguments[0].scrollIntoView(true);", element1);
Suppose all this fails then another way is to again make use of Javascript executor as following :
executor.executeScript("arguments[0].click();", element1);
If you still can't click , then it could again mean two things :
1. Iframe
Check the DOM to see if the element you are inspecting lives in any frame. If that is true then you would need to switch to this frame before attempting any operation.
driver.switchTo().frame("a077aa5e"); //switching the frame by ID
System.out.println("********We are switching to the iframe*******");
driver.findElement(By.xpath("html/body/a/img")).click();
2. New tab
If a new tab has opened up and the element exists on it then you again need to code something like below to switch to it before attempting operation.
String parent = driver.getWindowHandle();
driver.findElement(By.partialLinkText("Continue")).click();
Set<String> s = driver.getWindowHandles();
// Now iterate using Iterator
Iterator<String> I1 = s.iterator();
while (I1.hasNext()) {
String child_window = I1.next();
if (!parent.equals(child_window)) {
driver.switchTo().window(child_window);
element1.click()
}

Related

Selenium Web Driver code with Java not navigating the website

I have below code in eclipse. I am trying to execute it in Chrome. It works fine till clicking on ID #divpaxinfo, but it does not add number of adults. On IE, It does nothing. It just opens the webpage and stops navigating. I have been struggling to know what is the issue, but nothing seems wrong at my end. What could be the issue with?
package testProject2;
import org.openqa.selenium.By;
import org.openqa.selenium.By.ById;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.Select;
public class test2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.setProperty("webdriver.chrome.driver", "C:\\Users\\bk0107\\Documents\\QA\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("http://spicejet.com");
driver.findElement(By.id("divpaxinfo")).click();
/*int i=1;
while(i<5)
{
driver.findElement(By.id("hrefIncAdt")).click();//4 times
i++;
}*/
System.out.println(driver.findElement(By.id("divpaxinfo")).getText());
for(int i=1;i<5;i++)
{
driver.findElement(By.id("hrefIncAdt")).click();
}
driver.findElement(By.id("btnclosepaxoption")).click();
System.out.println(driver.findElement(By.id("divpaxinfo")).getText());
}
}
The real problem here is that ChromeDriver is really really fast. As a result it's trying to click on an element before Chrome has finished rendering it and the element is not yet clickable.
The correct solution is to use an explicit wait to wait until the element is clickable, then click on it. You should never mix implicit and explicit waits, so once you have decided to use explicit waits stick with them (they are best practice).
I've added a full set of refactored code, you really only need to add the WebDriver wait and tweak your loop though.
driver.get("http://spicejet.com");
driver.findElement(By.id("divpaxinfo")).click();
System.out.println(driver.findElement(By.id("divpaxinfo")).getText());
WebDriverWait wait = new WebDriverWait(driver, 15, 50);
for (int i = 1; i < 5; i++) {
wait.until(ExpectedConditions.elementToBeClickable(By.id("hrefIncAdt"))).click();
}
driver.findElement(By.id("btnclosepaxoption")).click();
System.out.println(driver.findElement(By.id("divpaxinfo")).getText());
This explicitly waits for the element that you want to click on to be clickable before you click on it, this is a better check than visibility because an element can be visible, but not clickable.
Add Implicit wait and browser maximize code Just after creating instance of driver as follows :
WebDriver driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS);
driver.manage().window().maximize();
Suggestion : Add some wait(implicit/fluent) in script for proper execution
Your Program with improvements :
package practice;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.util.concurrent.TimeUnit;
public class Program1 {
public static void main(String[] args) throws InterruptedException {
System.setProperty("webdriver.chrome.driver","src\\main\\resources\\drivers\\win\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS);
driver.manage().window().maximize();
driver.get("http://spicejet.com");
WebDriverWait wait=new WebDriverWait(driver, 20);
WebElement element =wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("divpaxinfo")));
element.click();
System.out.println(driver.findElement(By.id("divpaxinfo")).getText());
WebElement element1 =wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("hrefIncAdt")));
for(int i=1;i<5;i++){
element1.click();
}
driver.findElement(By.id("btnclosepaxoption")).click();
System.out.println(driver.findElement(By.id("divpaxinfo")).getText());
}
}

Running selenium test with DrJava IDE

It is possible to run the selenium libraries on DrJava, if so how can I make the test case to run the respective libraries.
I'm tying to run some test cases in Junit
I think you can run Selenium on DrJava. Therefore you have to follow instructions here to get started. Then just create the sample class like this and enjoy the testing:
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.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.WebDriverWait;
public class Selenium2Example {
public static void main(String[] args) {
// Create a new instance of the Firefox driver
// Notice that the remainder of the code relies on the interface,
// not the implementation.
WebDriver driver = new FirefoxDriver();
// And now use this to visit Google
driver.get("http://www.google.com");
// Alternatively the same thing can be done like this
// driver.navigate().to("http://www.google.com");
// Find the text input element by its name
WebElement element = driver.findElement(By.name("q"));
// Enter something to search for
element.sendKeys("Cheese!");
// Now submit the form. WebDriver will find the form for us from the element
element.submit();
// Check the title of the page
System.out.println("Page title is: " + driver.getTitle());
// Google's search is rendered dynamically with JavaScript.
// Wait for the page to load, timeout after 10 seconds
(new WebDriverWait(driver, 10)).until(new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver d) {
return d.getTitle().toLowerCase().startsWith("cheese!");
}
});
// Should see: "cheese! - Google Search"
System.out.println("Page title is: " + driver.getTitle());
//Close the browser
driver.quit();
}
}

Selenium fluent wait and page factories

So, I've been rattling my head with this challenge, so far I'm not winning.
I'd highly appreciate if anyone could assist me with this.
Details as follows.
Below is the code Example: 1,
1.In example 1, the incorrect xpath is this "//input[#id='identifierIdd']"
2.This is deliberate just to examine fluent wait. As expected after 1 minute test exited and with exception org.openqa.selenium.NoSuchElementException:
import com.google.common.base.Function;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;
import static java.util.concurrent.TimeUnit.MINUTES;
import static java.util.concurrent.TimeUnit.SECONDS;
public class Tester01 {
public static void main(String[] args) {
WebDriver webDriver = new ChromeDriver();
webDriver.get("https://accounts.google.com/
signin/v2/identifier?
continue=https%3A%2F%2Fmail.google.com%2Fmail%2F
&service=mail&sacu=1&rip=1&flowName=GlifWebSignIn
&flowEntry=ServiceLogin");
webDriver.manage().window().maximize();
WebElement webElement;
Wait<WebDriver> fluentWaiter = new FluentWait<WebDriver>
(webDriver).withTimeout(1, MINUTES)
.pollingEvery(5, SECONDS)
.withMessage("element couldn't be found after 1 minutes")
.ignoring(NoSuchElementException.class);
webElement = fluentWaiter.until(new Function<WebDriver,
WebElement>()
{
public WebElement apply(WebDriver driver) {
return driver.findElement(By.xpath
("//input[#id='identifierIdd']"));
}
});
webElement.sendKeys("testemail.com");
}
}
So, I've decided to experiment with fluentwait & pageFactory unfortunately I couldn't figure out how to achieve the below line from Tester01 class with pageFactory.
return driver.findElement(By.xpath("//input[#id='identifierIdd']"));
Details for fluentwait & pageFactory experimentation.
Below is the code Example: 2,
import org.openqa.selenium.By;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.How;
public class LocatorTest{
#FindBy(how = How.XPATH, using="//input[#id='identifierIdd']")
public WebElement elementTest;
}
And Tester01 class with LocatorTest class
public class Tester01 {
public static void main(String[] args) {
WebDriver webDriver = new ChromeDriver();
webDriver.get("https://accounts.google.com/signin/v2/identifier?
continue=https%3A%2F%2Fmail.google.
com%2Fmail%2F&service=mail&sacu=1&rip=1
&flowName=GlifWebSignIn&flowEntry=ServiceLogin");
webDriver.manage().window().maximize();
WebElement webElement;
Wait<WebDriver> fluentWaiter = new FluentWait<WebDriver>(webDriver)
.withTimeout(1, MINUTES)
.pollingEvery(5, SECONDS)
.withMessage("element couldn't be found after 1 minutes")
.ignoring(NoSuchElementException.class);
LocatorTest locatorTest = new LocatorTest();
PageFactory.initElements(webDriver, locatorTest);
webElement = fluentWaiter.until
(new Function<WebDriver, WebElement>()
{
public WebElement apply(WebDriver driver) {
return locatorTest.elementTest;
}
});
webElement.sendKeys("testemail.com");
}
}
So Tester01 class with pagefactory doesn't wait fluently for 1 min, test fails immediately with org.openqa.selenium.NoSuchElementException:
I think I know what the issue is however doesn't really know how to overcome this issue,
This is my explanation of the issue, in Example: 2 Tester01 class the return statement in fluentWaiter instance doesn't use the appropriate driver instance.
This is the line I'm talking about return locatorTest.elementTest; because I think the method apply() accepts an Webdriver instance however
the line return locatorTest.elementTest; doesn't utilise the driver instance.
Is my thinking correct?
could someone please assist me with this issue please?
Or propose an alternative solution please?
Please let me know if any of the above doesn't make sense or need more info.
Thanks in advance
Niro
PageFactory.initElements() will create Proxy for all the WebElement and List<WebElement> fields. And also setup the locator strategies that are passed in FindBy annotation. No location of elements is performed. It is a lazy initialization. The actual location will be done when commands like click(), sendkeys() etc are sent to the webelement.
Now in first case, you search for the actual element
webElement = fluentWaiter.until(new Function<WebDriver,
WebElement>()
{
public WebElement apply(WebDriver driver) {
return driver.findElement(By.xpath
("//input[#id='identifierIdd']"));
}
});
In the second case, you are just making a java call to a page object which returns you back the Proxy object. No selenium business is involved.
webElement = fluentWaiter.until
(new Function<WebDriver, WebElement>()
{
public WebElement apply(WebDriver driver) {
return locatorTest.elementTest;
}
});
But when this code is run - webElement.sendKeys("testemail.com");, actual element location is done and it fails. There is no wait involved here. The PageFactory was initialized with the webDriver instance.
Look at [ExpectedConditions] class which you can use along with the FluentWait or the specialized [WebDriverWait]. Use a method like visibilityOf(WebElement) from ExpectedConditions which return the ExpectedCondition<WebElement>.
Or you can even look at a LocatorFactory which waits for a certain time period while searching for an element. AjaxElementLocatorFactory and AjaxElementLocator. Though this will be an overkill as these are meant for Ajax cases rather than a wrong locator.

My scrip works fine in java class but same script fails when I use testng. It just opens the browser and fails my script

Please Find the below code: I have performed the following steps, but didn't worked.
Please Help:
public class ForSe_TestCases
public WebDriver driver;
#BeforeTest
public void setup ()
{
System.setProperty("webdriver.chrome.driver", "path");
WebDriver driver =new ChromeDriver();
driver.manage().deleteAllCookies();
}
#Test(priority = 0)
public void Validlogin_IO () throws InterruptedException {
driver.navigate().to("http://**URL**");
driver.findElement(By.xpath("//*[#id='email_address']")).sendKeys("tengku.forse#gmail.com");
driver.findElement(By.xpath("//*[#id='password']")).sendKeys("Pass12345");
driver.findElement(By.xpath("//*[#id='login-form']/div[4]/button")).click();
System.out.println("Login button pressed");
}
What can be the issue with TestNG ?
Try any/all of the following
Remove and Add TestNG jar again to ur project build path
UNinstall and reinstall the TestNG plugin
Clean the Eclipse project amd rerun.
If nothing works try this :
public static void main(String[] args) {
TestListenerAdapter tla = new TestListenerAdapter();
TestNG testng = new TestNG();
testng.setTestClasses(new Class[] { YOURCLASSNAME.class });
testng.addListener(tla);
testng.run();
}
In place of YOURCLASSNAME give the classname that contains the #Test annotations. This is like running your testing without the plugin from main method.
Sanchit, I think it fails because you are not waiting for the element to appear on the page and the webDriver (which is faster than its shadow!) thinks the first element you are trying to locate isn't there (id='email_address).
Try reading here for implicit or explicit way to wait or use this code of mine below instead (if the element is present then the method returns true):
public boolean waitForElement(String elementXpath, int timeOut) {
try{
WebDriverWait wait = new WebDriverWait(driver, timeOut);
boolean elementPresent=wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(elementXpath)).isDisplayed());
System.out.printf("%nElement is present [T/F]..? ")+elementPresent;
}
catch(TimeoutException e1){e1.printStackTrace();elementPresent=false;}
return elementPresent;
}
Update after OP's comments
To see if my method works, try replacing your first find element line:
driver.findElement(By.xpath("//*[#id='email_address']")).sendKeys("tengku.forse#gmail.com"); //this is official email
with this code below instead (then your script won't break from then ownwards, if it does use this waiting method again for the 'breaking' element). I think your script is breaking straight away because you locate the element and sendKeys very fast without waiting for it to appear first!
waitForElement ("//*[#id='email_address']", 10);
if(elementPresent==true){
driver.findElement(By.xpath("//*[#id='email_address']")).sendKeys("tengku.forse#gmail.com");
}
else{
System.out.println("FATAL! Couldn't locate email address field!");
}
Hope you can crack it this time round!
Update to Chrome driver 2.28, Google Chrome to 57.x and Selenium to 3.x.x You also have to set the path of the Chrome driver before you open the browser.
package demo;
import java.util.concurrent.TimeUnit;
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.chrome.ChromeOptions;
import org.openqa.selenium.interactions.Actions;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
public class TestAnyURL_TestNG
{
WebDriver driver;
#BeforeTest
public void setup ()
{
System.setProperty("webdriver.chrome.driver", "C:\\Utility\\BrowserDrivers\\chromedriver.exe");
ChromeOptions options = new ChromeOptions();
options.addArguments("test-type");
options.addArguments("start-maximized");
options.addArguments("--js-flags=--expose-gc");
options.addArguments("--enable-precise-memory-info");
options.addArguments("--disable-popup-blocking");
options.addArguments("--disable-default-apps");
options.addArguments("test-type=browser");
options.addArguments("disable-infobars");
driver = new ChromeDriver(options);
driver.manage().deleteAllCookies();
}
#Test(priority = 0)
public void Validlogin_IO () throws InterruptedException
{
driver.navigate().to("http://google.com"); //ForSe test environment URL
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
driver.findElement(By.xpath("//*[#id='email_address']")).sendKeys("tengku.forse#gmail.com"); //this is official email
driver.findElement(By.xpath("//*[#id='password']")).sendKeys("Pass12345"); //this is password
driver.findElement(By.xpath("//*[#id='login-form']/div[4]/button")).click(); //click on submit button to login
System.out.println("Login button pressed"); } //This code is to add new case
#Test (priority = 1)
public void AddCase() throws InterruptedException
{
WebElement element = driver.findElement(By.partialLinkText("Add Case")); //To find 'Add Case' button on dashboard
Actions action = new Actions (driver); action.moveToElement(element); //Move mouse and hover to 'Add Case' button
action.click().build().perform(); //Click on 'Add Case' button
driver.findElement(By.id("name")).sendKeys("Perak Murder Case -53311");//Provide Case Name
driver.findElement(By.id("fileupload")).sendKeys("C:\\Users\\sanchit.IGENEDC\\Desktop\\iCSIImages\\FisheyeImages\\IMG_1187.JPG"+"\n"+"C:\\Users\\sanchit.IGENEDC\\Desktop\\iCSIImages\\FisheyeImages\\IMG_1188.JPG"+"\n"+"C:\\Users\\sanchit.IGENEDC\\Desktop\\iCSIImages\\FisheyeImages\\IMG_1189.JPG"+"\n"+"C:\\Users\\sanchit.IGENEDC\\Desktop\\iCSIImages\\Fisheye Images\\IMG_1190.JPG"); //Upload files
driver.findElement(By.id("fileupload1")).sendKeys("C:\\Users\\sanchit.IGENEDC\\Desktop\\iCSIImages\\EvidenceImages\\_DSC0970.JPG"+"\n"+"C:\\Users\\sanchit.IGENEDC\\Desktop\\iCSI>Images\\EvidenceImages\\_DSC0971.JPG"+"\n"+"C:\\Users\\sanchit.IGENEDC\\Desktop\\iCSIImages\\Evidence Images\\_DSC0972.JPG");
Thread.sleep(6000); //wait for files to load
driver.findElement(By.id("btnSubmit")).click();//click on submit button
}
}
Check this code. This code successfully opens the google.co.in
Execute this file "Run As TestNG Test"
Let me know if this helps you.

Long press on AndroidElement in Appium

I`m trying to perform a long press action on AndroidElement in Appium. What I found is that i need to perform a TouchAction on this element, but... it only takes as argument WebDriver, no AndroidDriver that I`m using. For this reason it will not work.
TouchAction action = new TouchAction(AndroidDriver);
action.longPress(element, 10000);
I was looking for some answer for some time. LongPress (or something similar) is used in last test that I`m writting right now.
Try this.
TouchAction action = new TouchAction();
action.longPress(webElement).release().perform();
Workaround could be usage of io.appium.java_client.MultiTouchAction.
MultiTouchAction multiTouch = new MultiTouchAction(AndroidDriver);
multiTouch.add(createTap(element, duration));
multiTouch.perform();
Below code will perform single tap and long press for particular period of time in android app
Make use of it
package com.prac.com;
import java.net.MalformedURLException;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.WebElement;
import io.appium.java_client.TouchAction;
import static io.appium.java_client.touch.TapOptions.tapOptions;
import static io.appium.java_client.touch.LongPressOptions.longPressOptions;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
import static java.time.Duration.ofSeconds;
import static io.appium.java_client.touch.offset.ElementOption.element;
public class UdmeyCode extends Demo4TestBase {
public static void main(String[] args) throws MalformedURLException {
// TODO Auto-generated method stub
AndroidDriver<AndroidElement> driver=Capabilities();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.findElementByXPath("//android.widget.TextView[#text='Views']").click();
//Tap
TouchAction t =new TouchAction(driver);
WebElement expandList= driver.findElementByXPath("//android.widget.TextView[#text='Expandable Lists']");
t.tap(tapOptions().withElement(element(expandList))).perform();
driver.findElementByXPath("//android.widget.TextView[#text='1. Custom Adapter']").click();
WebElement pn= driver.findElementByXPath("//android.widget.TextView[#text='People Names']");
t.longPress(longPressOptions().withElement(element(pn)).withDuration(ofSeconds(2))).release().perform();
//Thread.sleep(2000);
System.out.println(driver.findElementById("android:id/title").isDisplayed());
}
}