After zoom out unable to find the webelement in selenium webdriver - java

In my app, I need to zoom out and then find out the web element.
I zoom out using Robot robot = new Robot(). It zoomed out successfully. After that, it doesn't find the web element. I tried with an explicit wait.
Robot robot = new Robot();
Thread.sleep(5000);
System.out.println("About to zoom out");
for (int i = 0; i < 3; i++) {
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_SUBTRACT);
robot.keyRelease(KeyEvent.VK_SUBTRACT);
robot.keyRelease(KeyEvent.VK_CONTROL);
}
new WebDriverWait(driver,50).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(prop.getProperty("mpath"))))
.click();
WebElement module1 = driver.findElement(By.cssSelector(prop.getProperty("msite")));
module1.click() ;

I don't know your case exactly, but here's what I would try to do if I were you.
1. Try to zoom out the browser in a different way.
Instead of using Robot class, try to use:
element.sendKeys(Keys.chord(Keys.CONTROL, "-")) (Keys.COMMAND on MacOS).
You could also try out Actions class if this doesn't work.
2. Consider looking for that element again, after the resize.
Not sure how it works during resizing of a page, but I know that after the refresh, WebElement's id might change, which might cause your problem.
Anyway, if none of these work, try to post the error code so we can try to help you.

Related

Robot keypress not working in headless mode

Could like to press character 'v' in keyboard through robot which works fine as expected in browser mode but not working in headless mode .
Trying to loop throught list of elements and screenshot it post keypress . I am using Robot class to press the character 'v' which is not working instead it prints v in output.
I am using firefox- geckodriver-v0.24.0-win64 driver and my browser version is v69.0.1 .
List<WebElement> eleq = driver.findElements(By.cssSelector(".class"));
JavascriptExecutor js = ((JavascriptExecutor) driver);
for(WebElement e: eleq){
js.executeScript("arguments[0].scrollIntoView(true);", e);
Actions builder = new Actions(driver);
Action seriesOfActions = builder
.moveToElement(e)
.build();
seriesOfActions.perform();
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_V);
Thread.sleep(1000);
Date d =new Date();
File screenshot = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(screenshot, new File(d.toString().replace(":", "_")+".png"));
Thread.sleep(3000);
robot.keyPress(KeyEvent.VK_V);
}
Could like to know if there are any alternatives to keypress in Java selenium apart from Robot since most of my search led to Robot not working in headless.
Of-course it will not as Robot do the event without seen any other dependency.
Even if you minimize the your automation browser screen it won't work as it is independent from everything
That's why using Robot is not recommended in automation.
You need to identify other way to complete your step
you can do something like below:
String selectAll = Keys.chord(Keys.CONTROL, "a");
driver.findElement(By.id("your locator")).sendKeys(selectAll);
I have achieved this using Actions in selenium.

Element does not move within canvas

I am tyring to move element within canvas but somehow it is not happening.
Code I tried :
Actions actions = new Actions(driver);
actions.moveToElement(flowCanvas, 434, 177);
actions.clickAndHold();
actions.moveToElement(flowCanvas, 592 , 373);
actions.release();
actions.perform();
My xpath :
#FindBy(xpath = "//div[#id='diagramDiv']//canvas")
protected WebElement flowCanvas;
URL where I am trying : https://gojs.net/latest/samples/panelLayout.html
I am using selenium webdriver and Java. I am not getting any error in above code but it does not move element as well.
Trying to move following element :
Basically, the problem is with the coordinates which you use and the bowser / web driver implementation which you are using. The W3C specification states that the Action commands offset is from the center of the element. But not all of the web driver implemntations are following this. So basically the moveToElement x and y offsets for gecko driver (Firefox) are calculated from the center of the element in your case from the center of the Canvas but for Chrome Driver (Google Chrome) the cordinates are calulated from the left top corner. So if you want a cross borwser support of drag and drop you will need something like this.
WebDriver driver = getDriver();
driver.get("https://gojs.net/latest/samples/panelLayout.html");
WebElement flowCanvas = driver.findElement(By.xpath("//div[#id='myDiagramDiv']//canvas"));
if(isGoogleChrome()){
new Actions(driver)
.moveToElement(flowCanvas, 100, 125).clickAndHold()
.moveToElement(flowCanvas, 150, 175).release()
.perform();
} else if (isFireFox()){
new Actions(driver)
.moveToElement(flowCanvas, -50, -50).clickAndHold()
.moveToElement(flowCanvas, 100, 100).release()
.perform();
}
As you can see for firefox you must use negative values to move mouse from center to the top left element in the canvas and for chrome you need to move mouse a bit down and right.
Try Action and Actions combinations
Actions builder = new Actions(driver);
Action moveAction = builder.moveToElement(flowCanvas,434,177)
.click()
.moveByOffset(592, 373)
.doubleClick()
.build();
moveAction.perform();
I tried moving that object with Sikuli and it worked like a charm. Please check the snippet below.
Pattern p = new Pattern("Win/AboutScreen/Move.PNG");
Region r1 = screen.exists(p);
r1.hover();
r1.mouseDown(Button.LEFT);
r1.mouseMove(50, 50);
r1.mouseUp(Button.LEFT);
You need to save a screenshot at some location and mention the path. hover(); method will find the screen and mouse hover on it. mouseDown(Button.LEFT) will keep the Left click pressed and the last mouserMove(50,50) will move the element to coordinate.
It's very easy to install Sikuli if you are using Maven project then just add one simple dependency and you are done.
Hope this help :)

