Element is not clickable at point ... error when using headless browsing - selenium-webdriver

I have this error "org.openqa.selenium.ElementClickInterceptedException: element click intercepted: Element is not clickable at point (209, 760)", when I run the piece of code below in headless mode. When it is run with browser displayed I have no error and test passes fine. As you can see below, I trie with waiting, js executor, actions move to element but still no good result. I am using xpath to locate / define the element, and not coordinates. Why is this happening please and how can I solve it? Thanks in advance.
#Test(priority = 1)
public void verifyAddUserWithMarkedMandatoryFields() {
// accessing add user webpage / functionality
userListObject.getAddUserButton().click();
// inserting data to complete form
addOrEditUserPageObject.insertCredentials(userModel.getUsername(), userModel.getEmail(), "", userModel.getPassword());
// clicking Submit when becoming enabled
WebDriverWait myWaitVariable = new WebDriverWait(driver, 5);
myWaitVariable.until(ExpectedConditions.elementToBeClickable(addOrEditUserPageObject.getSubmitButtonAddOrEdit()));
// Actions actions = new Actions(driver);
// actions.moveToElement(addOrEditUserPageObject.getSubmitButtonAddOrEdit()).click().perform();
JavascriptExecutor jse = (JavascriptExecutor)driver;
// jse.executeScript("scroll(209, 760)"); // if the element is on top.
jse.executeScript("scroll(760, 209)"); // if the element is on bottom.
addOrEditUserPageObject.getSubmitButtonAddOrEdit().click();
}

You should add screen size for the headless mode, something like this:
Map<String,String> prefs = new HashMap<>();
prefs.put("download.default_directory", downloadsPath); // Bypass default download directory in Chrome
prefs.put("safebrowsing.enabled", "false"); // Bypass warning message, keep file anyway (for .exe, .jar, etc.)
ChromeOptions opts = new ChromeOptions();
opts.setExperimentalOption("prefs", prefs);
opts.addArguments("--headless", "--disable-gpu", "--window-size=1920,1080","--ignore-certificate-errors","--no-sandbox", "--disable-dev-shm-usage");
driver = new ChromeDriver(opts);
I put much more things here, the only relevant point here is "--window-size=1920,1080", this should resolve your problem.
The rest is to show how things are managed, including other relevant settings for headless mode.

Related

Draw on a Canvas Using Selenium

