1 /* 2 * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 @test 26 @summary See <rdar://problem/3429130>: Events: actionPerformed() method not called when it is button is clicked (system load related) 27 @summary com.apple.junit.java.awt.Frame 28 @library ../../../regtesthelpers 29 @build VisibilityValidator 30 @build RobotUtilities 31 @build Waypoint 32 @run junit NestedModelessDialogTest 33 */ 34 35 /////////////////////////////////////////////////////////////////////////////////////// 36 // NestedModelessDialogTest.java 37 // The test launches a parent frame. From this parent frame it launches a modal dialog 38 // From the modal dialog it launches a modeless dialog with a text field in it and tries 39 // to write into the text field. The test succeeds if you are successfully able to write 40 // into this Nested Modeless Dialog 41 ///////////////////////////////////////////////////////////////////////////////////// 42 43 // classes necessary for this test 44 import junit.framework.*; 45 import java.awt.*; 46 import java.awt.event.*; 47 import java.util.Enumeration; 48 49 import test.java.awt.regtesthelpers.RobotUtilities; 50 import test.java.awt.regtesthelpers.VisibilityValidator; 51 import test.java.awt.regtesthelpers.Waypoint; 52 53 54 public class NestedModelessDialogTest extends TestCase { 55 56 public static Test suite() { 57 return new TestSuite(NestedModelessDialogTest.class); 58 } 59 60 Waypoint[] event_checkpoint = new Waypoint[3]; 61 VisibilityValidator[] win_checkpoint = new VisibilityValidator[2]; 62 63 IntermediateDialog interDiag; 64 TextDialog txtDiag; 65 66 // Global variables so the robot thread can locate things. 67 Button[] robot_button = new Button[2]; 68 TextField robot_text = null; 69 70 /** 71 * Get called by test harness 72 * @throws Exception 73 */ 74 75 public void testModelessDialogs() throws Exception { 76 Frame frame = null; 77 String result = ""; 78 79 event_checkpoint[0] = new Waypoint(); // "-Launch 1-" 80 event_checkpoint[1] = new Waypoint(); // "-Launch 2-" 81 82 try { 83 // Thread.currentThread().setName("NestedModelessDialogTest Thread"); 84 // launch first frame with fistButton 85 frame = new StartFrame(); 86 VisibilityValidator.setVisibleAndConfirm(frame); 87 88 Thread.sleep(250); // shouldn't need this, but Thread.sleep adds stability 89 RobotUtilities.click (robot_button[0]); 90 91 // Dialog must be created and onscreen before we proceed. 92 // The event_checkpoint waits for the Dialog to be created. 93 // The win_checkpoint waits for the Dialog to be visible. 94 95 event_checkpoint[0].requireClear(); 96 Thread.sleep(250); // shouldn't need this, but Thread.sleep adds stability 97 assertTrue( "TestFrame actionPerformed() never called, see <rdar://problem/3429130>", event_checkpoint[0].isValid() ); 98 99 win_checkpoint[0].requireVisible(); 100 assertTrue( "Could not confirm intermediate dialog was visible", win_checkpoint[0].isValid() ); 101 102 Thread.sleep(250); // shouldn't need this, but Thread.sleep adds stability 103 RobotUtilities.click (robot_button[1]); 104 105 // Again, the Dialog must be created and onscreen before we proceed. 106 // The event_checkpoint waits for the Dialog to be created. 107 // The win_checkpoint waits for the Dialog to be visible. 108 109 event_checkpoint[1].requireClear(); 110 Thread.sleep(250); // shouldn't need this, remove when 3429130 is addressed 111 assertTrue( "IntermediateDialog actionPerformed() never called, see <rdar://problem/3429130>", event_checkpoint[1].isValid() ); 112 113 win_checkpoint[1].requireVisible(); 114 assertTrue( "Could not confirm test dialog was visible", win_checkpoint[1].isValid() ); 115 116 Thread.sleep(250); // shouldn't need this, but Thread.sleep adds stability 117 RobotUtilities.click(robot_text); 118 119 // I'm really not sure whether the click is needed for focus 120 // but since it's asynchronous, as is the actually gaining of focus 121 // we might as well do our best 122 Thread.sleep(250); // shouldn't need this, but Thread.sleep adds stability 123 try { EventQueue.invokeAndWait(new Runnable() { public void run() {} }); } catch (Exception e) {} 124 125 RobotUtilities.pressKey(KeyEvent.VK_SHIFT); 126 RobotUtilities.typeKey(KeyEvent.VK_H); 127 RobotUtilities.releaseKey(KeyEvent.VK_SHIFT); 128 RobotUtilities.typeKey(KeyEvent.VK_E); 129 RobotUtilities.typeKey(KeyEvent.VK_L); 130 RobotUtilities.typeKey(KeyEvent.VK_L); 131 RobotUtilities.typeKey(KeyEvent.VK_O); 132 133 // 134 // NOTE THAT WE MAY HAVE MORE SYNCHRONIZATION WORK TO DO HERE. 135 // CURRENTLY THERE IS NO GUARANTEE THAT THE KEYEVENT THAT THAT 136 // TYPES THE 'O' HAS BEEN PROCESSED BEFORE WE GET THE RESULT 137 // 138 139 // This is a (lame) attempt at waiting for the last typeKey events to propagate 140 // It's not quite right because robot uses CGRemoteOperations, which are asynchronous 141 // But that's why I put in the Thread.sleep 142 Thread.sleep(250); // shouldn't need this, but Thread.sleep adds stability 143 try { EventQueue.invokeAndWait(new Runnable() { public void run() {} }); } catch (Exception e) {} 144 145 // We really need to call this before the dialog that robot_text is in is disposed 146 result = robot_text.getText(); 147 148 Thread.sleep(250); // shouldn't need this, but Thread.sleep adds stability 149 RobotUtilities.clickAt(txtDiag, 14,10); // Click Close box of modeless dialog with textField 150 151 Thread.sleep(250); // shouldn't need this, but Thread.sleep adds stability 152 RobotUtilities.clickAt(interDiag, 14,10); // Click Close box of intermediate modal dialog 153 154 Thread.sleep(250); // shouldn't need this, but Thread.sleep adds stability 155 RobotUtilities.clickAt(frame, 14,10); // Click Close box of intermediate modal dialog 156 } 157 finally { 158 frame.setVisible(false); 159 frame.dispose(); 160 } 161 162 String expected = "Hello"; 163 assertEquals("Bad result from getText().\n\nExpected: \n\t*" + expected +"*\nActual:\n\t*"+result +"*\n",expected, result ); 164 165 } 166 167 168 //////////////////// Start Frame /////////////////// 169 /** 170 * Launches the first frame with a button in it 171 */ 172 173 class StartFrame extends Frame { 174 /** 175 * Constructs a new instance. 176 */ 177 public StartFrame() { 178 super("First Frame"); 179 setLayout(new GridBagLayout()); 180 setLocation(375, 200); 181 setSize(271,161); 182 Button but = new Button("Make Intermediate"); 183 but.addActionListener(new java.awt.event.ActionListener() { 184 public void actionPerformed(ActionEvent e) { 185 interDiag = new IntermediateDialog(StartFrame.this); 186 win_checkpoint[0] = new VisibilityValidator(interDiag); 187 interDiag.setSize(300, 200); 188 189 // may need listener to watch this move. 190 interDiag.setLocation(getLocationOnScreen()); 191 interDiag.pack(); 192 event_checkpoint[0].clear(); 193 interDiag.setVisible(true); // <--- thread stops here until the modal dialog is closed 194 } 195 }); 196 Panel pan = new Panel(); 197 pan.add(but); 198 add(pan); 199 robot_button[0] = but; 200 addWindowListener(new WindowAdapter() { 201 public void windowClosing(WindowEvent e) { 202 setVisible(false); 203 dispose(); 204 } 205 }); 206 } 207 208 } 209 210 ///////////////////////////// VARIOUS DIALOGS ////////////////////////////////// 211 212 213 /* A Dialog that launches a sub-dialog */ 214 class IntermediateDialog extends Dialog { 215 Dialog m_parent; 216 217 public IntermediateDialog(Frame parent) { 218 super(parent, "Intermediate Modal", true /*Modal*/); 219 m_parent = this; 220 Button but = new Button("Make Text"); 221 but.addActionListener(new java.awt.event.ActionListener() { 222 public void actionPerformed(ActionEvent e) { 223 txtDiag = new TextDialog(m_parent); 224 win_checkpoint[1] = new VisibilityValidator(txtDiag); 225 txtDiag.setSize(300, 100); 226 event_checkpoint[1].clear(); 227 txtDiag.setVisible(true); // <--- thread stops here until the modal dialog is closed 228 } 229 }); 230 Panel pan = new Panel(); 231 pan.add(but); 232 add(pan); 233 pack(); 234 addWindowListener(new WindowAdapter() { 235 public void windowClosing(WindowEvent e) { 236 setVisible(false); 237 dispose(); 238 } 239 }); 240 241 // The robot needs to know about us, so set global 242 robot_button[1] = but; 243 } 244 } 245 246 /* A Dialog that just holds a text field */ 247 class TextDialog extends Dialog { 248 public TextDialog(Dialog parent) { 249 super(parent, "Modeless Dialog", false /*Modeless*/); 250 TextField txt = new TextField("",10); 251 Panel pan = new Panel(); 252 pan.add(txt); 253 add(pan); 254 pack(); 255 addWindowListener(new WindowAdapter() { 256 public void windowClosing(WindowEvent e) { 257 setVisible(false); 258 dispose(); 259 } 260 }); 261 262 263 // The robot needs to know about us, so set global 264 robot_text = txt; 265 } 266 267 } 268 269 public static void main (String[] args) throws RuntimeException { 270 try { 271 TestResult tr = junit.textui.TestRunner.run(suite()); 272 273 int numErrors = tr.errorCount(); 274 if (numErrors != 0) { 275 Enumeration e = tr.errors(); 276 while (e.hasMoreElements()) { 277 System.out.println(e.nextElement()); 278 } 279 280 } 281 int numFailures = tr.failureCount(); 282 if (numFailures != 0) { 283 Enumeration e = tr.failures(); 284 while (e.hasMoreElements()) { 285 System.out.println(e.nextElement()); 286 } 287 } 288 if ((numErrors != 0) || (numFailures != 0)){ 289 throw new RuntimeException("Test encountered " + numErrors + " errors and " + numFailures + " failures."); 290 } 291 } 292 catch (Exception e) { 293 throw new RuntimeException(e.getMessage()); 294 } 295 } 296 } 297 298