3789983e89
Reviewed-by: darcy, ihse
308 lines
9.9 KiB
Java
308 lines
9.9 KiB
Java
/*
|
|
* Copyright (c) 2011, 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.
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
/*
|
|
* @summary Utility routines that wait for a window to be displayed or for
|
|
colors to be visible
|
|
* @summary com.apple.junit.utils
|
|
*/
|
|
package test.java.awt.regtesthelpers;
|
|
|
|
import java.awt.*;
|
|
import java.awt.event.*;
|
|
|
|
//import junit.framework.Assert;
|
|
public class VisibilityValidator {
|
|
|
|
// Wait up to five seconds for our window events
|
|
static final int SETUP_PERIOD = 5000;
|
|
static final boolean DEBUG = false;
|
|
|
|
volatile Window win = null;
|
|
boolean activated = false;
|
|
boolean opened = false;
|
|
boolean focused = false;
|
|
volatile boolean valid = false;
|
|
|
|
//
|
|
// Utility functions that encapsulates normal usage patterns
|
|
//
|
|
public static void setVisibleAndConfirm(Frame testframe) throws Exception {
|
|
setVisibleAndConfirm(testframe, "Could not confirm test frame was "
|
|
+ "visible");
|
|
}
|
|
|
|
public static void setVisibleAndConfirm(Frame testframe, String msg)
|
|
throws Exception {
|
|
if (testframe.isVisible()) {
|
|
throw new RuntimeException("Frame is already visible");
|
|
}
|
|
|
|
VisibilityValidator checkpoint = new VisibilityValidator(testframe);
|
|
testframe.setVisible(true);
|
|
checkpoint.requireVisible();
|
|
if (!checkpoint.isValid()) {
|
|
//System.err.println(msg);
|
|
throw new Exception("Frame not visible after " + SETUP_PERIOD
|
|
+ " milliseconds");
|
|
}
|
|
}
|
|
|
|
//
|
|
// Add listeners to the window
|
|
//
|
|
public VisibilityValidator(Window win) {
|
|
this.win = win;
|
|
WindowAdapter watcher = new WindowAdapter() {
|
|
public void windowOpened(WindowEvent e) {
|
|
doOpen();
|
|
}
|
|
|
|
public void windowActivated(WindowEvent e) {
|
|
doActivate();
|
|
}
|
|
|
|
public void windowGainedFocus(WindowEvent e) {
|
|
doGainedFocus();
|
|
}
|
|
};
|
|
|
|
win.addWindowListener(watcher);
|
|
win.addWindowFocusListener(watcher);
|
|
}
|
|
|
|
// Make the window visible
|
|
//
|
|
// The only way to make it through this routine is for the window to
|
|
// generate BOTH a windowOpened, a windowActivated event and a
|
|
// windowGainedFocus, or to timeout.
|
|
//
|
|
synchronized public void requireVisible() {
|
|
int tries = 0;
|
|
|
|
// wait for windowOpened and windowActivated events
|
|
try {
|
|
while ((opened == false)
|
|
|| (activated == false)
|
|
|| (focused == false)) {
|
|
if (tries < 4) {
|
|
tries += 1;
|
|
wait(SETUP_PERIOD);
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (opened && activated) {
|
|
valid = true;
|
|
} else {
|
|
valid = false;
|
|
}
|
|
} catch (InterruptedException ix) {
|
|
valid = false;
|
|
}
|
|
|
|
// Extra-super paranoid checks
|
|
if (win.isVisible() == false) {
|
|
valid = false;
|
|
}
|
|
|
|
if (win.isShowing() == false) {
|
|
valid = false;
|
|
}
|
|
|
|
if (win.isFocused() == false) {
|
|
valid = false;
|
|
}
|
|
|
|
if (DEBUG) {
|
|
if (!isValid()) {
|
|
System.out.println("\tactivated:" + new Boolean(activated));
|
|
System.out.println("\topened:" + new Boolean(opened));
|
|
System.out.println("\tfocused:" + new Boolean(focused));
|
|
System.out.println("\tvalid:" + new Boolean(valid));
|
|
System.out.println("\tisVisible():"
|
|
+ new Boolean(win.isVisible()));
|
|
System.out.println("\tisShowing():"
|
|
+ new Boolean(win.isShowing()));
|
|
System.out.println("\tisFocused():"
|
|
+ new Boolean(win.isFocused()));
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
synchronized void doOpen() {
|
|
opened = true;
|
|
notify();
|
|
}
|
|
|
|
synchronized void doActivate() {
|
|
activated = true;
|
|
notify();
|
|
}
|
|
|
|
synchronized void doGainedFocus() {
|
|
focused = true;
|
|
notify();
|
|
}
|
|
|
|
public boolean isValid() {
|
|
return valid;
|
|
}
|
|
|
|
public boolean isClear() {
|
|
return valid;
|
|
}
|
|
|
|
volatile static Robot robot = null;
|
|
|
|
// utility function that waits until a Component is shown with the
|
|
// appropriate color
|
|
public static boolean waitForColor(Component c,
|
|
Color expected) throws AWTException,
|
|
InterruptedException {
|
|
Dimension dim = c.getSize();
|
|
int xOff = dim.width / 2;
|
|
int yOff = dim.height / 2;
|
|
return waitForColor(c, xOff, yOff, expected);
|
|
}
|
|
|
|
// utility function that waits for 5 seconds for Component to be shown with
|
|
// the appropriate color
|
|
public static boolean waitForColor(Component c,
|
|
int xOff,
|
|
int yOff,
|
|
Color expected) throws AWTException, InterruptedException {
|
|
return waitForColor(c, xOff, yOff, expected, 5000L);
|
|
}
|
|
|
|
// utility function that waits until a Component is up with the appropriate
|
|
// color
|
|
public static boolean waitForColor(Component c,
|
|
int xOff,
|
|
int yOff,
|
|
Color expected,
|
|
long timeout) throws AWTException, InterruptedException {
|
|
Point p = c.getLocationOnScreen();
|
|
int x = (int) p.getX() + xOff;
|
|
int y = (int) p.getY() + yOff;
|
|
return waitForColor(x, y, expected, timeout);
|
|
}
|
|
|
|
// utility function that waits until specific screen coords have the
|
|
// appropriate color
|
|
public static boolean waitForColor(int locX,
|
|
int locY,
|
|
Color expected,
|
|
long timeout) throws AWTException, InterruptedException {
|
|
if (robot == null) {
|
|
robot = new Robot();
|
|
}
|
|
|
|
long endtime = System.currentTimeMillis() + timeout;
|
|
while (endtime > System.currentTimeMillis()) {
|
|
if (colorMatch(robot.getPixelColor(locX, locY), expected)) {
|
|
return true;
|
|
}
|
|
Thread.sleep(50);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// utility function that asserts that two colors are similar to each other
|
|
public static void assertColorEquals(final String message,
|
|
final Color actual,
|
|
final Color expected) {
|
|
System.out.println("actual color: " + actual);
|
|
System.out.println("expect color: " + expected);
|
|
//Assert.assertTrue(message, colorMatch(actual, expected));
|
|
}
|
|
|
|
// determines if two colors are close in hue and brightness
|
|
public static boolean colorMatch(final Color actual, final Color expected) {
|
|
final float[] actualHSB = getHSB(actual);
|
|
final float[] expectedHSB = getHSB(expected);
|
|
|
|
final float actualHue = actualHSB[0];
|
|
final float expectedHue = expectedHSB[0];
|
|
final boolean hueMatched = closeMatchHue(actualHue, expectedHue, 0.17f);
|
|
//System.out.println("hueMatched? " + hueMatched);
|
|
final float actualBrightness = actualHSB[2];
|
|
final float expectedBrightness = expectedHSB[2];
|
|
final boolean brightnessMatched = closeMatch(actualBrightness,
|
|
expectedBrightness, 0.15f);
|
|
//System.out.println("brightnessMatched? " + brightnessMatched);
|
|
|
|
// check to see if the brightness was so low or so high that the hue
|
|
// got clamped to red
|
|
if (brightnessMatched && !hueMatched) {
|
|
return (expectedBrightness < 0.15f);
|
|
}
|
|
|
|
return brightnessMatched && hueMatched;
|
|
}
|
|
|
|
static float[] getHSB(final Color color) {
|
|
final float[] hsb = new float[3];
|
|
Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), hsb);
|
|
return hsb;
|
|
}
|
|
|
|
// matches hues from 0.0 to 1.0, accounting for wrap-around at the 1.0/0.0
|
|
// boundry
|
|
static boolean closeMatchHue(final float actual,
|
|
final float expected,
|
|
final float tolerance) {
|
|
if (closeMatch(actual, expected, tolerance)) {
|
|
return true;
|
|
}
|
|
|
|
// all that remains is the overflow and underflow cases
|
|
final float expectedHigh = expected + tolerance;
|
|
final float expectedLow = expected - tolerance;
|
|
|
|
if (expectedHigh > 1.0f) {
|
|
// expected is too high, and actual was too low
|
|
//System.out.println("\thue expected too high, actual too low");
|
|
return closeMatch(actual + 0.5f, expected - 0.5f, tolerance);
|
|
}
|
|
|
|
if (expectedLow < 0.0f) {
|
|
// expected is too low, and actual was too high
|
|
//System.out.println("\thue expected too low, actual too high");
|
|
return closeMatch(actual - 0.5f, expected + 0.5f, tolerance);
|
|
}
|
|
|
|
//System.out.println("\tcloseMatchHue? " + false);
|
|
return false;
|
|
}
|
|
|
|
static boolean closeMatch(final float actual,
|
|
final float expected,
|
|
final float tolerance) {
|
|
return (expected + tolerance) > actual && (expected - tolerance) < actual;
|
|
}
|
|
}
|