When will the java.awt.Robot fail to click? - java

I use java.awt.Robot to perform some mouse behaviors on my PC. The code is simple like below:
import java.awt.Robot;
import java.awt.event.InputEvent;
public class RobotProxy {
public static void main(String[] args) {
// TODO Auto-generated method stub
RobotProxy robotProxy = new RobotProxy();
try {
robotProxy.foo();
} catch (Exception e) {
// TODO: handle exception
System.out.println("Exception there...");
}
}
public void foo() throws Exception{
Thread.sleep(3000);
Robot robot = new Robot();
robot.mouseMove(501, 296);
leftClick(robot);
robot.mouseMove(505, 296);
leftClick(robot);
robot.mouseMove(509, 296);
leftClick(robot);
}
public void leftClick(Robot robot) throws Exception{
Thread.sleep(1000);
System.out.println("before Click...");
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
System.out.println("after Click...");
}
}
You can find that I use the combination of java.awt.Robot.mousePress(InputEvent.Button1_MASK) and java.awt.Robot.mouseRelease(InputEvent.Button1_MASK) to perform the mouse left click behavior.
It works fine at most time but fails sometimes. For example, the left click behavior for a kind of software's check box will fail. I can make sure I send the click command to java.awt.Robot but just nothing happens. What's more incredible is that java.awt.Robot.mouseMove(int x, int y) still works in that situation.
PC's OS is Windows8.1
The software is not market available and it's just a Windows native app written by cpp. The button on the software can be clicked but not for check box.
If the situation makes you confused, pls just tell me when will the java.awt.Robot fail to click. Thanks for your help in advance.

The problem is there is no delay between the robot.mousePress and robot.mouseRelease commands.
Here is an example of what you could add in between the two to fix the issue
Thread.sleep(100); a delay for 100ms. about as fast as you can hear, click click

Related

How to automate basic authentication chrome alert

Have tried several approached to handle it but none worked.
https://user:password#pageaddress.com - doesn't work, chrome launches controlled bu automates test software and authentication pop-up appears anyway.
Adding --disable-blink-features=BlockCredentialedSubresources to Chrome arg and repeat 1'st point - doesn't work, reason the same as in 1'st point.
driver.switchTo().alert.authenticateUsing(new UserAndPassword(user, password)) - here seems like driver doesn't see an alert, have impelented method that checks it and returns false:
private Alert alert;
public boolean isAlertPresent() {
try {
waitForTimeout(10, TimeUnit.SECONDS);
alert = driver.switchTo().alert();
return true;
} catch (NoAlertPresentException e) {
return false;
}}
Triggering keyboard or mouse event via selenium Action() doesn't work too.
chromedriver 2.31
Google Chrome Version 61
Any other ideas ? Maybe some js script ?
I had something similar here.
you may not need the full Native Messaging API, though ...
This will all be JavaScript and will work for any browser-generated auth request (at least, it looks that way).
webRequest - chrome and firefox - has an anAuthRequired event.
You can hook into this with a listener then just pass in the credentials you need per some examples.
If you're wanting to just pass in user credentials that won't change, you'll want to use the synchronous method - it's much easier. This question may, indeed, be all you need.
If you're needing to pass in different credentials, you may well want to look into the asynchronous method, that's the one I had to use.
If you're using chrome, forget promises ... but Firefox should work with them.
Hope this helped!
Finally - I was able to do it by Robot Framework which is not a solution that I am proud of, but didn't have any other idea.
import java.awt.*;
import java.awt.datatransfer.StringSelection;
import java.awt.event.KeyEvent;
private Robot robot;
public void login(String login, String password) {
copyValueFromClipboardToInput(login);
getRobot().keyPress(KeyEvent.VK_TAB);
getRobot().keyRelease(KeyEvent.VK_TAB);
copyValueFromClipboardToInput(password);
getRobot().keyPress(KeyEvent.VK_ENTER);
getRobot().keyRelease(KeyEvent.VK_ENTER);
}
private void copyValueFromClipboardToInput(String value) {
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(value), null);
getRobot().keyPress(KeyEvent.VK_CONTROL);
getRobot().keyPress(KeyEvent.VK_V);
getRobot().keyRelease(KeyEvent.VK_V);
getRobot().keyRelease(KeyEvent.VK_CONTROL);
}
private Robot getRobot() {
if (robot == null) {
try {
robot = new Robot();
} catch (AWTException e) {
e.printStackTrace();
}
}
return robot;
}

