How to simulate mouse movement in selenium using java - java

I have a requirement that when a certain automation script is run, the browser should show the cursor moving from one field to another as the script moves ahead. I am not sure about what exactly I need to do to get it done. I used the Action class to implement it but it's not working.
Please find the code I have implemented below:
public void MouseHover(WebElement Mouse,WebDriver driver) throws InterruptedException
{
Actions act = new Actions(driver);
act.moveToElement(Mouse).build().perform();
System.out.println("Curser movement Performed Successfully");
}

The java.awt.Robot class can be used to programmatically move the user's mouse (among other things). See: Link.
For example:
Robot r = new Robot();//construct a Robot object for default screen
r.mouseMove(1360, 7);//move mouse to java coords 1360, 7
r.mousePress(InputEvent.BUTTON1_MASK);//press the left mouse button
r.mouseRelease(InputEvent.BUTTON1_MASK);//release the mouse button

Related

Selenium actions multithreading

I would like to open multiple Selenium WebDrivers and process them in different threads. The question is how do Selenium Action class share keyboard/ mouse resources?
public class InterruptInput implements Runnable {
public static void main(String[] args) {
// two instances of action will run simultaneously
new Thread(new InterruptInput()).start();
new Thread(new InterruptInput()).start();
}
#Override
public void run() {
// not sure if the same can be replicated using ChromeDriver
WebDriver driver = new FirefoxDriver();
Actions act1 = new Actions(driver);
act1.moveToElement(searchBar)
.click()
.sendKeys("G")
.pause(1000)
.sendKeys("O")
.pause(1000)
.sendKeys("O")
.pause(1000)
.sendKeys("G")
.pause(1000)
.sendKeys("L")
.pause(1000)
.sendKeys("E")
.pause(1000)
.perform();
}
}
The observed result is:
Two browsers will open. Each will type GOOGLE to the search bar in 7 seconds. There are no interference.
If I manually click somewhere on the same page, and move the search bar out of focus, the input will be interrupted.
If I manually open a new tab in one of the browsers, or switch to other apps in the operating system, GOOGLE will finish typing in the background.
How is this achieved? Does this mean I can open as many instances of WebDriver, and not worry about clogging up I/O. How is this different from Java's Robot class, which actively takes over keyboard and mouse control? For the reference, I am using Windows 10. Not sure if this is platform dependent.
The fundamental purpose being, I am writing a simple app that allows the user (me) to scrape some websites, while obviously allowing the user to do other work on the computer.
When you use Actions class you do not use real input devices. The only thing you share is what you have in your code - a WebDriver object that is new for each of your threads so that there is no interference.
So by performing a "mouse move" you send a command to webdriver that sends the event to a browser that it would receive if you would use the real mouse or keyboard. The real mouse pointer would not move.

How to perform mousemove based on webelement instead of xy coordinates of getlocation in Selenium using robot class?

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.

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

Discover and click hyperlink

I'm trying to test by SWTBot hyperlinks inside my Eclipse's text editor. The problem is that the hyperlinks are shown on demand (an Eclipse feature), meaning - the token changes is revealed as hyperLink only when mouse moves over it + a keyboard key (Ctrl or Alt) is pressed.
How can I simulate in SWTBot the mouse-move together with a key pressed?
When mouse moves over a link, then a MouseEvent is generated. Some MouseMotionListener (or maybe MouseListener) consumes this event and then shows hiperlink for you.
You can simulate this event:
Component source = null; // TODO set up a valid component
MouseEvent event = new MouseEvent(source, MouseEvent.MOUSE_ENTERED, System.currentTimeMillis(), InputEvent.ALT_DOWN_MASK, source.getX(), source.getY(), 0, false);
MouseMotionListener[] mouseMotionListeners = source.getMouseMotionListeners();
if (mouseMotionListeners!= null && mouseMotionListeners.length > 0) {
MouseMotionListener mouseMotionListener = mouseMotionListeners[0];
mouseMotionListener.mouseMoved(event);
}
The InputEvent.ALT_DOWN_MASK in the constructor means that Alt is pressed.
Note that you should define what Component responsible for consuming events in your case.
You can find more information in the tutorial How to Write a Mouse Listener and MouseEvent API

