niedziela, kwietnia 05, 2009

Seek & Click - automagicznie wykryj buttona i na niego kliknij ;-)

W ramach nic nie robienia weekendowego spróbowałem ostatnio napisać coś co pozwoliłoby na kontrolowanie IE z Java'y, tak by można było pisać jakieś proste testy naszej pracowej aplikacji w Java'ie.

Z pomocą przyszedł mi Jacob, dzięki któremu Java może operować obiektami COM/ActiveX.

Dzięki niemu linia:
ActiveXComponent misio = new ActiveXComponent("InternetExplorer.Application");
Dispatch.put(misio,"Visible",new Variant(true));

Tworzy nam połączenie między Java'ą, a kontrolką IE i powoduje pokazanie okienka IE.

Korzystając z takiego połączenia można np. załadować do naszego IE jakąś stronę:
Dispatch.call(misio, "Navigate", url);


Można pobrać obiekt document:
Dispatch document = Dispatch.get(misio,"document").toDispatch();


A używając obiektu document możemy dobrać się do elementów na stronie:
Dispatch field = Dispatch.call(document,"getElementById",id).toDispatch();


I ustawiać ich atrybuty:
Dispatch.put(field,"value",value);


Zachciało mi się jednak wprowadzania znaków nie poprzez operowanie na polach, a przez symulowanie pisania na klawiaturze [chciałem przetestować mój ficzer do autocomplet'u]. Użyłem tu sztuczki polegającej na przeniesieniu focusa do wybranego elementu, a później przesłaniu kodów klawiszy dzięki klasie java.awt.Robot:
Dispatch field = Dispatch.call(document,"getElementById",id).toDispatch();
Dispatch.call(field,"focus");
Robot robot = new Robot();
robot.setAutoDelay(50);
robot.keyPress(KeyEvent.VK_F);
robot.keyRelease(KeyEvent.VK_F);


Do szczęścia brakowało mi tylko klikania na elementy interfejsu ;-)
Miałem kilka pomysłów, ale tutaj przedstawię tylko jeden, najbardziej szalony ;-)

Z pomocą przyszła mi znowu klasa java.awt.Robot i jej metoda createScreenCapture(Rectangle).
W celu wykrycia położenia współrzędnych [w pewnych warunkach ;-)] wystarczy:
1) zniknąć element

2) zrobić zrzut ekranu
3) pojawić element

4) zrobić zrzut ekranu
5) na wszystkich pixelach obu obrazów zrobić XOR


Fakt, faktem, że taka operacja jest o tyle ryzykowna, że nie tylko nasz element może być widoczny na wynikowym obrazku ;-)
Poniżej fragment wynikowego obrazka, na którym widać wszystkie elementy ekranu, które uległy zmianie.



W tym miejscu przyznam się, że poszedłem na łatwiznę i jako położenie elementu do klikania uznałem współrzędne pierwszego widocznego elementu [patrząc od lewego górnego rogu :-)]. Do takich współrzędnych wystarczy dodać po 5 pixeli i jesteśmy w domu ;-) Możemy klikać:
robot.mouseMove(startX+5, startY+5);
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.mouseRelease(InputEvent.BUTTON1_MASK);


Tak to jest jak się człowiekowi nudzi ;-)


Podobne postybeta
Mój Robot - podejście pierwsze ;-)
Sprawdź godzinę wschodu i zachodu Słońca na komórce ;-)
Motanie kodu - czyli co wynika z chęci zarządzania zadaniami
Tak tworzy się przyszłość
"Kodowanie" na Chrome OS ;-)