Key press in (Ctrl + mouse click) in Selenium WebDriver using java

I need to press control+mouse click keys using Selenium WebDriver(java). I need to select multiple element in my script.
Is there any way to do it?
I checked the Selenium libraries and found that selenium allows key press of special and functional keys only.
There is already written library Actions in WebDriver which you can use.
Short Description of what is happening:
First you are pressing the Control button and then you are clicking (in this case) 3 times on your defined WebElemen objects) then your are unpressing the Control and finish your Actions.
In this case you can achive the selection of 3 items (or opening a 3 new tabs) depending on what your WebElements are.
Actions actions = new Actions(driver);
actions.keyDown(Keys.LEFT_CONTROL)
.click(first_WebElement)
.click(second_WebElement)
.click(third_WebElement)
.keyUp(Keys.LEFT_CONTROL)
.build()
.perform();
Do it with the help of 'Actions' as below:
Actions action=new Actions(driver);
action.keyDown(Keys.CONTROL).build().perform();
driver.findElement(By.xpath(".//*[#id='selectable']/li[1]")).click();
driver.findElement(By.xpath(".//*[#id='selectable']/li[3]")).click();
action.keyUp(Keys.CONTROL).build().perform();
In the case of using Mac, te code would be next:
action.keyDown(Keys.COMMAND)
.click(WebElement)
.keyUp(Keys.COMMAND)
.build()
.perform();
You achieve same using jquery code
JavascriptExecutor js = (JavascriptExecutor) driver;
String script = "e = jQuery.Event('click');e.ctrlKey = true; $('secondRow_Css_locator').trigger(e);";
js.executeScript(script);
OR you can also use robot class but it can lock your screen for a moment
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyRelease(KeyEvent.VK_CONTROL);
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
As of 2018 the is the first results pops up. Earlier it was working fine after FF 61 (direct jump form 47 to 61) It starts breaking. unfortunately none of the answer worked for me. Solved it by action.keyDown(Keys.CONTROL).click(myWebElements.get(i)).keyUp(Keys.CONTROL).perform(); just iterating every element one by one
it worked with me using this:
Actions action=new Actions(driver);
action.keyDown(Keys.CONTROL).build().perform();
driver.findElement(By.xpath(".//*[#id='selectable']/li[1]")).click();
driver.findElement(By.xpath(".//*[#id='selectable']/li[3]")).click();
action.keyUp(Keys.CONTROL).build().perform();

Selenium Webdriver Java - looking for alternatives for Actions and Robot when performing drag-and-drop

