Index: /gs3-extensions/testing/trunk/src/src/gstests/tutorials/RunGLITest.java
===================================================================
--- /gs3-extensions/testing/trunk/src/src/gstests/tutorials/RunGLITest.java	(revision 32713)
+++ /gs3-extensions/testing/trunk/src/src/gstests/tutorials/RunGLITest.java	(revision 32714)
@@ -2,4 +2,6 @@
 
 /*
+Ctrl+Shift+A TO ABORT A RUNNING GUI-TEST CYCLE (won't abort Selenium/browser tests)
+
 Using AssertJ Swing to do Java GUI testing (of swing classes)
 - Obtain from: https://search.maven.org/search?q=assertj-swing-junit
@@ -35,6 +37,8 @@
 // Junit imports
 import org.junit.AfterClass;
+import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
+import org.junit.BeforeClass;
 import org.junit.Test;
 
@@ -47,6 +51,5 @@
 import org.assertj.swing.junit.testcase.AssertJSwingJUnitTestCase;
 import org.assertj.swing.fixture.*;
-import org.assertj.swing.edt.GuiActionRunner;
-import org.assertj.swing.core.*;
+import org.assertj.swing.core.*; // Robot
 import org.assertj.swing.data.Index;
 
@@ -64,14 +67,14 @@
 import javax.swing.*;
 
-
-     
 // static imports
-import static org.assertj.swing.launcher.ApplicationLauncher.*;
-import static org.assertj.swing.finder.WindowFinder.findFrame;
-
 import static org.greenstone.gsdl3.testing.GSGUITestingUtil.*;
 
+/**
+ * Class that will eventually go through all the Greenstone3 tutorials by running GLI and GEMS.
+ */
 public class RunGLITest extends AssertJSwingJUnitTestCase {
-
+    // For aborting running test suite, with Ctrl+Shift+A by default
+    // https://joel-costigliola.github.io/assertj/assertj-swing-running.html
+    private static EmergencyAbortListener abortListener = EmergencyAbortListener.registerInToolkit();    
     private static WebDriver _driver = new FirefoxDriver(); // selenium
     
@@ -89,26 +92,17 @@
     }
     
+
+    // assertj-swing
+    // As init() above, onSetUp() gets called before every test method too,
+    // but is overridden from assertj-swing base class
     @Override
     protected void onSetUp() {
-	GathererProg frame = GuiActionRunner.execute(() -> new GathererProg());           
-	// IMPORTANT: note the call to 'robot()'
-	// we must use the Robot from AssertJSwingJUnitTestCase
+	// Launch GLI and then get a ref to the launched app window:
+	runGLI();
 	
-	//window = new FrameFixture(robot(), frame);
-	//window.show(); // shows the frame to test
 	
-	// Launch GathererProg.java's main() method
-	// See https://joel-costigliola.github.io/assertj/assertj-swing-launch.html
-	
-	String GSDLOS = System.getenv("GSDLOS");
-	String GSDLHOME = System.getenv("GSDLHOME");
-	String GSDL3HOME = System.getenv("GSDL3HOME");
-	String GSDL3SRCHOME = System.getenv("GSDL3SRCHOME");
-	application("org.greenstone.gatherer.GathererProg").withArgs(
-								 "-gsdl", GSDLHOME,
-								 "-gsdlos", GSDLOS,
-								 "-gsdl3", GSDL3HOME,
-								 "-gsdl3src", GSDL3SRCHOME,
-								 "-testing_mode").start();
+	// IMPORTANT, note the call to 'robot()': must use the Robot from AssertJSwingJUnitTestCase
+	//window = findFrame("GUIManager").using(robot());
+	window = GSGUITestingUtil.getGLIApplicationWindow(robot());
     }
     
@@ -117,8 +111,7 @@
   public void testGLIRunning() {
 
-      
+	
       // waiting a few seconds for window, so we can see it
-      PAUSE(2);
-      
+      PAUSE(2);      
     
       System.err.println("@@@ First test: GLI Running");
@@ -127,8 +120,5 @@
       String expectedWindowTitle = Gatherer.PROGRAM_NAME;
 
-      window = findFrame("GUIManager").using(robot());
-      
-      GSGUITestingUtil.setWindow(window); // set this first before calling any of Util's other methods
-      
+            
       String gatherPaneLabel = Dictionary.get("GUI.Gather");
       System.err.println("@@@ Expecting label: " + gatherPaneLabel);
@@ -168,8 +158,10 @@
       changeUserMode("expert");
       
-      PAUSE(5);
-      //exitGLI();
+      PAUSE(2);      
       
       switchToPane(GATHER_PANE);
+
+      //exitGLI(); //System.exit() on GLI won't allow quit to be called on Selenium's web _driver, why?
+      PAUSE(3);
   }
 