closeing download option for IE with selenium and robot

Trying to find a way to close the option to download a file from a link in IE. Looked up a robot that could use the keyboard " Alt+Q" that would be the desired outcome, but when I go to run the program it gets stuck at the Robit() part.
When I click off the Webbrowser I'm working with the commands go through. In whatever application I'm working with at the time. Would love some help
public static void V_home(WebDriver driver) throws InterruptedException, AWTException{
driver.get(VUrl);
...
driver.findElement(By.linkText("Download School and District File")).click();
Robit();
}
public static void Robit() throws InterruptedException, AWTException{
Robot robot = new Robot();
Thread.sleep(1000);
robot.keyPress(KeyEvent.VK_ALT);
Thread.sleep(1000);
robot.keyPress(KeyEvent.VK_Q);
Thread.sleep(1000);
robot.keyRelease(KeyEvent.VK_ALT);
robot.keyRelease(KeyEvent.VK_Q);
}

Selenium WebDriver, TestNG with Java

I am unable to Handle the Print window/popup when I click on a Print button on the Web application. I need to be able to either Close this Window, Click on Print or Cancel. I am not sure whether this is a pop-up or a window.
Could some one help me?
see whether any web elements are visible if you hover the mouse over the popup.
if web elements are visible then its web application pop up
if no web elements are visible then its windows popup
However you can ignore the popup by sending escape key. the following code will work. i just tried, it worked.
public class demo extends parent {
WebDriver driver = new FirefoxDriver();
#Test
public void launch() throws InterruptedException {
driver.get("https://www.google.co.in");
Robot r = null;
try {
r = new Robot();
} catch (AWTException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
WebElement el = driver.findElement(By.xpath(".//*[#id='hplogo']"));
el.click();
Thread.sleep(10000);
el.sendKeys(Keys.CONTROL + "p"); // trying to invoke print pop up
Thread.sleep(10000);
r.keyPress(KeyEvent.VK_ESCAPE); //dismissing it by sending escape keys
}
}
hope you will get some idea here :)

Java SystemTray icon does not always work

I need your help please: I'm working on a little Java application (Java version 7) which has to be minimized into the system tray.
I'm using Class SystemTray, with SystemTray.isSupported(), then
SystemTray systemTray = SystemTray.getSystemTray();
ImageIcon icon = new javax.swing.ImageIcon(getClass().getResource("icon.png"));
[...]
systemTray.add(trayIcon);
(With popup of course)
On Windows, it's working great. On XFCE, Xubuntu, no problem, icon is working with popup. However on KDE and Gnome shell... it doesn't work.
KDE (4.14.1)
(Qt: 4.8.6 Tools Plasma: 4.11.12)
SystemTray.isSupported() = true and when the program arrived at the line:
systemTray.add(trayIcon); An exception is caught:
Error during Tray process:
java.awt.AWTException: TrayIcon couldn't be displayed.
Thereby the icon is white, and doesn't work when user clicks on it, no popup.
Gnome Shell (3.12.2)
SystemTray.isSupported() = true, the icon is located on notification area at the bottom, but mouse events don't work...
To fix these problem, I thought SWT could be a good idea. But when I implemented it (last version), I've got this warning:
WARNING **: Couldn't connect to accessibility bus: Failed to connect
to socket /tmp/[...]
And it doesn't work...
Edit: not anymore, I can fix the problem of SWT with an external class. The warning is not caused by SWT, but environment system probably (I had the same warning with other applications in the terminal).
So now, what can I do?
I think to check environment system with System.getenv("XDG_CURRENT_DESKTOP") & System.getenv("GDMSESSION") and then enable or disable system tray if it is KDE or Gnome 3... but this solution is not really good because of it is a local solution for multi-platform (in function of OS I mean), and not a global solution (one method for all OS)...
So, other idea? I don't know... is there a way to define an embedded JWindow into the system tray?
I have run up against this problem myself, and as I recall I ran up against a brick wall in sorting it out with a legitimate solution. I traced the problem to a call to the TrayIcon.addNotify() method randomly failing. I seem to recall this was because of a race condition in the internals where a call to the X11 system was taking too long to complete so the java side was giving up.
But if you have a ninja PC with a decent graphics card you would probably never meet this situation, which is probably why it hasn't been fixed yet. My dev machine is on the slow side so it was happening to me about 50% of the time.
I did hack a quick and dirty solution together, which involves trying to call addNotify repeatedly (with a pause inbetween each attempt) until it succeeds (or has failed a maximum number of times). Unfortunately the only way to do this was via reflection as the addNotify method is package-private.
Code follows:
public class HackyLinuxTrayIconInitialiser extends SwingWorker<Void, TrayIcon> {
private static final int MAX_ADD_ATTEMPTS = 4;
private static final long ADD_ICON_DELAY = 200;
private static final long ADD_FAILED_DELAY = 1000;
private TrayIcon[] icons;
public HackyLinuxTrayIconInitialiser(TrayIcon... ic) {
icons = ic;
}
#Override
protected Void doInBackground() {
try {
Method addNotify = TrayIcon.class.getDeclaredMethod("addNotify", (Class<?>[]) null);
addNotify.setAccessible(true);
for (TrayIcon icon : icons) {
for (int attempt = 1; attempt < MAX_ADD_ATTEMPTS; attempt++) {
try {
addNotify.invoke(icon, (Object[]) null);
publish(icon);
pause(ADD_ICON_DELAY);
break;
} catch (NullPointerException | IllegalAccessException | IllegalArgumentException e) {
System.err.println("Failed to add icon. Giving up.");
e.printStackTrace();
break;
} catch (InvocationTargetException e) {
System.err.println("Failed to add icon, attempt " + attempt);
pause(ADD_FAILED_DELAY);
}
}
}
} catch (NoSuchMethodException | SecurityException | NoSuchFieldException e1) {
Log.err(e1);
}
return null;
}
private void pause(long delay) {
try {
Thread.sleep(delay);
} catch (InterruptedException e1) {
Log.err(e1);
}
}
#Override
protected void process(List<TrayIcon> icons) {
for (TrayIcon icon : icons) {
try {
tray.add(icon);
} catch (AWTException e) {
Log.err(e);
}
}
}
}
To use it, just call:
if (<OS is Linux>) {
new HackyLinuxTrayIconInitialiser(ticon, micon, licon).execute();
} else {
try {
tray.add(ticon);
tray.add(micon);
tray.add(licon);
} catch (AWTException e) {
Log.err(e);
}
}
I seem to recall at the time I couldn't just keep calling SystemTray.add(icon) as it this would leave "ghost" trayicons behind on the system tray if I did.
Hope this helps.

