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 main NestedModalDialogTest 33 */ 34 35 /////////////////////////////////////////////////////////////////////////////////////// 36 // NestedModalDialogTest.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 second modal 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 second Nested Modal Dialog 41 ///////////////////////////////////////////////////////////////////////////////////// 42 43 // classes necessary for this test 44 import junit.framework.*; 45 46 import java.awt.*; 47 import java.awt.event.*; 48 import java.util.Enumeration; 49 50 import test.java.awt.regtesthelpers.RobotUtilities; 51 import test.java.awt.regtesthelpers.VisibilityValidator; 52 import test.java.awt.regtesthelpers.Waypoint; 53 54 55 public class NestedModalDialogTest extends TestCase { 56 57 public static Test suite() { 58 return new TestSuite(NestedModalDialogTest.class); 59 } 60 61 Waypoint[] event_checkpoint = new Waypoint[3]; 62 VisibilityValidator[] win_checkpoint = new VisibilityValidator[2]; 63 64 IntermediateDialog interDiag; 65 TextDialog txtDiag; 66 67 // Global variables so the robot thread can locate things. 68 Button[] robot_button = new Button[2]; 69 TextField robot_text = null; 70 71 /* 72 * @throws InterruptedException 73 * @throws WaypointException 74 */ 75 76 public void testModalDialogs() throws Exception { 77 Frame frame = null; 78 String result = ""; 79 80 event_checkpoint[0] = new Waypoint(); // "-Launch 1-" 81 event_checkpoint[1] = new Waypoint(); // "-Launch 2-" 82 83 try { 84 // Thread.currentThread().setName("NestedModalDialogTest Thread"); 85 // launch first frame with firstButton 86 frame = new StartFrame(); 87 VisibilityValidator.setVisibleAndConfirm(frame); 88 89 Thread.sleep(250); // shouldn't need this, but pause adds stability 90 RobotUtilities.click (robot_button[0]); 91 92 // Dialog must be created and onscreen before we proceed. 93 // The event_checkpoint waits for the Dialog to be created. 94 // The win_checkpoint waits for the Dialog to be visible. 95 96 event_checkpoint[0].requireClear("TestFrame actionPerformed() never called, see <rdar://problem/3429130>"); 97 Thread.sleep(250); // shouldn't need this, but pause adds stability 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 pause 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("IntermediateDialog actionPerformed() never called, see <rdar://problem/3429130>"); 110 Thread.sleep(250); // shouldn't need this, remove when 3429130 is addressed 111 112 win_checkpoint[1].requireVisible(); 113 assertTrue( "Could not confirm test dialog was visible", win_checkpoint[1].isValid() ); 114 115 Thread.sleep(250); // shouldn't need this, but pause adds stability 116 RobotUtilities.click(robot_text); 117 118 // I'm really not sure whether the click is needed for focus 119 // but since it's asynchronous, as is the actually gaining of focus 120 // we might as well do our best 121 Thread.sleep(250); // shouldn't need this, but pause adds stability 122 try { EventQueue.invokeAndWait(new Runnable() { public void run() {} }); } catch (Exception e) {} 123 124 RobotUtilities.pressKey(KeyEvent.VK_SHIFT); 125 RobotUtilities.typeKey(KeyEvent.VK_H); 126 RobotUtilities.releaseKey(KeyEvent.VK_SHIFT); 127 RobotUtilities.typeKey(KeyEvent.VK_E); 128 RobotUtilities.typeKey(KeyEvent.VK_L); 129 RobotUtilities.typeKey(KeyEvent.VK_L); 130 RobotUtilities.typeKey(KeyEvent.VK_O); 131 132 // 133 // NOTE THAT WE MAY HAVE MORE SYNCHRONIZATION WORK TO DO HERE. 134 // CURRENTLY THERE IS NO GUARANTEE THAT THE KEYEVENT THAT THAT 135 // TYPES THE 'O' HAS BEEN PROCESSED BEFORE WE GET THE RESULT 136 // 137 138 // This is a (lame) attempt at waiting for the last typeKey events to propagate 139 // It's not quite right because robot uses CGRemoteOperations, which are asynchronous 140 // But that's why I put in the pause 141 Thread.sleep(250); // shouldn't need this, but pause adds stability 142 try { EventQueue.invokeAndWait(new Runnable() { public void run() {} }); } catch (Exception e) {} 143 144 // We really need to call this before the dialog that robot_text is in is disposed 145 result = robot_text.getText(); 146 147 148 Thread.sleep(250); // shouldn't need this, but pause adds stability 149 RobotUtilities.clickAt(txtDiag, 14,10); // Click Close box of modal dialog with textField 150 151 Thread.sleep(250); // shouldn't need this, but pause 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 pause 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 ///////////////////////////// MODAL 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, "Modal Dialog", true /*Modal*/); 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