How to simulate a real mouse click using java?

I'm attempting to perform a mouse click in Java, to click something in an external program. To do this, I'm using java.awt.robot, and the following code:
Robot bot = new Robot();
int mask = InputEvent.MOUSE_BUTTON1_DOWN;
bot.mouseMove(x, y);
bot.mousePress(mask);
bot.mouseRelease(mask);
Here's the problem. The external program is able to detect that this click is computer-generated and not human-generated, and hence, its rejecting this click.
I have already tried moving the mouse there naturally and that didn't have any effect. So my guess is, that it must be listening to the keyboard state or such, and telling from that, that the click is computer generated.
What do I have to do to set all keyboard / mouse states to act in the same way as a normal mouse click would?
Well I had the same exact requirement, and Robot class is perfectly fine for me. It works on windows 7 and XP (tried java 6 & 7).
public static void click(int x, int y) throws AWTException{
Robot bot = new Robot();
bot.mouseMove(x, y);
bot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
bot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
}
May be you could share the name of the program that is rejecting your click?
FYI, in newer versions of Windows, there's a new setting where if a program is running in Adminstrator mode, then another program not in administrator mode, cannot send any clicks or other input events to it. Check your source program to which you are trying to send the click (right click -> properties), and see if the 'run as administrator' checkbox is selected.
it works in Linux. perhaps there are system settings which can be changed in Windows to allow it.
jcomeau#aspire:/tmp$ cat test.java; javac test.java; java test
import java.awt.event.*;
import java.awt.Robot;
public class test {
public static void main(String args[]) {
Robot bot = null;
try {
bot = new Robot();
} catch (Exception failed) {
System.err.println("Failed instantiating Robot: " + failed);
}
int mask = InputEvent.BUTTON1_DOWN_MASK;
bot.mouseMove(100, 100);
bot.mousePress(mask);
bot.mouseRelease(mask);
}
}
I'm assuming InputEvent.MOUSE_BUTTON1_DOWN in your version of Java is the same thing as InputEvent.BUTTON1_DOWN_MASK in mine; I'm using 1.6.
otherwise, that could be your problem.
I can tell it worked because my Chrome browser was open to http://docs.oracle.com/javase/7/docs/api/java/awt/Robot.html when I ran the program, and it changed to Debian.org because that was the link in the bookmarks bar at (100, 100).
[added later after cogitating on it today]
it might be necessary to trick the listening program by simulating a smoother mouse movement. see the answer here: How to move a mouse smoothly throughout the screen by using java?
With all respect the most likely thing is that you are mistaken about why the click is being 'rejected'. Why do you think some program is trying to determine if it's human or not? The Robot class (have used it a lot) should send messages that the operating system has no way to distinguish from a user doing the click.
Some applications may detect click source at low OS level. If you really need that kind of hack, you may just run target app in virtual machine's window, and run cliker in host OS, it can help.
You could create a simple AutoIt Script that does the job for you, compile it as an executable and perform a system call there.
in au3 Script:
; how to use: MouseClick ( "button" [, x, y [, clicks = 1 [, speed = 10]]] )
MouseClick ( "left" , $CmdLine[1], $CmdLine[1] )
Now find aut2exe in your au3 Folder or find 'Compile Script to .exe' in your Start Menu and create an executable.
in your Java class call:
Runtime.getRuntime().exec(
new String[]{
"yourscript.exe",
String.valueOf(mypoint.x),
String.valueOf(mypoint.y)}
);
AutoIt will behave as if it was a human and won't be detected as a machine.
Find AutoIt here: https://www.autoitscript.com/

Categories

Resources