I'm using selenium with java (latest for both). Trying to draw on a small canvas area inside a modal in our webapp. The library we used for our canvas was 'signature pad js'. I have confirmed it is not inside an iframe or anything tricky that could be the problem (it's just a regular div.modal-body with a div.signature-input canvas element).
But it is not doing anything. Have looked at many posts here on stackoverflow and most of them seem pretty identical with few variations to try (I've been trying them all).
Here's the latest code I tried:
// Draw a signature of some sort
WebElement element = driver.findElement(Using.locator(SIGNATURE_AREA)); // canvas element
Actions builder = new Actions(driver);
builder.clickAndHold(element).moveByOffset(10, 50).
moveByOffset(50,10).
moveByOffset(-10,-50).
moveByOffset(-50,-10).release().perform();
I've tried all sorts of offsets, and such to no avail.
If anyone has experience with this, would really love a hand.
I think your issue is in the code , I've done this with ruby and it worked fine.. Code in Ruby below (worked in FireFox)
driver.find_element(:xpath, "html/body/div[1]/div[5]/div[2]/canvas").click
element = driver.find_element(:xpath, "html/body/div[1]/div[5]/div[2]/canvas");
driver.action.move_to(element).perform
driver.action.click_and_hold(element).perform
driver.action.move_by(150, 50).click.perform
driver.action.move_to(element).perform
driver.action.click_and_hold(element).perform
driver.action.move_by(100, 50).click.perform
driver.action.move_to(element).perform
driver.action.click_and_hold(element).perform
driver.action.move_by(300, 10).click.perform
sleep (5)
So I have tried same thing using Java for you , and its working fine , Its drawing two lines as expected. The trick is that moveby should not be followed with a click otherwise it will loose focus. Below code is working fine in java and chrome . I used https://sketchtoy.com/ to draw on canvas
public class BrowserTesting {
WebDriver driver;
#Test
public void test1() throws InterruptedException {
//WebDriverManager.chromedriver().setup();
System.setProperty("webdriver.chrome.driver","C:\\Users\\pathtyourchrome\\chromedriver.exe");
ChromeOptions options = new ChromeOptions();
options.setExperimentalOption("useAutomationExtension", false);
//disable automation info bar
options.addArguments("disable-infobars");
driver = new ChromeDriver(options);
driver.get("https://sketchtoy.com/");
WebElement element = driver.findElement(By.xpath("//div[#class='sketch-canvas-container']/canvas"));//canvas element
Actions builder = new Actions(driver);
builder.moveToElement(element).perform();
builder.clickAndHold(element).perform();
builder.moveByOffset(150, 50).perform();
builder.moveToElement(element).perform();
builder.clickAndHold(element).perform();
builder.moveByOffset(100, 50).perform();
builder.moveToElement(element).perform();
Thread.sleep(5000);
//driver.quit();
}
}
See this screen shot for the drawing:
Let me know if this worked!

Element ... is not clickable at point (35, 37) [duplicate]

I am trying to make some tests using selenium based Katalon Studio. In one of my tests I have to write inside a textarea. The problem is that I get the following error:
...Element MyElement is not clickable at point (x, y)... Other element would receive the click...
In fact my element is place inside some other diva that might hide it but how can I make the click event hit my textarea?
Element ... is not clickable at point (x, y). Other element would receive the click" can be caused for different factors. You can address them by either of the following procedures:
Element not getting clicked due to JavaScript or AJAX calls present
Try to use Actions Class:
WebElement element = driver.findElement(By.id("id1"));
Actions actions = new Actions(driver);
actions.moveToElement(element).click().build().perform();
Element not getting clicked as it is not within Viewport
Try to use JavascriptExecutor to bring the element within Viewport:
JavascriptExecutor jse1 = (JavascriptExecutor)driver;
jse1.executeScript("scroll(250, 0)"); // if the element is on top.
jse1.executeScript("scroll(0, 250)"); // if the element is at bottom.
Or
WebElement myelement = driver.findElement(By.id("id1"));
JavascriptExecutor jse2 = (JavascriptExecutor)driver;
jse2.executeScript("arguments[0].scrollIntoView()", myelement);
The page is getting refreshed before the element gets clickable.
In this case induce some wait.
Element is present in the DOM but not clickable.
In this case add some ExplicitWait for the element to be clickable.
WebDriverWait wait2 = new WebDriverWait(driver, 10);
wait2.until(ExpectedConditions.elementToBeClickable(By.id("id1")));
Element is present but having temporary Overlay.
In this case induce ExplicitWait with ExpectedConditions set to invisibilityOfElementLocated for the Overlay to be invisible.
WebDriverWait wait3 = new WebDriverWait(driver, 10);
wait3.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("ele_to_inv")));
Element is present but having permanent Overlay.
Use JavascriptExecutor to send the click directly on the element.
WebElement ele = driver.findElement(By.xpath("element_xpath"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", ele);
I assume, you've checked already that there is no any other component overlapping here (transparent advertisement-iframes or some other component of the DOM => seen quite often such things in input/textfield elements) and, when manually (slowly) stepping your code, it's working smoothly, then ajax calls might cause this behaviour.
To avoid thread.sleep, try sticking with EventFiringWebDriver and register a handle to it.
(Depending on your application's techstack you may work it for Angular, JQuery or wicket in the handler, thus requiring different implementations)
(Btw: This approach also got me rid of "StaleElementException" stuff lots of times)
see:
org.openqa.selenium.support.events.EventFiringWebDriver
org.openqa.selenium.support.events.WebDriverEventListener
driveme = new ChromeDriver();
driver = new EventFiringWebDriver(driveme);
ActivityCapture handle=new ActivityCapture();
driver.register(handle);
=> ActivityCapture implements WebDriverEventListener
e.g. javascriptExecutor to deal with Ajax calls in a wicket/dojo techstack
#Override
public void beforeClickOn(WebElement arg0, WebDriver event1) {
try {
System.out.println("After click "+arg0.toString());
//System.out.println("Start afterClickOn - timestamp: System.currentTimeMillis(): " + System.currentTimeMillis());
JavascriptExecutor executor = (JavascriptExecutor) event1;
StringBuffer javaScript = new StringBuffer();
javaScript.append("for (var c in Wicket.channelManager.channels) {");
javaScript.append(" if (Wicket.channelManager.channels[c].busy) {");
javaScript.append(" return true;");
javaScript.append(" }");
;
;
;
javaScript.append("}");
javaScript.append("return false;");
//Boolean result = (Boolean) executor.executeScript(javaScript.toString());
WebDriverWait wait = new WebDriverWait(event1, 20);
wait.until(new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
return !(Boolean) executor.executeScript(javaScript.toString());
}
});
//System.out.println("End afterClickOn - timestamp: System.currentTimeMillis(): " + System.currentTimeMillis());
} catch (Exception ex) {
//ex.printStackTrace();
}
}
As #DebanjanB said, your button (or another element) could be temporarily covered by another element, but you can wait and click it even if you don't know which element is covering the button.
To do this, you can define your own ExpectedCondition with the click action:
public class SuccessfulClick implements ExpectedCondition<Boolean> {
private WebElement element;
public SuccessfulClick(WebElement element) { //WebElement element
this.element = element;
}
#Override
public Boolean apply(WebDriver driver) {
try {
element.click();
return true;
} catch (ElementClickInterceptedException | StaleElementReferenceException | NoSuchElementException e) {
return false;
}
}
}
and then use this:
WebDriverWait wait10 = new WebDriverWait(driver, 10);
wait10.until(elementToBeClickable(btn));
wait10.until(new SuccessfulClick(btn));
Try Thread.Sleep()
Implicit - Thread.Sleep()
So this isn’t actually a feature of Selenium WebDriver, it’s a common feature in most programming languages though.
But none of that matter.
Thread.Sleep() does exactly what you think it does, it’s sleeps the thread. So when your program runs, in the majority of your cases that program will be some automated checks, they are running on a thread.
So when we call Thread.Sleep we are instructing our program to do absolutely nothing for a period of time, just sleep.
It doesn’t matter what our application under test is up to, we don’t care, our checks are having a nap time!
Depressingly though, it’s fairly common to see a few instances of Thread.Sleep() in Selenium WebDriver GUI check frameworks.
What tends to happen is a script will be failing or failing sporadically, and someone runs it locally and realises there is a race, that sometimes WedDriver is losing. It could be that an application sometimes takes longer to load, perhaps when it has more data, so to fix it they tell WebDriver to take a nap, to ensure that the application is loaded before the check continues.
Thread.sleep(5000);
The value provided is in milliseconds, so this code would sleep the check for 5 seconds.
I was having this problem, because I had clicked into a menu option that expanded, changing the size of the scrollable area, and the position of the other items. So I just had my program click back on the next level up of the menu, then forward again, to the level of the menu I was trying to access. It put the menu back to the original positioning so this "click intercepted" error would no longer happen.
The error didn't happen every time I clicked an expandable menu, only when the expandable menu option was already all the way at the bottom of its scrollable area.

How to Test Print-preview of Chrome browser using Chrome webdriver?

I have tried using switching between windows using
String winHandleBefore = driver.getWindowHandle();
<code to print>
for (String winHandle : driver.getWindowHandles())
driver.switchTo().window(winHandle);
driver.findElement(By.className("cancel")).click();
driver.switchTo().window(winHandleBefore);
This hangs my test case execution after it opens the print preview page.
Also tried with javascript executor method, but no use.
JavascriptExecutor jse = (JavascriptExecutor) driver;
jse.executeScript("window.close()", "");
Please suggest if it's possible to do so.
I have found the answer to my question. I used below code snippet.
//Create a Region for Desktop Screen
ScreenRegion s = new DesktopScreenRegion();
//Find target with below Image in Desktop Screen
Target target = new ImageTarget(new File("Image.png"));
ScreenRegion r = s.find(target);
// Create a mouse object
Mouse mouse = new DesktopMouse();
// Use the mouse object to click on the center of the target region
mouse.click(r.getCenter());
With the help of this snippet you would able to find the print or cancel and do the mouse click event and proceed with selenium tests. This was possible using sikuli API

Selenium webdriver: Unable to send keys In a new popup window

Using selenium web-driver I am trying to put region name In the text box In new popup screen and click on save button. I using the below script for that
String mainWindowHandle1=driver.getWindowHandle();
driver.switchTo().window(mainWindowHandle1 );
driver.findElement(By.id("MainContent_imgAddRegion")).click();
Thread.sleep(5000);
java.util.Set<String> s1 = driver.getWindowHandles();
Iterator<String> ite1 = s1.iterator();
while(ite1.hasNext())
{
String popupHandle=ite1.next().toString();
if(!popupHandle.contains(mainWindowHandle1))
{
driver.switchTo().window(popupHandle).findElement(By.id("txtRegionName")).sendKeys("South Region");
Thread.sleep(3000);
driver.findElement(By.id("txtRegionName")).sendKeys("South Region");
Thread.sleep(1000);
driver.findElement(By.id("btnSave")).click();
By doing this I am able to open the new popup screen to enter the region but, I am unable to send keys [region name] and save the text.Even I am not getting any failed report when I run the test.
This may be due to iFrames presence.
Look in the HTML code and check if the text field that you are trying to send keys to and the save button are included in some sort of iFrame.
If so, you will need to do something like:
driver.switchTo().defaultContent();
driver.switchTo().frame("framename");
driver.findElement(By.id("txtRegionName")).sendKeys("South Region");
driver.findElement(By.id("btnSave")).click();
Hope it helps!

Could not switch between browsers in selenium webdriver

Iam trying to switch between browser ie on click of a button it launches a new browser it
is finding the handle ..the problem is it is not able to find the object inside the new browser searched with id,xpath,name etc can some one give me any suggestion on the same.
also it is able to match the url as well.
please provide me the solution on the same.
below is the code.
//Previous screen
Set windows = driver1.getWindowHandles();
driver1.findElement(By.id("findButton")).click();
//switching handle for the new screen
driver1.switchTo().window("Customer Search");
driver1.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
int i = 1;
while(i<= 10){
for (String handle : driver1.getWindowHandles()) {
String myTitle = driver1.switchTo().window(handle).getTitle();
System.out.println("myTitle value : " +myTitle);
//customer search is the new window title
if(myTitle.equalsIgnoreCase("Customer Search")){
driver1.manage().window().maximize();
//if i pass the right url of the screen that is also matching here i have given dummy("sshsj")
if(driver1.getCurrentUrl().equalsIgnoreCase("sshsj"));
{
System.out.println("Url is matching");
//But not able the recognise the object on the new window.
driver1.findElement(By.xpath("html/body/left/form/table/tbody/tr[2]/td[1]/input")).sendKeys("kamal");
}
You can use JS to open a new window, it's faster.
IJavaScriptExecutor jscript = driver as IJavaScriptExecutor;
jscript.ExecuteScript("window.open()");
Then to switch windows, use the window handles:
List<string> handles = driver.WindowHandles.ToList<string>();
driver.SwitchTo().Window(handles.Last());
driver.get(url);
driver.findElement(By.xpath("html/body/left/form/table/tbody/tr[2]/td[1]/input")).sendKeys("kamal");
It is possible that the element may be present inside an iframe. In that case, you need to switch to that iframe before you can access any element inside the iframe.

Resources