@@ -179,6 +171,6 @@
     public static void destroy()
     {
+	abortListener.unregister(); // aborting assertJ-swing GUI tests
 	_driver.quit();
-	
     }
 }
Index: /gs3-extensions/testing/trunk/src/src/org/greenstone/gsdl3/testing/GSGUITestingUtil.java
===================================================================
--- /gs3-extensions/testing/trunk/src/src/org/greenstone/gsdl3/testing/GSGUITestingUtil.java	(revision 32713)
+++ /gs3-extensions/testing/trunk/src/src/org/greenstone/gsdl3/testing/GSGUITestingUtil.java	(revision 32714)
@@ -16,4 +16,16 @@
 import org.greenstone.gatherer.GathererProg; // main GLI class we'll be testing
 import org.greenstone.gatherer.Dictionary; // access to display strings
+
+
+// Java GUI testing with AssertJ Swing
+import org.assertj.swing.junit.testcase.AssertJSwingJUnitTestCase;
+import org.assertj.swing.fixture.*;
+import org.assertj.swing.edt.GuiActionRunner;
+import org.assertj.swing.core.Robot;
+
+
+// static imports
+import static org.assertj.swing.launcher.ApplicationLauncher.*;
+import static org.assertj.swing.finder.WindowFinder.findFrame;
 
 /*
@@ -42,8 +54,5 @@
     // can have easier access to those GUI components when testing here through their names    
 
-    /************************ GENERAL *******************************/
-
-    public static void setWindow(FrameFixture w) { window = w; }
-    
+    /****************************** APPLICATION  *******************************/
     public static void PAUSE() {	
 	PAUSE(5);
@@ -58,6 +67,54 @@
 	     e.printStackTrace();
 	 }
-    }
-    
+    }    
+
+    //public static void setWindow(FrameFixture w) { window = w; } // if we want to null window
+    
+    public static void runGLI() {
+	//GathererProg frame = GuiActionRunner.execute(() -> new GathererProg());           
+	
+	// IMPORTANT, note the call to 'robot()': must use the Robot from AssertJSwingJUnitTestCase
+	//window = new FrameFixture(robot(), frame);
+	//window.show(); // shows the frame to test
+
+	// Instead, we'll be launching GLI and then getting a ref to the launched app window:
+      
+	// Launch GathererProg.java's main() method
+	// See https://joel-costigliola.github.io/assertj/assertj-swing-launch.html
+	
+	String GSDLOS = System.getenv("GSDLOS");
+	String GSDLHOME = System.getenv("GSDLHOME");
+	String GSDL3HOME = System.getenv("GSDL3HOME");
+	String GSDL3SRCHOME = System.getenv("GSDL3SRCHOME");
+	application("org.greenstone.gatherer.GathererProg").withArgs(
+								 "-gsdl", GSDLHOME,
+								 "-gsdlos", GSDLOS,
+								 "-gsdl3", GSDL3HOME,
+								 "-gsdl3src", GSDL3SRCHOME,
+								 "-testing_mode").start();
+	// The -testing_mode flag passed into GLI above is a special flag
+	// that calls GLI's TestingPreparating.setNamesRecursively()
+	// to help testing by calling setName() on GUI components.
+    }
+    
+    public static void exitGLI() {
+	openMenuItem("file", "exit");
+    }
+
+    // Gets a ref to the main window (FrameFixture) of a running GLI
+    public static FrameFixture getGLIApplicationWindow(Robot robot) {
+	// locate and set the internal FrameFixture member variable 'window' and return a handle to it
+	window = findFrame("GUIManager").using(robot); // GLI application JFrame's name is set to its classname, 'GUIManager'
+
+	// https://joel-costigliola.github.io/assertj/swing/api/index.html?org/assertj/swing/launcher/ApplicationLauncher.html
+	// "To change the speed of a GUI test, you need to change the values of both delayBetweenEvents and eventPostingDelay."
+	//robot.settings().delayBetweenEvents(50);
+	//robot.settings().eventPostingDelay(2*SECOND); // annoying, after every click!
+	
+	return window;
+    }
+    
+    /****************************** BASICS  *******************************/
+
     
     //https://joel-costigliola.github.io/assertj/swing/api/org/assertj/swing/fixture/FrameFixture.html
@@ -122,8 +179,4 @@
     }
 
-    public static void exitGLI() {
-	openMenuItem("file", "exit");
-	PAUSE(5);
-    }
     
     public static void closeCollection(){
@@ -315,4 +368,15 @@
     }
 
+
+    /********************* GEMS ******************/
+    
+    // TODO:
+    public static void runGEMS() {}
+    public static void exitGEMS() {}
+    public static FrameFixture getGEMSApplicationWindow(Robot robot) {
+	// TODO: don't forget to set internal member variable called 'window' before returning it
+	return window;
+    }
+    
     // Moving these working bits of code here, in case I can use them to right
     // general get methods that make use of the GenericTypeMatcher method of accessing components
