Skip to content

Commit ffc97ba

Browse files
committedSep 30, 2020
8253543: sanity/client/SwingSet/src/ButtonDemoScreenshotTest.java failed with "AssertionError: All pixels are not black"
Reviewed-by: serb
1 parent 5310d85 commit ffc97ba

File tree

4 files changed

+121
-44
lines changed

4 files changed

+121
-44
lines changed
 

‎test/jdk/sanity/client/SwingSet/src/ButtonDemoScreenshotTest.java

+31-20
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -22,6 +22,7 @@
2222
*/
2323

2424
import com.sun.swingset3.demos.button.ButtonDemo;
25+
import org.jemmy2ext.JemmyExt;
2526
import org.jtregext.GuiTestListener;
2627
import org.netbeans.jemmy.ClassReference;
2728
import org.netbeans.jemmy.ComponentChooser;
@@ -33,7 +34,11 @@
3334
import org.testng.annotations.Test;
3435

3536
import java.awt.Component;
37+
import java.awt.Dimension;
38+
import java.awt.Point;
39+
import java.awt.Rectangle;
3640
import java.awt.Robot;
41+
import java.awt.Toolkit;
3742
import java.awt.image.BufferedImage;
3843

3944
import javax.swing.UIManager;
@@ -72,18 +77,32 @@ public void test(String lookAndFeel) throws Exception {
7277
UIManager.setLookAndFeel(lookAndFeel);
7378
Robot rob = new Robot();
7479

80+
//capture some of the background
81+
Dimension screeSize = Toolkit.getDefaultToolkit().getScreenSize();
82+
Point screenCenter = new Point(screeSize.width / 2, screeSize.height / 2);
83+
Rectangle center = new Rectangle(
84+
screenCenter.x - 50, screenCenter.y - 50,
85+
screenCenter.x + 50, screenCenter.y + 50);
86+
BufferedImage background = rob.createScreenCapture(center);
87+
7588
new ClassReference(ButtonDemo.class.getCanonicalName()).startApplication();
7689

7790
JFrameOperator mainFrame = new JFrameOperator(DEMO_TITLE);
78-
waitImageIsStill(rob, mainFrame);
91+
mainFrame.waitComponentShowing(true);
92+
93+
//make sure the frame is already painted
94+
waitChangedImage(rob, () -> rob.createScreenCapture(center),
95+
background, mainFrame.getTimeouts(), "background.png");
96+
//make sure the frame is painted completely
97+
waitStillImage(rob, mainFrame, "frame.png");
7998

8099
// Check all the buttons
81100
for (int i : BUTTONS) {
82101
checkButton(mainFrame, i, rob);
83102
}
84103
}
85104

