Keyboard Robot class issue - java

I've created Keyboard class for working with Robot. But when I starting using methods from this class I have error in logs.
Here's my Keyboard.java with method pressEscape():
public class Keyboard {
private static Robot robot;
private static int time = 1000;
public Keyboard(){
try {
robot = new Robot();
} catch (AWTException e) {
e.printStackTrace();
}
}
public void pressEscape() throws TestException {
if (!getSession().CanRun())
throw new TestException(InvalidStateMessage);
robot.delay(time);
robot.keyPress(KeyEvent.VK_ESCAPE);
robot.delay(time);
robot.keyRelease(KeyEvent.VK_ESCAPE);
robot.delay(time);
}
}
And here's error from log:
[2015/08/13 15:43:29] [ID:7F4315A] [Selenium]: java.lang.NullPointerException
[2015/08/13 15:43:29] [ID:7F4315A] [Selenium]: at Kodak.AutoTest.Framework.Keyboard.pressEscape(Keyboard.java:128)
Change a little method:
public void pressEscape() throws TestException {
if (!getSession().CanRun())
throw new TestException(InvalidStateMessage);
try {
new Robot();
robot.setAutoDelay(time);
robot.keyPress(KeyEvent.VK_ESCAPE);
robot.setAutoDelay(time);
robot.keyRelease(KeyEvent.VK_ESCAPE);
} catch (AWTException e) {
e.printStackTrace();
}
}
but still has the same error on line:
robot.keyPress(KeyEvent.VK_ESCAPE);

