source: gs3-extensions/testing/trunk/src/src/org/greenstone/gsdl3/testing/GSGUITestingUtil.java@ 32714

Last change on this file since 32714 was 32714, checked in by ak19, 5 years ago
  1. window (the main app windows of running GLI, or later GEMS) is now instantiated and a handle kept to it inside GSGUITestingUtil after all. The test class now calls GSGUITestingUtil.runGLI() followed by getApplicationWindow() to launch GLI and get a hold of its window and then sets its own private reference to it. 2. Added an abort listener to stop the running test suite on assertj-swing's default abort key combination of Ctrl+Shift+A. 3. More cleaning up.
File size: 15.8 KB
Line 
1package org.greenstone.gsdl3.testing;
2
3import java.io.File;
4import java.util.Map;
5import java.util.regex.*;
6import java.awt.Component;
7
8// only JUnit and JAssert-Swing, no Selenium in this class
9import org.junit.Assert;
10import org.assertj.swing.fixture.*;
11import org.assertj.swing.timing.Timeout ;
12
13
14// GLI imports
15import org.greenstone.gatherer.Gatherer;
16import org.greenstone.gatherer.GathererProg; // main GLI class we'll be testing
17import org.greenstone.gatherer.Dictionary; // access to display strings
18
19
20// Java GUI testing with AssertJ Swing
21import org.assertj.swing.junit.testcase.AssertJSwingJUnitTestCase;
22import org.assertj.swing.fixture.*;
23import org.assertj.swing.edt.GuiActionRunner;
24import org.assertj.swing.core.Robot;
25
26
27// static imports
28import static org.assertj.swing.launcher.ApplicationLauncher.*;
29import static org.assertj.swing.finder.WindowFinder.findFrame;
30
31/*
32 * Utility class containing helper functions for GLI GUI testing using AsssertJ Swing
33*/
34
35public class GSGUITestingUtil
36{
37 public static FrameFixture window = null;
38
39 public static final boolean PAUSE_ON = true;
40
41 public static final int SECOND = 1000; // 1000 ms
42
43 public static final String DOWNLOAD_PANE = "Download";
44 public static final String GATHER_PANE = "Gather";
45 public static final String ENRICH_PANE = "Enrich";
46 public static final String DESIGN_PANE = "Design";
47 public static final String CREATE_PANE = "Create";
48 public static final String FORMAT_PANE = "Format";
49
50
51 /************** NEEDED FOR TESTING *************/
52 // There's now a new method in GLI: GUIManager.setNamesRecursively()
53 // that attempts to recursively call setName() on visible GUI components so that we
54 // can have easier access to those GUI components when testing here through their names
55
56 /****************************** APPLICATION *******************************/
57 public static void PAUSE() {
58 PAUSE(5);
59 }
60 public static void PAUSE(int seconds) {
61 if(!PAUSE_ON) return; // ignore calls to PAUSE
62
63 // wait a couple of seconds again?
64 try{
65 Thread.sleep(seconds*SECOND);
66 } catch(Exception e) {
67 e.printStackTrace();
68 }
69 }
70
71 //public static void setWindow(FrameFixture w) { window = w; } // if we want to null window
72
73 public static void runGLI() {
74 //GathererProg frame = GuiActionRunner.execute(() -> new GathererProg());
75
76 // IMPORTANT, note the call to 'robot()': must use the Robot from AssertJSwingJUnitTestCase
77 //window = new FrameFixture(robot(), frame);
78 //window.show(); // shows the frame to test
79
80 // Instead, we'll be launching GLI and then getting a ref to the launched app window:
81
82 // Launch GathererProg.java's main() method
83 // See https://joel-costigliola.github.io/assertj/assertj-swing-launch.html
84
85 String GSDLOS = System.getenv("GSDLOS");
86 String GSDLHOME = System.getenv("GSDLHOME");
87 String GSDL3HOME = System.getenv("GSDL3HOME");
88 String GSDL3SRCHOME = System.getenv("GSDL3SRCHOME");
89 application("org.greenstone.gatherer.GathererProg").withArgs(
90 "-gsdl", GSDLHOME,
91 "-gsdlos", GSDLOS,
92 "-gsdl3", GSDL3HOME,
93 "-gsdl3src", GSDL3SRCHOME,
94 "-testing_mode").start();
95 // The -testing_mode flag passed into GLI above is a special flag
96 // that calls GLI's TestingPreparating.setNamesRecursively()
97 // to help testing by calling setName() on GUI components.
98 }
99
100 public static void exitGLI() {
101 openMenuItem("file", "exit");
102 }
103
104 // Gets a ref to the main window (FrameFixture) of a running GLI
105 public static FrameFixture getGLIApplicationWindow(Robot robot) {
106 // locate and set the internal FrameFixture member variable 'window' and return a handle to it
107 window = findFrame("GUIManager").using(robot); // GLI application JFrame's name is set to its classname, 'GUIManager'
108
109 // https://joel-costigliola.github.io/assertj/swing/api/index.html?org/assertj/swing/launcher/ApplicationLauncher.html
110 // "To change the speed of a GUI test, you need to change the values of both delayBetweenEvents and eventPostingDelay."
111 //robot.settings().delayBetweenEvents(50);
112 //robot.settings().eventPostingDelay(2*SECOND); // annoying, after every click!
113
114 return window;
115 }
116
117 /****************************** BASICS *******************************/
118
119
120 //https://joel-costigliola.github.io/assertj/swing/api/org/assertj/swing/fixture/FrameFixture.html
121 public static void switchToPane(String pane) {
122 String paneLabel = Dictionary.get("GUI." + pane); // e.g. GUI.Enrich
123 //JPanelFixture tab = window.panel(pane); // this just gets us the JPanel of controls within
124 JTabbedPaneFixture tab = window.tabbedPane("GUIManager.tab_pane");
125 tab.selectTab(paneLabel); // select tab by its title
126 }
127 public static void openMenuItem(String menu, String subMenu) {
128 /*String menuLabel = Dictionary.get("Menu." + menu); // e.g. Menu.File
129 window.menuItem(menuLabel).click(); //JMenuItemFixture.click()
130 String subMenuLabel = Dictionary.get(menuLabel + "_" + subMenu); // e.g. Menu.File_Open
131 window.menuItem(subMenuLabel).click();*/
132 window.menuItem("MenuBar."+menu).click();
133 window.menuItem("MenuBar."+menu+"_"+subMenu).click();
134 }
135
136 /*
137 public static void stealAnyLock() {
138 DialogFixture dialog = window.dialog("LockFileDialog");
139 if(dialog != null) {
140 dialog.button("LockFileDialog.ok_button").click();
141 }
142 }*/
143
144
145 // e.g. pane = Enrich,view=collection; pane = Gather, view = workspace (or collection)
146 public static void getFolderPath(String pane, String view, String folderPath) {}
147 public static void getFilePath(String pane, String view, String filePath) {}
148
149 /**********************FILE MENU*******************************/
150 public static void setPrefs(String tab, Map params) {
151 openMenuItem("file", "options");
152
153 }
154
155 /**
156 * @param toMode must be the dictionary key for Preferences mode.
157 * Choose from Preferences.Mode.Assistant, Preferences.Mode.Librarian, Preferences.Mode.Expert
158 */
159 public static void changeUserMode(String toMode) {
160 openMenuItem("file", "options"); // click MenuBar.file -> MenuBar.file_options
161
162 // switch to Mode tab
163 String paneLabel = Dictionary.get("Preferences.Mode");
164 DialogFixture dialog = window.dialog("Preferences");
165 JTabbedPaneFixture tab = window.tabbedPane("Preferences.tab_pane");
166 tab.selectTab(paneLabel); // select tab by its title
167
168 String mode = "assistant"; // library assistant
169 if(toMode.contains("xpert")) {
170 mode = "expert";
171 } else if (toMode.endsWith("ibrarian")) {
172 mode = "librarian";
173 }
174 dialog.radioButton("Preferences."+mode+"_mode_radio_button").check(true);
175
176 // apply and close dialog
177 dialog.button("Preferences.apply_button").click();
178 dialog.button("Preferences.ok_button").click();
179 }
180
181
182 public static void closeCollection(){
183 // Through componennt names, clicks on MenuBar.file then MenuBar.file_close
184 openMenuItem("file", "close");
185 }
186
187 public static void deleteCollection(String collName) {
188 openMenuItem("file", "delete");
189 DialogFixture dialog = window.dialog("DeleteCollectionPrompt"); // could call window.dialg() too as there will be only one, unless GLI run in debug mode?
190
191 JListFixture collection_list = dialog.list("DeleteCollectionPrompt.list");
192
193 Pattern collNameRegex = Pattern.compile(".*"+collName+".*");
194 collection_list.selectItem(collNameRegex);
195
196 collection_list.requireSelection(collNameRegex); // assert it exists and is selectable. Can't select (or delete) coll if it's open
197
198 dialog.checkBox("DeleteCollectionPrompt.confirmation").check(true); // check checkbox to be sure to delete
199 dialog.button("DeleteCollectionPrompt.ok_button").click(); // delete button
200
201 // A close confirmation optionPane dialog appears - click OK in it
202 dialog.optionPane().okButton().click();
203
204 dialog.button("DeleteCollectionPrompt.close_button").click(); // close deleteColl dialog
205 }
206
207 public static void saveCollection() {
208 openMenuItem("file", "save"); // MenuBar.file -> MenuBar.file_save
209 }
210
211 public static void createCollection(String collTitle, String collDescription, String baseColl)
212 {
213 openMenuItem("file", "new");
214 DialogFixture dialog = window.dialog("col"); // GLI is unable to setName() of this dialog
215 // to NewCollectioNDetailsPrompt. Not sure why.
216
217 dialog.textBox("NewCollectionDetailsPrompt.title").enterText(collTitle); // JTextField
218 if(collDescription != null && !collDescription.equals("")) {
219 // JTextArea description
220 dialog.textBox("NewCollectionDetailsPrompt.description").enterText(collDescription);
221 }
222
223 // JComboBox base_collection
224 if(baseColl != null && !baseColl.equals("")) {
225 JComboBoxFixture baseCollBox = dialog.comboBox("NewCollectionDetailsPrompt.base_collection");
226 Pattern collNameRegex = Pattern.compile(".*"+baseColl+".*"); // comboBox should CONTAIN this string
227 baseCollBox.selectItem(collNameRegex);
228 baseCollBox.requireSelection(collNameRegex); // assert the baseColl name exists
229 }
230 dialog.button("NewCollectionDetailsPrompt.create_button").click();
231 }
232
233 public static void loadCollection(String collName) {
234 openMenuItem("file", "open");
235 DialogFixture dialog = window.dialog("OpenCollectionDialog");
236 JListFixture collection_list = dialog.list("OpenCollectionDialog.collection_list");
237
238 // See section 4.2 of http://www.vogella.com/tutorials/JavaRegularExpressions/article.html
239 // Apparently, testing Pattern "collName" expects it to match in entirety
240 // whereas testing ".*collName.*" will test the string contains this Pattern
241 Pattern collNameRegex = Pattern.compile(".*"+collName+".*");
242
243 /*String[] items = collection_list.contents();
244 for(String item : items) {
245 System.err.println("@@@ ITEM: " + item);
246 }*/
247
248
249 //JListItemFixture collItem = collection_list.item(collNameRegex);
250 //collItem.click();
251 //collection_list.requireSelection(collNameRegex); // assert that the requested collection exists
252 //collItem.doubleClick();
253 collection_list.selectItem(collNameRegex);
254 collection_list.requireSelection(collNameRegex); // assert that the requested collection exists
255
256
257 /*String[] selections = collection_list.selection();
258 for(String s : selections) {
259 System.err.println("@@@ opening collection " + s);
260 }*/
261
262 JListItemFixture selectedColl = collection_list.item(collNameRegex);
263 //collection_list.doubleClick(); // will double-click on last item regardless of what's selected
264 selectedColl.doubleClick();
265
266 //steal any lock
267 /*
268 DialogFixture dialog = window.dialog("LockFileDialog");
269 if(dialog != null) {
270 dialog.button("LockFileDialog.ok_button").click();
271 }
272 */
273 }
274
275 /**
276 * @param exportColl has to be internal GS collection name, e.g. lucene-jdbm-demo
277 * not public collection name like "Demo Collection".
278 */
279 public static void exportCollection(String exportToFormat, String exportColl)
280 {
281 openMenuItem("file", "exportas"); // Clicks MenuBar.file -> MenuBar.file_exportas
282
283 DialogFixture dialog = window.dialog("ExportAsPrompt");
284 dialog.comboBox("ExportAsPrompt.saveas_combobox").selectItem(exportToFormat);
285
286 Pattern collNameRegex = Pattern.compile(".*"+exportColl+".*");
287 JListFixture collection_list = dialog.list("ExportAsPrompt.list");
288 collection_list.selectItem(collNameRegex); //JList of collections
289 collection_list.requireSelection(collNameRegex); // check it exists
290
291 dialog.button("ExportAsPrompt.ok_button").click(); // do export
292
293 // first we see a progress dialog
294
295 // Wait for subsequent export complete dialog
296 DialogFixture exportCompleteDialog = window.dialog("SimpleResultDialog", Timeout.timeout(30*SECOND));
297
298 // non-modal dialog, so give it focus, so we can close it through its Close button
299 exportCompleteDialog.focus();
300
301 //exportCompleteDialog.button().click();
302 exportCompleteDialog.button("SimpleResultDialog.GLIButton."+Dictionary.get("General.Close")).click(); // it only has a single button: "Close", still want to future proof if more buttons get added by specifying the particular button
303
304
305 // Close outer dialog too - cancel doubles as close button now that export is complete
306 dialog.button("ExportAsPrompt.cancel_button").click();
307
308 File file = new File(System.getenv("GSDLHOME") + File.separator + "tmp" + File.separator + "exported_"+exportColl+"_"+exportToFormat);
309
310 Assert.assertTrue(file.exists());
311 Assert.assertTrue(file.isDirectory());
312 }
313
314 /*************** DESIGN ******************************/
315 public static void changeIndexer(String toIndexer) {}
316 public static void changeDB(String toDB) {}
317
318 public static void configurePartitionIndex(String tab, Map params) {}
319
320 public static void configurePlugin(String pluginName, Map params) {
321 }
322
323 public static void configureClassifier(String classifierName, Map params) {}
324
325 public static void configurePlugout(String plugoutName, Map params) {}
326
327 // https://www.journaldev.com/1257/java-varargs
328 // https://www.geeksforgeeks.org/variable-arguments-varargs-in-java/
329 public static void keepOnlyPlugins(String ... plug_n) {}
330
331 public static void removePlugs(String ... plug_n) {}
332
333 /********************** CREATE PANEL ********************/
334 public static void buildOpenCollection() {}
335 public static void buildOpenCollection(boolean minimalRebuild) {}
336 public static void configureImportOptions(Map params) {}
337 public static void configureBuildOptions(Map params) {}
338
339 public static void buildOutputContains(String ... n) {}
340
341 /******************** GATHER PANE ********************/
342 public static void createWorkspaceShortcut(){}
343
344 // in current open collection
345 public static void createCollectionSubfolder() {}
346
347 public static void dragNDrop(String workspacePath, String collPath) {}
348
349 /********************* ENRICH PANE ******************/
350 // docPath can be just docName or collectionSubfolder/Subfolder2/docName
351 public static void addMeta(String docPath, Map metanamesToValues) {}
352 public static void addFolderLevelMeta(String folderPath, Map metanamesToValues) {}
353
354 /********************* DOWNLOAD PANE ******************/
355 // TODO: more functions needed here: e.g. serverInfo?
356 public static void download(String downloader, Map params) {}
357 public static void clearCache() {}
358 public static String serverInfo() {
359 return "";
360 }
361
362 /********************* DOWNLOAD PANE ******************/
363 public static void formatGeneral(){}
364 public static void formatSearch() {}
365 public static void formatFeature(String featureName, String filename) {}
366 public static boolean isFormatFeatureXMLValid() {
367 return true;
368 }
369
370
371 /********************* GEMS ******************/
372
373 // TODO:
374 public static void runGEMS() {}
375 public static void exitGEMS() {}
376 public static FrameFixture getGEMSApplicationWindow(Robot robot) {
377 // TODO: don't forget to set internal member variable called 'window' before returning it
378 return window;
379 }
380
381 // Moving these working bits of code here, in case I can use them to right
382 // general get methods that make use of the GenericTypeMatcher method of accessing components
383 // See https://joel-costigliola.github.io/assertj/assertj-swing-lookup.html
384
385 /*window = findFrame(new GenericTypeMatcher<JFrame>(JFrame.class) {
386 protected boolean isMatching(JFrame window) {
387 return window.getTitle().trim().startsWith(expectedWindowTitle)
388 && window.isShowing();
389 }
390 }).using(robot());
391 */
392 /*
393 JTabbedPaneFixture tab = window.tabbedPane(new GenericTypeMatcher<JTabbedPane>(JTabbedPane.class) {
394 @Override protected boolean isMatching(JTabbedPane tabPane) {
395 System.err.println("### trying for match");
396 //int index = GuiActionRunner.execute(() -> tabPane.getSelectedIndex());
397 int index = tabPane.getSelectedIndex();
398 String selectedTabTitle = tabPane.getTitleAt(index); //GuiActionRunner.execute(() -> tabPane.getTitleAt(index));
399 System.err.println("### GOT TITLE: " + selectedTabTitle);
400 return gatherPaneLabel.equals(selectedTabTitle);
401 }
402 });
403 */
404}
Note: See TracBrowser for help on using the repository browser.