Switching Apps on Mac with AWT Robot only sometimes works - java

I'm trying to use Robot in order to switch apps, and then enter some text. To do this (on my mac), I'm pressing Meta, Tab, and then releasing Tab, Meta in this order:
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_META);
robot.keyPress(KeyEvent.VK_TAB);
robot.keyRelease(KeyEvent.VK_TAB);
robot.keyRelease(KeyEvent.VK_META);
This works, but only occasionally (about every 5 or six presses). I've tried calling Thread.wait() inbetween press and release, but this has no effect. Neither does trying to mask Tab with META_DOWN_MASK. I also tried using the JavaFX Robot (com.sun.glass.ui.Robot), but the JavaFX version doesn't work at all.

Ah.. Seems that I need to specify a delay between the events. Updated:
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_META);
robot.delay(300);
robot.keyPress(KeyEvent.VK_TAB);
robot.keyRelease(KeyEvent.VK_TAB);
robot.keyRelease(KeyEvent.VK_META);

Related

Java Robot - Issue typing 'a' on mac

So I have the following code:
public static void main(String[] args) throws AWTException, InterruptedException {
Robot robot = new Robot();
robot.setAutoWaitForIdle(true);
robot.setAutoDelay(40);
// This works fine
robot.mouseMove(40, 130);
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.delay(200);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
robot.delay(200);
// The 'a' is never inputted
robot.keyPress(KeyEvent.VK_A);
robot.delay(200);
robot.keyRelease(KeyEvent.VK_A);
}
This code successfully moves the mouse to the location 40, 130 and clicks. I make sure to have a text editor open in this location so that it becomes focused.
The next bit of code is the issue. The keyPress/Release snippet works perfectly fine for other codes. (Like 100, corresponding to the number 4.) But for some reason the letter 'a' will not be printed into the text editor.
I have tried having the program continually loop and print a for ~5 seconds. After the programatic click it will not print 'a' in the text editor. If I click on the editor again myself during this time, the string of 'a's will then start to appear.
What is causing this behavior and how can I fix it?
As i assumed in my comments i think you have a problem focusing the editor correctly.
You can try to use the Windows solution by doing ALT+TAB and then release it to select the editor.
Robot robot = new Robot();
robot.setAutoWaitForIdle(true);
robot.setAutoDelay(40);
robot.keyPress(KeyEvent.VK_ALT);//on mac use VK_META
robot.keyPress(KeyEvent.VK_TAB);
robot.keyRelease(KeyEvent.VK_ALT);//on mac use VK_META
robot.keyRelease(KeyEvent.VK_TAB);
robot.keyPress(KeyEvent.VK_A);
robot.delay(200);
robot.keyRelease(KeyEvent.VK_A);

How to press 'Enter' without targeting a WebElement

I make tests with WebDriver and at a moment a popup appears, with no fixed attribute (auto-generated).
So, the simplest way (I think) is to press the key 'Enter' on the keyboard.
But I can't find the way to say 'Just click on the browser, not on an element of the browser'.
It's possible with WebDriver? How can I achieve it?
An alternative is to use the java.awt.Robot to simulate a keyboard's interaction and not a WebElement's treatment.
[WebDriver code]
try {
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_ENTER);
robot.keyRelease(KeyEvent.VK_ENTER);
robot.delay(200);
}
[WebDriver code]
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_ENTER); //press enter key
robot.keyRelease(KeyEvent.VK_ENTER); //release enter key
You should specify the release command also while the enter key has been pressed.
Using Actions utility we can achieve the same:
Actions builder = new Actions(driver);
builder.keyDown(Keys.RETURN).keyUp(Keys.RETURN).build().perform();
You can do something like this
driver.findElement(By.tagName("body")).sendKeys(Keys.ENTER);

Can Selenium WebDriver open a link in a new tab from the current window [duplicate]