It looks as though the only place you can realistically get a null pointer exception in that method is in this line:
if (!getSession().CanRun())
which will throw a NPE if getSession() returns null. Actually the other option is if you failed to initialise robot, but then you'd be seeing an AWTException in the logs.
But you should confirm this by looking at the line number that the logs gave you. If this is right, I'd suggest changing
if (!getSession().CanRun())
throw new TestException(InvalidStateMessage);
to
Session session = getSession();
if ((session==null) || !session.CanRun())
throw new TestException(InvalidStateMessage);
That will harden that part, and mean you'll get a TestException if the session is null. (I am guessing the type that getSession() returns.)
Additionally, although you are initialising robot in your constructor, you should be aware that it's a static field. That means that if you have lots of Keyboard instances, every time you create an instance, it'll overwrite the previous instance of robot with a new one, because they all share the same one.
You should either change it to an instance field (remove the static modifier), or initialise it only once (check if it's null, and initialise it only if so).

For this to happen your robot variable should be null at line 128. This can happen only new Robot() threw an exception. Check your logs to see whether it is the case. And also see comments to your questions from MadProgrammer and act on them.

It's working now, here's full code:
public class Keyboard {
private static Robot robot;
public void pressEscape() throws TestException {
if (!getSession().CanRun())
throw new TestException(InvalidStateMessage);
try {
robot = new Robot();
robot.setAutoDelay(time);
robot.keyPress(KeyEvent.VK_ESCAPE);
robot.setAutoDelay(time);
robot.keyRelease(KeyEvent.VK_ESCAPE);
} catch (AWTException e) {
e.printStackTrace();
}
}
}

Related

I want to test whether the try catch block in my method is working or not

The below method is a method in my logic class that removes the required index from the list. I made an exception class so it handles an empty list or a list that will not have this index
public class LogicClass{
public void removeThisObject (ArrayList<ThisObject> thisObjList, int index){
try{
if(thisObjList.size() < (index+1)) throw new MyException ("this list is empty or does not have this index");
thisObjList.remove(index);
}catch(MyException me){
me.getMessage();
}
}
}
Now Im trying to test this method in my JUnit tests class and I would like to INTENTIONALLY trigger the exception just to see whether the exception is not working or not
public class Testing extends TestCase {
public void testRemoveObj() {
System.out.println("Checking if obj is being removed");
LogicClass logicClass = new LogicClass();
//ThisObject thisObj = new ThisObject();
//INTENTIONALLY GIVING AN EMPTY LIST FOR THE METHOD TO PROCESS
ArrayList<ThisObj> emptyList = new ArrayList<ThisObj>();
try{
//INTENTIONALLY GIVING INDEX 3 FOR AN EMPTY LIST
logicClass.removeThisObject(3,emptyList);
fail("Exception was not caught");
}catch (Exception e){
System.out.println("Exception caught successfully");
System.out.println(e.getMessage());
}
System.out.println("Removal was processed successfully. End of Test\n");
}
}
But instead the method just .... works. The exception works fine as when i comment it out in the logic the JUnit throws an IndexOutOfBoundException, when uncommented it just gives me the output:
Checking if ingredient is being removed
Removal was processed successfully. End of Test
I apologize if i missed any brackets here and there. I really hope the code was typed out correctly to follow. Im hoping that you get the jist of it.
So all in all I am trying to purposely trigger the exception in the tests so to see whether the exception was properly implemented or not. Would appreciate any help.
Thank you !!!
about your line :
So all in all I am trying to purposely trigger the exception in the tests so to see whether the exception was properly implemented or not. Would appreciate any help.
you can trigger the catch by this code :
if(true){
Exception exception = new Exception();
throw exception;
}
for your function it will be like :
public class Testing extends TestCase {
public void testRemoveObj() {
System.out.println("Checking if obj is being removed");
LogicClass logicClass = new LogicClass();
//ThisObject thisObj = new ThisObject();
//INTENTIONALLY GIVING AN EMPTY LIST FOR THE METHOD TO PROCESS
ArrayList<ThisObj> emptyList = new ArrayList<ThisObj>();
try{
//INTENTIONALLY GIVING INDEX 3 FOR AN EMPTY LIST
if(true){
Exception exception = new Exception();
throw exception;
}
logicClass.removeThisObject(3,emptyList);
fail("Exception was not caught");
}catch (Exception e){
System.out.println("Exception caught successfully");
System.out.println(e.getMessage());
}
System.out.println("Removal was processed successfully. End of Test\n");
}
}
this code will trigger an exception so you will be able to test your catch methods
Using junit without assertThrows:
#Test
void test_throwExceptionWithoutAssertThrows() {
try {
// trigger exception
} catch(MyException ex) { // Catch your specified exception
...
assertStatements // optional
return; // Stop execution at this point.
}
fail(); // we didn't catch, assert and return. Something went wrong.
}
Using junit5 you can assert Exceptions with the assertThrows(< TargetedException >.class, lambdaExpression) like this:
#Test
void whenRemoveThisObjectCalled_thenMyExceptionThrown() {
LogicClass logicClass = new LogicClass();
assertThrows(MyException.class, () -> {
List<Integer> emptyList = Collections.emptyList();
logicClass.removeThisObject(1, emptyList);
});
}
Explanation:
After your try-catch block executed, Exception or not, the program will continue. That is why you will see your "was successful" output, even if your desired Exception was thrown. If you know which scenario of exception throwing you want to test, it's not a good idea to "test try-catch in general", because we can assume that try-catch will work. Instead you can test, if your Exception is thrown under specified circumstances (see code above).
try this answer will post the success when it done :
public class Testing extends TestCase {
public void testRemoveObj() {
System.out.println("Checking if obj is being removed");
LogicClass logicClass = new LogicClass();
//ThisObject thisObj = new ThisObject();
//INTENTIONALLY GIVING AN EMPTY LIST FOR THE METHOD TO PROCESS
ArrayList<ThisObj> emptyList = new ArrayList<ThisObj>();
try{
//INTENTIONALLY GIVING INDEX 3 FOR AN EMPTY LIST
if(true){
Exception exception = new Exception();
throw exception;
}
logicClass.removeThisObject(3,emptyList);
fail("Exception was not caught");
System.out.println("Removal was processed successfully. End of Test\n");
}catch (Exception e){
System.out.println("Exception caught successfully");
System.out.println(e.getMessage());
}
}
}

Java Robot doesnt Press Enter Key how it should

Im trying to program a litte Robot, that should just write for some hours the same phrase with a delay.
But somehow, if i have mor than 1 Letter at the same time before the Enter Key, it rather types a Pyramide.
For Example, if i wanna print "ted", it prints the following:
ted
tedted
tedtedted
tedtedtedted
[...]
(There is no empty line between the Pyramide-Lines)
It gets really frustrating.
I Tried many solutions, but none worked. Making a Delay for the robot, an extra Robot for the Enter Key, put it in an extra Thread or creating new Robots every time before a new Typing. It just doesnt work. What am i doing wrong?
Here is a SSCCE with some trys i did:
#SuppressWarnings("CallToPrintStackTrace")
public class RobotTest {
private static Robot robo;
private static Robot okRobo;
static {
createRobos();
}
private static void createRobos(){
try {
robo = new Robot();
okRobo = new Robot();
} catch (AWTException ex) {
ex.printStackTrace();
}
}
#SuppressWarnings({"CallToPrintStackTrace", "SleepWhileInLoop"})
public static void main(String[] args) throws InterruptedException {
Thread.sleep(5000);
for (int i = 0; i < 16; i++) {
createRobos();
perform();
// Thread.sleep(500);
performOk();
}
}
private static void perform() {
robo.keyPress(KeyEvent.VK_SHIFT);
robo.keyPress(KeyEvent.VK_1);
robo.keyRelease(KeyEvent.VK_SHIFT);
robo.keyRelease(KeyEvent.VK_1);
robo.keyPress(KeyEvent.VK_B);
robo.keyRelease(KeyEvent.VK_B);
robo.keyPress(KeyEvent.VK_O);
robo.keyRelease(KeyEvent.VK_O);
robo.keyPress(KeyEvent.VK_O);
robo.keyRelease(KeyEvent.VK_O);
robo.keyPress(KeyEvent.VK_S);
robo.keyRelease(KeyEvent.VK_S);
robo.keyPress(KeyEvent.VK_T);
robo.keyRelease(KeyEvent.VK_T);
robo.keyPress(KeyEvent.VK_E);
robo.keyRelease(KeyEvent.VK_E);
robo.keyPress(KeyEvent.VK_D);
robo.keyRelease(KeyEvent.VK_D);
// robo.waitForIdle();
}
private static void performOk() {
okRobo.keyPress(KeyEvent.VK_ENTER);
okRobo.keyRelease(KeyEvent.VK_ENTER);
// okRobo.waitForIdle();
}
}
And here is my first try, that should work in my opinion too, but it doesnt:
public class RobotTest {
private static Robot robo;
#SuppressWarnings("CallToPrintStackTrace")
static {
try {
robo = new Robot();
} catch (AWTException ex) {
ex.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException {
Thread.sleep(5000);
for (int i = 0; i < 16; i++) {
perform();
}
}
private static void perform() {
robo.keyPress(KeyEvent.VK_SHIFT);
robo.keyPress(KeyEvent.VK_1);
robo.keyRelease(KeyEvent.VK_SHIFT);
robo.keyRelease(KeyEvent.VK_1);
robo.keyPress(KeyEvent.VK_B);
robo.keyRelease(KeyEvent.VK_B);
robo.keyPress(KeyEvent.VK_O);
robo.keyRelease(KeyEvent.VK_O);
robo.keyPress(KeyEvent.VK_O);
robo.keyRelease(KeyEvent.VK_O);
robo.keyPress(KeyEvent.VK_S);
robo.keyRelease(KeyEvent.VK_S);
robo.keyPress(KeyEvent.VK_T);
robo.keyRelease(KeyEvent.VK_T);
robo.keyPress(KeyEvent.VK_E);
robo.keyRelease(KeyEvent.VK_E);
robo.keyPress(KeyEvent.VK_D);
robo.keyRelease(KeyEvent.VK_D);
robo.keyPress(KeyEvent.VK_ENTER);
robo.keyRelease(KeyEvent.VK_ENTER);
robo.delay(500);
}
Try not to initialize your Robot at each iteration of the loop. Call createRobos() outside of the loop. That is unless you have a specific reason that you're doing it that way.
I don't think you need two separate instances of Robot to get this to work.
Instead of using Thread.sleep(), you can use the delay() method within the Robot class. This is if you want to add a delay between Robot method calls.
You may want to try to add a delay between when you're typing out the letter keys and when you're pressing the enter key and after you press the enter key. A 50 - 100 ms delay will usually do the trick. Sometimes, things get a little messed up, especially when you throw Thread.sleep() into the mix.
I ran your code with these small changes and it seemed to work fine.

Class body - Call function to instantiate variable (unhandled exception type)

I'm having a small issue with my java code.
public class test {
static char[] pass = getMac(); // getting error on this line
public static char[] getMac() throws UnknownHostException
{
...code...
return x;
}
}
I am already throwing the exception in the method but i'm getting the error on this line too :
static char[] pass = getMac(); // getting error on this line
unhandled Exception Type : unknownHostException
is there any way to fix this ?
Thanks
I have tried :
try
{
static char[] pass = getMac();
}
catch (UnknownHostException e)
{
.....
}
but it doesn't work in the main class .
I am already throwing the exception in the method...
Right. That's the problem. By saying that the method throws that exception, you're forcing the calling code to handle it. Java's class initialization code isn't going to handle it for you, so you're getting an unhandled exception error.
Either handle it in the method, or defer initializing that static field until a time when you can handle it*. Note that static initializer blocks are allowed to include flow logic, so that's also an option.
Handling it in the method:
public static char[] getMac()
{
try {
// ...
return x;
}
catch (UnknownHostException e) {
// Appropriate handling
return null; // Or whatever's appropriate
}
}
Using a static initializer block:
public class test {
static char[] pass;
static {
try {
// ...
pass = x;
}
catch (UnknownHostException e) {
// Appropriate handling
pass = null; // Or whatever's appropriate
}
}
}

I need JUnit to pass only if 6 IllegalArgumentExceptions are thrown

Each statement new M#().multiply(-1) throws an IllegalArgumentException. Right now This passes if at least 1 exception is thrown. I need this to only pass if every single statement new M#().multiply(-1) throws an exception.
#Rule
public ExpectedException exception = ExpectedException.none();
#Test
public void test(){
exception.expect(IllegalArgumentException.class);
exception.expectMessage("Integers must be positive");
new M1().multiply(-1);
new M2().multiply(-1);
new M3().multiply(-1);
new M4().multiply(-1);
new M5().multiply(-1);
new M6().multiply(-1);
}
I've been working on this for way too long now, please help.
First, I don't think a unit test should do this. You can simply create 6 tests, each creating a different class object and expecting an exception.
Yet still, for this situation, you can catch the IllegalArgumentExceptions and count how many times they occur:
int exceptionCount = 0;
try {
new M1().multiply(-1);
} catch(IllegalArgumentException ex) {
exceptionCount++;
}
try {
new M2().multiply(-1);
} catch(IllegalArgumentException ex) {
exceptionCount++;
}
...
Assert.assertEquals(exceptionCount, 6);

How can I make Robot type a `:`?

I want to type : using Java Robot. However, I'm getting an IllegalArgumentException. My code is:
robot.keyPress(KeyEvent.VK_SHIFT);
robot.keyPress(KeyEvent.VK_COLON);
robot.keyRelease(KeyEvent.VK_COLON);
robot.keyRelease(KeyEvent.VK_SHIFT);
The exception is:
java.lang.IllegalArgumentException: Invalid key code.].
I also tried with:
robot.keyPress(KeyEvent.VK_SHIFT);
robot.keyPress(KeyEvent.VK_SEMICOLON);
robot.keyRelease(KeyEvent.VK_SEMICOLON);
robot.keyRelease(KeyEvent.VK_SHIFT);
How can I solve this problem?
try with this code :
robot.keyPress(KeyEvent.VK_SHIFT);
robot.keyPress(KeyEvent.VK_SEMICOLON);
robot.keyRelease(KeyEvent.VK_SEMICOLON);
robot.keyRelease(KeyEvent.VK_SHIFT);
As with the keyboard you enter : when you press shift + ;. the same you need to simulate.
Try running this code just to try out which works fine with above answer:
public class Test {
public static void main(String[] args) {
Robot robot;
try {
robot = new Robot();
robot.keyPress(KeyEvent.VK_SHIFT);
robot.keyPress(KeyEvent.VK_SEMICOLON);
robot.keyRelease(KeyEvent.VK_SEMICOLON);
robot.keyRelease(KeyEvent.VK_SHIFT);
} catch (AWTException e) {
// TODO Auto-generated catch bloc
e.printStackTrace();
}
}
}
Unfortunately, Java Robot class relies on a platform specific implementation of an undocumented interface called java.awt.peer.RobotPeer. The platform specific implementation decides what key press events are legal or illegal.
On my windows XP box, this works fine:
public static void main(final String[] args) throws InterruptedException, IOException {
Robot robot;
try {
robot = new Robot();
robot.keyPress(KeyEvent.VK_SHIFT);
robot.keyPress(KeyEvent.VK_SEMICOLON);
robot.keyRelease(KeyEvent.VK_SEMICOLON);
robot.keyRelease(KeyEvent.VK_SHIFT);
} catch (final AWTException e) {
// TODO Auto-generated catch bloc
e.printStackTrace();
}
}
On a different platform you may want to try:
public static void main(final String[] args) throws InterruptedException, IOException {
Robot robot;
try {
robot = new Robot();
robot.keyPress(KeyEvent.VK_COLON);
robot.keyRelease(KeyEvent.VK_COLON);
} catch (final AWTException e) {
// TODO Auto-generated catch bloc
e.printStackTrace();
}
}
try this code ;), maybe it helps (using ascii code alt+5+8=:):
robot9.delay(20);
robot9.keyPress(KeyEvent.VK_ALT);
robot9.delay(20);
robot9.keyPress(KeyEvent.VK_NUMPAD5);
robot9.keyRelease(KeyEvent.VK_NUMPAD5);
robot9.delay(20);
robot9.keyPress(KeyEvent.VK_NUMPAD8);
robot9.keyRelease(KeyEvent.VK_NUMPAD8);
robot9.delay(20);
robot9.keyRelease(KeyEvent.VK_ALT);
robot9.delay(20);
This also seems to be language dependent. On a German keyboard, using the combination of VK_SHIFT and VK_PERIOD worked.
I don't know about Java Robots, but if you're using shift, shouldn't you then type semicolon, because shift + semicolon = colon. So it's probably an illegal argument because colon isn't a key, semicolon is.
Try This Code
case KeyEvent.VK_SEMICOLON:
if((event.getModifiers() & KeyEvent.KEY_PRESSED)!=0)
System.out.println(":");
else
System.out.print(";");
break;
Someone build a KeyboardKeys class and published it here in SO. it´s at https://stackoverflow.com/a/20979488/7069565. In a nutshell, he types every character as an Alt + Number combination.
Semicolon is an "upercase leter", that is, you only get it with the combination of Keys
Shift+Coma
Try this:
robot = new Robot();
robot.keyPress(KeyEvent.VK_SHIFT);
robot.keyPress(KeyEvent.VK_COMMA);
//Since you have the Shift pressed it will generate a semi colon.
robot.keyRelease(KeyEvent.VK_COMMA);
robot.keyRelease(KeyEvent.VK_SHIFT);
I hope I have helped.
Have a nice day. :)

Categories

Resources