86-
private void checkButton(JFrameOperator jfo, int i, Robot rob) {
105+
private void checkButton(JFrameOperator jfo, int i, Robot rob) throws InterruptedException {
87106
JButtonOperator button = new JButtonOperator(jfo, i);
88107

89108
//additional instrumentation for JDK-8198920. To be removed after the bug is fixed
@@ -93,9 +112,8 @@ private void checkButton(JFrameOperator jfo, int i, Robot rob) {
93112

94113
button.moveMouse(button.getCenterX(), button.getCenterY());
95114

96-
BufferedImage initialButtonImage = capture(rob, button);
97-
assertNotBlack(initialButtonImage);
98-
save(initialButtonImage, "button" + i + ".png");
115+
BufferedImage notPressed, pressed = null;
116+
notPressed = waitStillImage(rob, button, "not-pressed-" + i + ".png");
99117

100118
BufferedImage[] pressedImage = new BufferedImage[1];
101119

@@ -108,22 +126,15 @@ private void checkButton(JFrameOperator jfo, int i, Robot rob) {
108126
//additional instrumentation for JDK-8198920. To be removed after the bug is fixed
109127
button.getOutput().printTrace("JDK-8198920: Button press confirmed by " + System.currentTimeMillis());
110128
//end of instrumentation for JDK-8198920
111-
button.waitState(new ComponentChooser() {
112-
public boolean checkComponent(Component c) {
113-
pressedImage[0] = capture(rob, button);
114-
assertNotBlack(pressedImage[0]);
115-
return !sComparator.compare(initialButtonImage, pressedImage[0]);
116-
}
117-
118-
public String getDescription() {
119-
return "Button with new image";
120-
}
121-
});
129+
waitChangedImage(rob, () -> capture(rob, button), notPressed,
130+
button.getTimeouts(), "pressed-" + i + ".png");
131+
pressed = waitStillImage(rob, button, "pressed.png");
122132
} finally {
123-
if (pressedImage[0] != null) {
124-
save(pressedImage[0], "button" + i + "_pressed.png");
125-
}
126133
button.releaseMouse();
134+
if(pressed != null) {
135+
waitChangedImage(rob, () -> capture(rob, button), pressed,
136+
button.getTimeouts(), "released-" + i + ".png");
137+
}
127138
//additional instrumentation for JDK-8198920. To be removed after the bug is fixed
128139
button.getOutput().printTrace("JDK-8198920: Button released at " + System.currentTimeMillis());
129140
try {

‎test/jdk/sanity/client/SwingSet/src/EditorPaneDemoTest.java

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -23,8 +23,8 @@
2323

2424
import static com.sun.swingset3.demos.editorpane.EditorPaneDemo.DEMO_TITLE;
2525
import static com.sun.swingset3.demos.editorpane.EditorPaneDemo.SOURCE_FILES;
26-
import static org.jemmy2ext.JemmyExt.EXACT_STRING_COMPARATOR;
27-
import static org.jemmy2ext.JemmyExt.assertNotBlack;
26+
import static org.jemmy2ext.JemmyExt.*;
27+
import static org.testng.Assert.assertFalse;
2828

2929
import java.awt.Color;
3030
import java.awt.Dimension;
@@ -149,7 +149,8 @@ private void checkImage(JEditorPaneOperator editorPaneOperator,
149149
final int xGap = 100, yGap = 40, columns = 2, rows = 5;
150150
editorPaneOperator.waitState(comp -> {
151151
BufferedImage capturedImage = ImageTool.getImage(imageRect);
152-
assertNotBlack(capturedImage);
152+
save(capturedImage, "editor.png");
153+
assertFalse(isBlack(capturedImage), "image blackness");
153154
int x = 0, y = 0, i = 0, j;
154155
for (; i < columns; i++) {
155156
x += xGap;

‎test/jdk/sanity/client/lib/Extensions/src/org/jemmy2ext/JemmyExt.java

+83-19
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -40,6 +40,7 @@
4040
import java.util.Collections;
4141
import java.util.List;
4242
import java.util.function.Function;
43+
import java.util.function.Supplier;
4344
import java.util.logging.Level;
4445
import java.util.logging.Logger;
4546
import java.util.stream.IntStream;
@@ -56,9 +57,11 @@
5657
import org.netbeans.jemmy.DefaultCharBindingMap;
5758
import org.netbeans.jemmy.QueueTool;
5859
import org.netbeans.jemmy.TimeoutExpiredException;
60+
import org.netbeans.jemmy.Timeouts;
5961
import org.netbeans.jemmy.Waitable;
6062
import org.netbeans.jemmy.Waiter;
6163
import org.netbeans.jemmy.drivers.scrolling.JSpinnerDriver;
64+
import org.netbeans.jemmy.image.ImageComparator;
6265
import org.netbeans.jemmy.image.StrictImageComparator;
6366
import org.netbeans.jemmy.operators.ComponentOperator;
6467
import org.netbeans.jemmy.operators.ContainerOperator;
@@ -89,17 +92,13 @@ public class JemmyExt {
8992
DefaultCharBindingMap.class
9093
};
9194

92-
public static void assertNotBlack(BufferedImage image) {
93-
int w = image.getWidth();
94-
int h = image.getHeight();
95-
try {
96-
assertFalse("All pixels are not black", IntStream.range(0, w).parallel().allMatch(x
97-
-> IntStream.range(0, h).allMatch(y -> (image.getRGB(x, y) & 0xffffff) == 0)
98-
));
99-
} catch (Throwable t) {
100-
save(image, "allPixelsAreBlack.png");
101-
throw t;
102-
}
95+
/**
96+
* Checks if the image is complitely black.
97+
*/
98+
public static boolean isBlack(BufferedImage image) {
99+
return IntStream.range(0, image.getWidth()).parallel()
100+
.allMatch(x-> IntStream.range(0, image.getHeight())
101+
.allMatch(y -> (image.getRGB(x, y) & 0xffffff) == 0));
103102
}
104103

105104
public static void waitArmed(JButtonOperator button) {
@@ -184,28 +183,93 @@ public static void save(BufferedImage image, String filename) {
184183
}
185184
}
186185

187-
public static void waitImageIsStill(Robot rob, ComponentOperator operator) {
188-
operator.waitState(new ComponentChooser() {
186+
/**
187+
* Waits for a screen area taken by a component to not be completely black rectangle.
188+
* @return last (non-black) image
189+
* @throws TimeoutExpiredException if the waiting is unsuccessful
190+
*/
191+
public static BufferedImage waitNotBlack(Robot rob, ComponentOperator operator, String imageName) {
192+
class NonBlackImageChooser implements ComponentChooser {
193+
private BufferedImage image = null;
194+
@Override
195+
public boolean checkComponent(Component comp) {
196+
image = capture(rob, operator);
197+
save(image, imageName);
198+
return !isBlack(image);
199+
}
200+
201+
@Override
202+
public String getDescription() {
203+
return "A non-black Image of " + operator;
204+
}
205+
}
206+
NonBlackImageChooser chooser = new NonBlackImageChooser();
207+
operator.waitState(chooser);
208+
return chooser.image;
209+
}
189210

211+
/**
212+
* Waits for the displayed image to be still.
213+
* @return last still image
214+
* @throws TimeoutExpiredException if the waiting is unsuccessful
215+
*/
216+
public static BufferedImage waitStillImage(Robot rob, ComponentOperator operator, String imageName) {
217+
operator.getTimeouts().setTimeout("Waiter.TimeDelta", 1000);
218+
class StillImageChooser implements ComponentChooser {
190219
private BufferedImage previousImage = null;
191-
private int index = 0;
192220
private final StrictImageComparator sComparator = new StrictImageComparator();
193221

194222
@Override
195223
public boolean checkComponent(Component comp) {
196224
BufferedImage currentImage = capture(rob, operator);
197-
save(currentImage, "waitImageIsStill" + index + ".png");
198-
index++;
225+
save(currentImage, imageName);
199226
boolean compareResult = previousImage == null ? false : sComparator.compare(currentImage, previousImage);
200227
previousImage = currentImage;
201228
return compareResult;
202229
}
203230

204231
@Override
205232
public String getDescription() {
206-
return "Image of " + operator + " is still";
233+
return "A still image of " + operator;
207234
}
208-
});
235+
}
236+
StillImageChooser chooser = new StillImageChooser();
237+
operator.waitState(chooser);
238+
return chooser.previousImage;
239+
}
240+
241+
/**
242+
* Waits for the displayed image to change.
243+
* @param reference image to compare to
244+
* @return last (changed) image
245+
* @throws TimeoutExpiredException if the waiting is unsuccessful
246+
*/
247+
public static BufferedImage waitChangedImage(Robot rob,
248+
Supplier<BufferedImage> supplier,
249+
BufferedImage reference,
250+
Timeouts timeouts,
251+
String imageName) throws InterruptedException {
252+
ImageComparator comparator = new StrictImageComparator();
253+
class ImageWaitable implements Waitable {
254+
BufferedImage image;
255+
256+
@Override
257+
public Object actionProduced(Object obj) {
258+
image = supplier.get();
259+
save(image, imageName);
260+
return comparator.compare(reference, image) ? null : image;
261+
}
262+
263+
@Override
264+
public String getDescription() {
265+
return "Waiting screen image to change";
266+
}
267+
}
268+
ImageWaitable waitable = new ImageWaitable();
269+
Waiter waiter = new Waiter(waitable);
270+
waiter.setTimeouts(timeouts);
271+
waiter.waitAction(null);
272+
return waitable.image;
209273
}
210274

211275
private static class ThrowableHolder {

‎test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/ButtonDemo.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -218,6 +218,7 @@ public static void main(String args[]) throws InterruptedException, InvocationTa
218218
JFrame frame = new JFrame(DEMO_TITLE);
219219
frame.add(buttonDemo);
220220
frame.pack();
221+
frame.setLocationRelativeTo(null);
221222
frame.setVisible(true);
222223
});
223224
}

0 commit comments

Comments
 (0)
Please sign in to comment.