I first tried Actions class and the drag-and-drop does work on different elements, however it was unable to locate the a specific draggable element on it's exact screen/webpage position.
Here's the code I've used:
Point loc = driver.findElement(By.id("thiselement")).getLocation();
System.out.println(loc);
WebElement drag = driver.findElement(By.id("thiselement"));
Actions test = new Actions(driver);
test.dragAndDropBy(drag, 0, 60).build().perform();
I checked the element with it's pixel location and it prints (837, -52), which was somewhere on top of the webpage and was pixels away from the actual element.
Then I tried using the Robot class and works perfectly fine on my script, but can only provide constant successful runs on a single test machine, running it with a different machine with different screen resolution and screen size will render the script to fail due to the dependency of Robot on the pixel location of the element.
The sample code of the Robot script I'm using:
Robot dragAndDrop = new Robot();
dragAndDrop.mouseMove(945, 166); //actual pixel location of the draggable element
dragAndDrop.mousePress(InputEvent.BUTTON1_MASK);
sleep(3000);
dragAndDrop.mouseMove(945, 226);
dragAndDrop.mouseRelease(InputEvent.BUTTON1_MASK);
sleep(3000);
Is there any alternative for Actions and Robot to automate drag-and-drop? Or maybe a help on working the script to work on Actions as I really can't use Robot.
Thanks in advance.
Another alternative to drag and drop,
Actions test= new Actions(driver);
builder.clickAndHold("thisElement").moveToElement("targetElement")
.release("targetElement")
.build().perform();
This SO post will help you better here

How to switch from main window to popup window?

I'm not talking about the popups like alert, confirm or prompt dialogs. In the application if I click on a button popup gets opened. I am not able to switch the WebDriver to the popup window.
I've tried to use getWindowHandles() but it only returns the main window handle.
I also tried switchTo.window("windowname") but it didn't work.
Usually Modular Windows are part of the same DOM, unlike javascripts alerts. Only thing that sets them apart from rest of the page is that they are in different frame.
Try to see if this Modular Window lies inside a frame or iframe tag. If any of the parent is frame or iframe then you will have to change the context to that frame before you can performa any action on the Modal Window.
So find the frame do a driver.switchTo().frame() and then perform the action on the element you want to. Once the action is done, which would most probably bring you back to the main page. Use driver.switchTo().defaultContent() to bring focus back to main page.
This SO question will be helpful.
If this does not work it would be helpful to have a look at the page or its HTML.
//handle of the master window before clicking the link
String master = driver.getWindowHandle();
driver.findElement(By.linkText("Click me")).click();
//logic for waiting for the popup, checking the size to become greater than 1 or breaking after sometime to avoid the infinite loop.
int timeCount = 1;
do
{
driver.getWindowHandles();
Thread.sleep(200);
timeCount++;
if ( timeCount > 50 )
{
break;
}
}
while ( driver.getWindowHandles().size == 1 );
//Assigning the handles to a set
Set<String> handles = driver.getWindowHandles();
//Switching to the popup window.
for ( String handle : handles )
{
if(!handle.equals(master))
{
driver.switchTo().window(handle);
}
}
Are you using pageobjects?
If you are using this, you will need to find the elements after the popup appears, because initElements will not initialize them if they are not visible when you first open the page.
Assuming your talking about a javascript alert.
final Alert a = driver.switchTo().alert();
a.accept();
or
Execute JavaScript directly to handle the altert
and
Maybe wait for the alert to show up
As per webdriver this issue is fixed in 2.16 but still it does not work
Support for window.ShowmodalDialog
You can use Java Robot class for handling such cases.
Example :
Wait(5000); // Wait for model pop,
int keyInput[] =
{
KeyEvent.VK_S, KeyEvent.VK_E, KeyEvent.VK_L, KeyEvent.VK_E,
KeyEvent.VK_N, KeyEvent.VK_I, KeyEvent.VK_U, KeyEvent.VK_M,
};
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_TAB);
robot.keyPress(KeyEvent.VK_TAB);
for (int i = 0; i < keyInput.length; i++)
{
robot.keyPress(keyInput[i]);
robot.delay(100);
}
robot.delay(1000);
robot.keyPress(KeyEvent.VK_TAB);
robot.delay(1000);
robot.keyPress(KeyEvent.VK_TAB);
robot.delay(1000);
robot.keyPress(KeyEvent.VK_TAB);
robot.delay(1000);
robot.keyPress(KeyEvent.VK_ENTER); // Save Btn
The delay between events is necessary otherwise you will miss the events.

Categories

Resources