How to get screenshot of any Linux/Windows application running outside of the JVM

Is it possible to use Java to get a screenshot of an application external to Java, say VLC/Windows Media Player, store it as an Image object and then display it in a JLabel or something of a similar nature? Does anybody know if this is possible and if so does anybody have a general idea as to how to do it?
Note: I just need to find out how to get a screenshot and store it as some form of Image object. After that I can use, manipulate it, display it, etc.
Here is the answer for Windows (not sure if alt+printScr works on linux :P)
I guess one way to achieve this
1. using Robot class to fire alt+printScreen Command (this captures active window to clipboard)
2. read the clipboard!
Here are the two pieces of code that do that. I have not actually tried, but something that I pieced together.
Code to Fire commands to get active window on clipboard
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.KeyEvent;
public class ActiveWindowScreenShot
{
/**
* Main method
*
* #param args (not used)
*/
public static void main(String[] args)
{
Robot robot;
try {
robot = new Robot();
} catch (AWTException e) {
throw new IllegalArgumentException("No robot");
}
// Press Alt + PrintScreen
// (Windows shortcut to take a screen shot of the active window)
robot.keyPress(KeyEvent.VK_ALT);
robot.keyPress(KeyEvent.VK_PRINTSCREEN);
robot.keyRelease(KeyEvent.VK_PRINTSCREEN);
robot.keyRelease(KeyEvent.VK_ALT);
System.out.println("Image copied.");
}
}
Code to read image on clipboard
// If an image is on the system clipboard, this method returns it;
// otherwise it returns null.
public static Image getClipboard() {
Transferable t = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null);
try {
if (t != null && t.isDataFlavorSupported(DataFlavor.imageFlavor)) {
Image text = (Image)t.getTransferData(DataFlavor.imageFlavor);
return text;
}
} catch (UnsupportedFlavorException e) {
} catch (IOException e) {
}
return null;
}
You can manage the control as you need to! Let me know if this works for you. but this is certainly on my todo to try it out!
You can get screen shot of whole screen using class named Robot. Unfortunately you cannot get location and size of windows that belong to other applications using pure java solution. To do this you need other tools (scripting, JNI, JNA). These tools are not cross-platform.

Categories

Resources