I want to be able to open a link in a new tab in Selenium 2. Also i want to close the tab when i am finished interacting with the page. How is this possible if I have a WebElement of an <a> tag?
I am using the Java API of Selenium 2 with the Firefox Driver, running on Firefox 4.
The way I figure out for selenium 2, work fine for Chrome and firefox, IE has security check issue:
Set<String> winSet = webDriver.getWindowHandles();
List<String> winList = new ArrayList<String>(winSet);
String newTab = winList.get(winList.size() - 1);
webDriver.close(); // close the original tab
webDriver.switchTo().window(newTab); // switch to new tab
At the moment, the Selenium WebDriver API doesn't have any way of handling tabs. The project would really need a consistent, cross-browser set of methods for managing tabs before I would expect to see an implementation in one of the language bindings like Java. Until then, your JavaScript solution may be the only way, and remember that your code would then be responsible for managing the lifetime of that tab.
to use selenium at its best we at sol-logics combine it with java.awt.robot class. you can send keys that can close a browser window. try using
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_W);
and reply if it works
Took awhile (~2 weeks) for me to track down the right sequence of commands, but this is by far the easiest method I've found for a Win7/Chrome setup to open a link in a new tab AND switch to the new tab automatically.
WARNING! Make sure to always perform the keyUp actions. If you fail to perform keyUp your system will keep those keys pressed until a reboot or keyUp occurs.
Windows 7/Chrome:
WebElement elem = driver.findElement(By.linkText("MyLinkText"));
// Chrome key combos:
// SHIFT + CTRL + click = Open in new tab (and switch to new tab)
// SHIFT + CTRL + RETURN = Open in new tab (in background)
Actions act = new Actions(driver);
act.keyDown(Keys.LEFT_CONTROL).keyDown(Keys.LEFT_SHIFT).perform();
// Wrap in a try/catch during implementation to ensure you perform keyUp(s).
elem.click();
act.keyUp(Keys.LEFT_CONTROL).keyDown(Keys.LEFT_SHIFT).perform();
Note: I know it's an old thread, I just wanted to catalog the solution here because I couldn't find a more elegant solution and wanted to save someone else a little time (hopefully :).
Edit: Typo
Here is how i did it using Python.
This solution is a bit dirty but it works if you want to close the tab.
Im mimicking the mac shortcut CMD + W to close a tab, if you are running windows you may have to implement a different key combination.
import from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("http://www.amazon.com/gp/search/ref=sr_in_-2_p_lbr_brands_browse-_2895?rh=n%3A172282%2Cn%3A!493964%2Cn%3A502394%2Cp_lbr_brands_browse-bin%3ALytro")
action_chains = ActionChains(driver)
action_chains.key_down(Keys.COMMAND + "w")
action_chains.perform()
action_chains.key_up(Keys.COMMAND + "w")
driver.implicitly_wait(5)
What I use is the Robor class.
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_W);
robot.keyRelease(KeyEvent.VK_CONTROL);
robot.keyRelease(KeyEvent.VK_W);
This makes the Robot rapidly press and release the CTRL + W keys to simulate a user interaction. If you only use keyPress event, this will close all the tabs and windows of the WebDriver.
Hope I helped you.

Switching between user name and password text box and entering corresponding values using Selenium WebDriver java

I am using selenium to navigate to a page and take screenshots using Internet Explorer. But the problem is the login is taken care by a Javascript alert box. Now Selenium has a facility where the focus can be brought to the alert box by using Alert element and I have managed to bring the focus and also enter some values in the user name text box.
The problem is Selenium does not switch focus to the password text box and enters the username and password in the same box. I tried Java AWT Robot to click on the tab key and it changes the focus, but Selenium does not recognized this and it continues entering the user name and password in the same box.
Below is my code:
Robot robot = new Robot();
driver.get("the url");
Alert alert = driver.switchTo().alert();
alert.sendKeys("username");
robot.keyPress(KeyEvent.VK_TAB);
alert.sendKeys("password");
alert.accept();
What am I missing here? Is my approach here correct or do I have to take a different route?
hi Madusudanan Try the code by commenting the another switch method.
Robot robot = new Robot();
Alert alert=dr.switchTo().alert();
dr.get("the url");
alert.sendKeys("username");
//dr.switchTo().alert();
robot.keyPress(KeyEvent.VK_TAB);
alert.sendKeys("password");
alert.accept();
Not a Java answer but since I found this question searching for a .net answer to this problem.
If you're using .NET you'll need to use SendKeys rather than Robot
using System.Windows.Forms;
_driver.SwitchTo().Alert().SendKeys("Username");
SendKeys.SendWait("{TAB}");
SendKeys.SendWait("password");
SendKeys.SendWait("{Enter}");
Hope this helps someone!
According to your question, after focusing on Password field Selenium WebDriver failed to enter/input/type it's corresponding value. You can do type the password value by using Robot class. The following is the whole code:
//First write a method to use StringSelection
public void setClipboardData(String string) {
StringSelection stringSelection = new StringSelection(string);
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null);
}
Robot robot = new Robot();
driver.get("Your URL");
Alert alert = driver.switchTo().alert();
alert.sendKeys("username");
robot.keyPress(KeyEvent.VK_TAB);
robot.keyRelease(KeyEvent.VK_TAB);
//call setClipboardData method declared above
setClipboardData("Your Password");
//Copy Paste by using Robot class
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_CONTROL);
alert.accept();
I create code like that from any source and work after add: a.keyRelease(KeyEvent.VK_ADD);
// Initialize InternetExplorerDriver Instance.
WebDriver driver = new InternetExplorerDriver();
// Load sample calc test URL.
driver.get("your homepage testing");
//Code to handle Basic Browser Authentication in Selenium.
Alert aa = driver.switchTo().alert();
Robot a = new Robot();
aa.sendKeys("beyond"+"\\"+"DND");
a.keyPress(KeyEvent.VK_TAB);
a.keyRelease(KeyEvent.VK_TAB);
a.keyRelease(KeyEvent.VK_ADD);
setClipboardData("P#ssw0rd");
a.keyPress(KeyEvent.VK_CONTROL);
a.keyPress(KeyEvent.VK_V);
a.keyRelease(KeyEvent.VK_V);
a.keyRelease(KeyEvent.VK_CONTROL);
aa.accept(); private static void setClipboardData(String string)StringSelection stringSelection = new StringSelection(string);
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null);
Using java.awt.Robot class comes with two main drawbacks.
Mac issue:
On a Mac OS, when we instantiate a Robot class, Java app launches in the background and takes away the focus (so some in the community were sending VK_META (Cmd key) and VK_TAB to get back to the alert). Since copy & paste shortcut keys are different for Mac, that needs to be also handled (using VK_META in place of VK_CONTROL).
Jenkins or remote runner issue:
Even if we accommodated the issue above, eventually when tests are run from Jenkins job, Robot instantiation becomes a problem again (Robotframework selenium execution through jenkins not working)
Fortunately, sendKeys can handle the tab key (as a scan code) and the code below worked for me.
Alert alert = driver.switchTo().alert();
alert.sendKeys("username" + Keys.TAB.toString() + "password");
alert.accept();

