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 :)
Related
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.
Problem Statement: How to perform mousemove based on webelement instead of xy coordinates of getlocation in Selenium using robot class?
Below snippet is often used to mousemove which moves mouse based on x-y co-ordinates
Robot robot = new Robot();
robot.mouseMove(to_x, to_y);
But, Is there a way to move mouse of robot class based on webelement without using getlocation?
Example:
webelement drag = driver.findelement(by_xpath('xpaht'))
Robot robot = new Robot();
robot.mouseMove(drag); //Is there any way to do it like this in selenium java
I do not want to use movetoelement of actions class.
Selenium 3.141 / Java
Chromedriver 76 and FF browsers
You can use Locatable class -
Locatable hoverItem = (Locatable) driver.findElement(By.xpath("element xpath"));enter code here
int y = hoverItem.getCoordinates().getLocationOnScreen().getY();
((JavascriptExecutor)driver).executeScript("window.scrollBy(0,"+y+");");
Hope this help.
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();
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
I'm trying to drag an object from one location to another location in an iframe.
But I'm getting movetargetoutofboundsexception. How do I find coordinates to which I can move the object?
Exception in thread "main" org.openqa.selenium.interactions.MoveTargetOutOfBoundsException: Given coordinates (552, 440) are outside the document. Error: MoveTargetOutOfBoundsError: The target location (552, 440) is not on the webpage.
FirefoxProfile prof = new FirefoxProfile();
prof.setEnableNativeEvents(true);
WebDriver driver = new FirefoxDriver(prof);
driver.get("http://jqueryui.com/draggable/");
driver.manage().window().maximize();
// WebElement frame1 = driver.findElement(By.xpath("//*[#id='content']/iframe"));
// System.out.println(frame1.getLocation());
driver.switchTo().frame(0);
Actions act = new Actions(driver);
WebElement src = driver.findElement(By.xpath("//div[#id='draggable']"));
System.out.println(src.getText());
act.dragAndDropBy(src, 474, 360).build().perform();
Your code is more or less okay.
The only thing that is wrong is the amount of move possible to make. If you lowered your offsets to, say, 100 px, it would have worked. I found out the maximums (on my computer's Firefox) are 572 and 338 px.
Now, these numbers are not random. If you print out the size of the <iframe> element, you'll get (584, 350). If you print out the initial location of the draggable element inside the <iframe>, you'll get (8, 8). When you subtract those, you'll get 576 and 342 px which is very close to our empirical result. Actually, it differs exactly by 4 px in both directions. To be honest, I don't know where those 4 px come from. It might be some kind of border.
Only one thing is certain. For obvious reasons, WebDriver makes sure you won't drag an element out of the frame you are currently in.
WebDriver driver = new FirefoxDriver();
driver.manage().window().maximize();
driver.get("http://jqueryui.com/draggable/");
WebElement iFrame = driver.findElement(By.tagName("iframe"));
System.out.println(iFrame.getSize());
driver.switchTo().frame(iFrame);
WebElement draggable = driver.findElement(By.id("draggable"));
System.out.println(draggable.getLocation());
new Actions(driver).dragAndDropBy(draggable, 572, 338).perform();