Статьи

Прогресс в области тестирования пользовательского интерфейса JavaFX

Я наконец сделал некоторый прогресс на FEST-JavaFX ! ?

Основным препятствием было найти способ поиска элементов управления пользовательского интерфейса на любом пользовательском интерфейсе JavaFX. Проблема заключалась в том, что все это время я работал с неверной иерархией узлов, сценарием, а не с JavaFX! Было невозможно выяснить, какой узел соответствует элементу управления. Узлы JavaFX компилируются в узлы Scenegraph, но эти скомпилированные узлы не имеют никакой информации об исходных узлах JavaFX. Кроме того, Сценарий — это деталь реализации, которая может измениться в любое время.

Все это время решение находилось у меня под носом, и я нашел пару хаков, которые могут сделать возможным тестирование пользовательских интерфейсов JavaFX.

Примечание: эти хаки работают с JavaFX 1.3, но могут не работать с будущими выпусками.

Как запустить пользовательский интерфейс JavaFX из Java

Это первый шаг для тестирования любого пользовательского интерфейса JavaFX. В идеале, мы хотели бы написать наш UI-тест в скрипте JavaFX, используя действительно классную поддержку тестов JFXtras (скоро будет объединен с FEST .) ИМХО, также полезно иметь возможность писать UI-тесты в Java (например, для есть выбор между JUnit и TestNG .) В следующем листинге кода показано, как запустить пользовательский интерфейс JavaFX с использованием некоторой магии отражения :

staticMethod("javafx$run$").withReturnType(Object.class)
.withParameterTypes(Sequence.class)
.in(javaFxClass)
.invoke(TypeInfo.String.emptySequence);

где javaFxClass — это класс пользовательского интерфейса JavaFX для запуска.

Этот метод возвращает JavaFX Stage. Как только у нас есть Этап, мы получаем доступ к Сцене пользовательского интерфейса, которая содержит все узлы и элементы управления JavaFX (не Сценарий) в пользовательском интерфейсе.

Поиск местоположения узла на экране: 1-й. попытка

Когда JavaFX запущен и у нас есть доступ ко всем узлам JavaFX (через стадию пользовательского интерфейса), мы можем имитировать ввод данных пользователем на любом узле или элементе управления. Проблема в том, что у узла JavaFX нет способа вернуть свое местоположение на экране (здесь может пригодиться метод, подобный getLocationOnScreen Swing.)

Ниже моя первая попытка. Это работает, но это ужасно в том смысле, что это зависит от слишком большого количества внутренних компонентов, и я уверен, что это не сработает в будущем.

Этот листинг кода вычисляет центр элемента управления относительно экрана:

public static Point centerOf(Control control) {
Point2D center = control.localToScene(control.get$width() / 2, control.get$height() / 2);
Point where = new Point((int)p.$x, (int)p.$y);
Stage stage = stageOf(control);
Point locationOnScreen = locationOnScreenOf(stage);
where.translate(locationOnScreen.x, locationOnScreen.y);
return where;
}

private static Stage stageOf(Control control) {
return control.get$scene().get$stage();
}

private static Point locationOnScreenOf(Stage stage) {
Window window = windowFrom(stage);
return window.getContentPane().getLocationOnScreen();
}

private static Window windowFrom(Stage stage) {
TKStage peer = stage.get$Stage$impl_peer();
FrameStage frameStage = (FrameStage)peer;
return frameStage.window;
}

Когда у нас есть экранные координаты элемента управления, на нем легко моделировать пользовательский ввод. Например, чтобы смоделировать пользователя, нажимающего кнопку, мы можем просто сообщить роботу FEST, где нажать.

Вывод

Теперь, когда можно найти любой узел и найти его положение на экране, мы можем применить все извлеченные уроки, работая над FEST-Swing, и создать инструмент тестирования для пользовательских интерфейсов JavaFX!

 

С http://alexruiz.developerblogs.com/?p=1163