One solution for File Upload using Java Robot API with Selenium WebDriver by Java

I saw that lots of people have Problems uploading a file in a test Environment with Selenium WebDriver. I use the selenium WebDriver and java, and had the same problem. I finally have found a solution, so i will post it here hoping that it helps someone else.
When i need to upload a file in a test, i click with Webdriver in the button and wait for the window "Open" to pop. And then i copy the path to the file in the clipboard and then paste it in the "open" window and click "Enter". This is working because when the window "open" pops up, the focus is always in the "open" button.
You will need these classes and method:
import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.awt.Toolkit;
import java.awt.datatransfer.StringSelection;
public static void setClipboardData(String string) {
StringSelection stringSelection = new StringSelection(string);
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null);
}
And that is what i do, just after opening the "open" window:
setClipboardData("C:\\path to file\\example.jpg");
//native key strokes for CTRL, V and ENTER keys
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_ENTER);
robot.keyRelease(KeyEvent.VK_ENTER);
And that´s it. It is working for me, i hope it works for some of you.
Actually, there is an in-built technique for this, too. It should work in all browsers and operating systems.
Selenium 2 (WebDriver) Java example:
// assuming driver is a healthy WebDriver instance
WebElement fileInput = driver.findElement(By.xpath("//input[#type='file']"));
fileInput.sendKeys("C:/path/to/file.jpg");
The idea is to directly send the absolute path to the file to an element which you would usually click at to get the modal window - that is <input type='file' /> element.
Thanks Alex,
Java Robot API helped me for uploading file. I was fedup with File Upload using WebDriver. Following is the code I used (Small modification to yours):
Robot robot = new Robot();
robot.delay(1000);
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_ENTER);
robot.keyRelease(KeyEvent.VK_ENTER);
robot.delay(1000);
Thanks Alex! I needed this since I could not get the sendKeys function to work when used via Play framework 2.1 (fluentlenium wrapper). I am testing over Firefox [17.0.7] for Mac and had to make a few mods to get it working. Below is an approximation of the final snippet I used.
val file = new File(PATH_TO_IPA)
val stringSelection: StringSelection = new StringSelection(file.getAbsolutePath)
Toolkit.getDefaultToolkit.getSystemClipboard().setContents(stringSelection, null)
val robot: Robot = new Robot()
// Cmd + Tab is needed since it launches a Java app and the browser looses focus
robot.keyPress(KeyEvent.VK_META)
robot.keyPress(KeyEvent.VK_TAB)
robot.keyRelease(KeyEvent.VK_META)
robot.keyRelease(KeyEvent.VK_TAB)
robot.delay(500)
robot.keyPress(KeyEvent.VK_META)
robot.keyPress(KeyEvent.VK_SHIFT)
robot.keyPress(KeyEvent.VK_G)
robot.keyRelease(KeyEvent.VK_META)
robot.keyRelease(KeyEvent.VK_SHIFT)
robot.keyRelease(KeyEvent.VK_G)
robot.keyPress(KeyEvent.VK_META)
robot.keyPress(KeyEvent.VK_V)
robot.keyRelease(KeyEvent.VK_META)
robot.keyRelease(KeyEvent.VK_V)
robot.keyPress(KeyEvent.VK_ENTER)
robot.keyRelease(KeyEvent.VK_ENTER)
robot.delay(500)
robot.keyPress(KeyEvent.VK_ENTER)
robot.keyRelease(KeyEvent.VK_ENTER)
The switching of application on Mac is much better to do with AppleScript. AppleScript is integrated to system, so it will be always functional and does not depend on order of apps on Cmd+Tab. Your test/app will be less fragile.
https://developer.apple.com/library/content/documentation/AppleScript/Conceptual/AppleScriptLangGuide/reference/ASLR_cmds.html
You need only detect you are on mac and has name of the application.
Runtime runtime = Runtime.getRuntime();
String[] args = { "osascript", "-e", "tell app \"Chrome\" to activate" };
Process process = runtime.exec(args);

Categories