--- /dev/null 2018-06-08 03:31:34.228000000 +0530 +++ new/tests/system/src/test/java/test/robot/javafx/scene/MouseLocationOnScreenTest.java 2018-06-08 18:28:29.516957525 +0530 @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package test.robot.javafx.scene; + +import com.sun.glass.ui.Robot; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import javafx.application.Application; +import javafx.application.Platform; +import javafx.geometry.Rectangle2D; +import javafx.stage.Screen; +import javafx.stage.Stage; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +public class MouseLocationOnScreenTest { + static CountDownLatch startupLatch; + static Robot robot; + static boolean mismatchFound = false; + + public static class TestApp extends Application { + + @Override + public void start(Stage primaryStage) throws Exception { + robot = com.sun.glass.ui.Application.GetApplication().createRobot(); + startupLatch.countDown(); + } + } + + @BeforeClass + public static void initFX() { + startupLatch = new CountDownLatch(1); + + new Thread(() -> Application.launch(TestApp.class, (String[]) null)) + .start(); + try { + if (!startupLatch.await(15, TimeUnit.SECONDS)) { + Assert.fail("Timeout waiting for FX runtime to start"); + } + } catch (InterruptedException ex) { + Assert.fail("Unexpected exception: " + ex); + } + } + + @Test(timeout = 40000) + public void testMouseLocation() throws Exception { + Screen screen = Screen.getPrimary(); + Rectangle2D bounds = screen.getBounds(); + double x1 = bounds.getMinX(); + double x2 = x1 + bounds.getWidth() - 1; + double y1 = bounds.getMinY(); + double y2 = y1 + bounds.getHeight() - 1; + + // We'll check all edge (two pixels in a width) of the each screen + edge(robot, x1, y1, x2, y1); // top + edge(robot, x1, y1 + 1, x2, y1 + 1); // top + + edge(robot, x2, y1, x2, y2); // right + edge(robot, x2 - 1, y1, x2 - 1, y2); // right + + edge(robot, x1, y1, x1, y2); // left + edge(robot, x1 + 1, y1, x1 + 1, y2); // left + + edge(robot, x1, y2, x2, y2); // bottom + edge(robot, x1, y2 - 1, x2, y2 - 1); // bottom + + // We'll check crossing of diagonals of each screen + cross(robot, x1, y1, x2, y2); // cross left-bottom + cross(robot, x1, y2, x2, y1); // cross left-top + } + + @AfterClass + public static void teardown() { + Platform.exit(); + } + + public static void waitForLatch(CountDownLatch latch, int seconds, + String msg) + { + try { + if (!latch.await(seconds, TimeUnit.SECONDS)) { + Assert.fail(msg); + } + } catch (Exception ex) { + Assert.fail("Unexpected exception: " + ex); + } + } + + /** + * This method checks the coordinates which were passed to robot and + * returned by robot are same + */ + static void validate(Robot robot, double x, double y) { + CountDownLatch latch = new CountDownLatch(1); + Platform.runLater(() -> { + int innerX = robot.getMouseX(); + int innerY = robot.getMouseY(); + if (innerX != (int)x || innerY != (int)y) { + System.err.println("Expected X: " + (int)x); + System.err.println("Actual X: " + innerX); + System.err.println("Expected Y: " + (int)y); + System.err.println("Actual Y: " + innerY); + mismatchFound = true; + } + latch.countDown(); + }); + waitForLatch(latch, 2, "Timeout in validate function"); + if (mismatchFound) { + throw new RuntimeException(); + } + } + + private static void edge(Robot robot, double x1, double y1, double x2, + double y2) { + for (double x = x1; x <= x2; x++) { + for (double y = y1; y <= y2; y++) { + CountDownLatch latch = new CountDownLatch(1); + final int innerX = (int)x; + final int innerY = (int)y; + Platform.runLater(() -> { + robot.mouseMove(innerX, innerY); + latch.countDown(); + }); + waitForLatch(latch, 2, "Timeout in edge function"); + validate(robot, x, y); + } + } + } + + private static void cross(Robot robot, double x0, double y0, double x1, + double y1) { + double dmax = (float) Math.max(Math.abs(x1 - x0), Math.abs(y1 - y0)); + double dx = (x1 - x0) / dmax; + double dy = (y1 - y0) / dmax; + + CountDownLatch latch = new CountDownLatch(1); + Platform.runLater(() -> { + robot.mouseMove((int)x0, (int)y0); + latch.countDown(); + }); + waitForLatch(latch, 2, "Timeout"); + validate(robot, x0, y0); + + for (double i = 1; i <= dmax; i++) { + double x = x0 + dx * i; + double y = y0 + dy * i; + CountDownLatch latch1 = new CountDownLatch(1); + Platform.runLater(() -> { + robot.mouseMove((int)x, (int)y); + latch1.countDown(); + }); + waitForLatch(latch1, 2, "Timeout in cross function"); + validate(robot, x, y); + } + } +}