Package DisplayProject

Source Code of DisplayProject.DisplayProjectTestUtils

/*
Copyright (c) 2003-2009 ITerative Consulting Pty Ltd. All Rights Reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted
provided that the following conditions are met:

o Redistributions of source code must retain the above copyright notice, this list of conditions and
the following disclaimer.
 
o Redistributions in binary form must reproduce the above copyright notice, this list of conditions
and the following disclaimer in the documentation and/or other materials provided with the distribution.
   
o This jcTOOL Helper Class software, whether in binary or source form may not be used within,
or to derive, any other product without the specific prior written permission of the copyright holder

 
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


*/
package DisplayProject;

import java.awt.Frame;
import java.lang.Thread.State;
import java.util.Stack;

import javax.swing.JFrame;
import javax.swing.UnsupportedLookAndFeelException;

import net.helipilot50.stocktrade.displayproject.UIutils;
import net.helipilot50.stocktrade.displayproject.WindowManager;
import net.helipilot50.stocktrade.framework.EventManager;
import net.helipilot50.stocktrade.framework.ServiceObjectRegistry;
import net.helipilot50.stocktrade.framework.Task;

import org.fest.swing.core.BasicComponentFinder;
import org.fest.swing.core.ComponentFinder;
import org.fest.swing.core.Robot;
import org.fest.swing.core.matcher.FrameMatcher;
import org.fest.swing.exception.ComponentLookupException;
import org.fest.swing.fixture.FrameFixture;
import org.fest.swing.fixture.JButtonFixture;
import org.fest.swing.fixture.JTextComponentFixture;


public class DisplayProjectTestUtils {
  private static Stack<Thread> threads = new Stack<Thread>();
  private static Robot robot = null;
 
  /**
   * Find a frame with the passed name. Delays for up to 5 seconds looking for a frame. If the
   * mainThread has been set, then this method will wait until this thread is idle before starting
   * to look for the window.
   * @param finder
   * @param frameName
   * @return the found frame, or null if no matching frame can be found.
   */
  public static FrameFixture findFrameWithName(ComponentFinder finder, String frameName) {
    FrameFixture result = null;
    JFrame windowFrame = null;
    FrameFixture frameFixture = null;
   
    if (!threads.empty()) {
      waitForIdle();
    }
    for (int i = 0; i < 1000 && result == null; i++) {
      try {
        if (windowFrame == null) {
          windowFrame = (JFrame)finder.find(FrameMatcher.withName(frameName).andShowing());
        }
        if (frameFixture == null && windowFrame != null) {
          if (robot == null) {
            frameFixture = new FrameFixture(windowFrame);
            robot = frameFixture.robot;
          }
          else {
            frameFixture = new FrameFixture(robot, windowFrame);
          }
        }
        if (frameFixture == null || !frameFixture.target.isVisible()) {
          Task.delay(50);
          continue;
        }
        result = frameFixture;
      }
      catch (ComponentLookupException ignoreAndTryAgain) {
      }
      Task.delay(50);
    }
    if (result == null) {
      finder.find(FrameMatcher.withName(frameName));
    }
    return result;
  }
 
  /**
   * Find a frame with the passed title. Delays for up to 5 seconds looking for a frame. If the
   * mainThread has been set, then this method will wait until this thread is idle before starting
   * to look for the window.
   * @param finder
   * @param frameName
   * @return the found frame, or null if no matching frame can be found.
   */
  public static FrameFixture findFrameWithTitle(ComponentFinder finder, String frameName) {
    FrameFixture result = null;
    JFrame windowFrame = null;
    FrameFixture frameFixture = null;
   
    if (!threads.empty()) {
      waitForIdle();
    }
    for (int i = 0; i < 1000 && result == null; i++) {
      try {
        if (windowFrame == null) {
          windowFrame = (JFrame)finder.find(FrameMatcher.withTitle(frameName).andShowing());
        }
        if (frameFixture == null) {
          if (robot == null) {
            frameFixture = new FrameFixture(windowFrame);
            robot = frameFixture.robot;
          }
          else {
            frameFixture = new FrameFixture(robot, windowFrame);
          }
        }
        if (!frameFixture.target.isVisible()) {
          Task.delay(50);
          continue;
        }
        result = frameFixture;
      }
      catch (ComponentLookupException ignoreAndTryAgain) {
      }
      Task.delay(50);
    }
    if (result == null) {
      finder.find(FrameMatcher.withTitle(frameName));
    }
    return result;
  }
 
  /**
   * Find a synchronous child of the passed parent window with the passed name.
   * @param parentWin The parent window fixture
   * @param string the name of the window to find.
   * @return
   */
  public static FrameFixture findChildWithName(FrameFixture parentWin, String string) {
    FrameFixture result = null;
 
    if (!threads.empty()) {
      waitForIdle();
    }
    for (int i = 0; i < 1000 && result == null; i++) {
          Frame windowFrame = parentWin.robot.finder().find(FrameMatcher.withName(string).andShowing());
          if (windowFrame != null) {
            result = new FrameFixture(parentWin.robot, windowFrame);
            break;
          }
          Task.delay(50);
    }
    return result;
  }
 
  /**
   * Wait for the thread passed to be idle, that is waiting for events from the event manager. To satisfy this,
   * the thread must be WAITING and there can be no pending events on the event manager queue. The EDT is also
   * waited for (until it is idle) although due to the asynchronous nature of threads, there is no guarantee
   * that either the passed thread nor the EDT is idle when this method returns.
   * @param mainThread
   */
  public static void waitForIdle(Thread mainThread) {
    UIutils.waitForEDTToBeIdle();
    outerLoop:
      while (true) {
        if (!mainThread.isAlive()) {
          break;
        }
        else if (!EventManager.hasPendingEvents(mainThread) &&  mainThread.getState() == State.WAITING) {
          // The thread is waiting and it could be waiting for an event, so get the stack trace
          // and make sure it's waiting in the event manager.
          StackTraceElement[] elements = mainThread.getStackTrace();
          for (StackTraceElement element : elements) {
            if (element.getClassName().equals("java.lang.Object")) {
              continue;
            }
            else if (element.getClassName().indexOf("EventManager$ThreadData") >= 0) {
              // We're waiting inside the event manager, break out
              break outerLoop;
            }
            else {
              // The top of the call stack is neither the event manager nor object, so we're in
              // the wrong spot. We must break out now, otherwise we run the risk of the event
              // manager calling an even handler which gets blocked on a monitor. This would
              // satisfy all the other criteria except the depth within the call stack.
              continue outerLoop;
            }
          }
        }
        Task.delay(50);
      }
    UIutils.waitForEDTToBeIdle();
  }

  /**
   * Wait for the thread passed to be idle, that is waiting for events from the event manager. To satisfy this,
   * the thread must be WAITING and there can be no pending events on the event manager queue. The EDT is also
   * waited for (until it is idle) although due to the asynchronous nature of threads, there is no guarantee
   * that either the passed thread nor the EDT is idle when this method returns.
   * <p>
   * If the main thread has not been set, a NullPointerException is thrown.
   */
  public static void waitForIdle() {
    if (threads.empty()) {
      throw new NullPointerException("No thread has been pushed onto the stack");
    }
    waitForIdle(threads.peek());
  }
 
  /**
   * Return the thread at the top of the stack.
   * @return
   */
  public static Thread getTopThread() {
    return threads.peek();
  }
 
  public static Thread pushThreadForAsyncWindow(FrameFixture newWindow) {
    if (!threads.empty()) {
      waitForIdle();
    }
    Thread newThread = WindowManager.getOwningThread(newWindow.target);
    if (newThread != null) {
      threads.push(newThread);
      return newThread;
    }
    else {
      throw new NullPointerException("Cannot find a thread for window " + newWindow);
    }
  }
 
  public static void pushThread(Thread thread) {
    threads.push(thread);
  }
 
  public static Thread popThread() {
    return threads.pop();
  }
 
  /**
   * Start a new test case. This method create a new thread for a display loop, initialise the
   * GUI system and the service object registry appropriately and push the display loop thread
   * onto the stack of threads.
   * <p>
   * An example of how this method should be called is:
   * <p>
   * <pre>      finder = DisplayProjectTestUtils.initialiseNewThread(new Runnable() {
     *    public void run() {
     *      LogonWindow.launch();
     *    }
     *  });
   * </pre>
   * where <code>LogonWindow</code> is the main window being tested.
   * <p>
   * @param threadInitiated - This should contain the code to be executed in the new thread once
   * it has been initialised properly. Normally it is a simple call to the "launch" method of
   * the main window.
   * @return
   */
  public static ComponentFinder initialiseNewThread(final Runnable threadInitiated) {
    ComponentFinder finder = BasicComponentFinder.finderWithNewAwtHierarchy();
        // Lauch the "main" thread
        Thread mainThread = new Thread(new Runnable() {
            public void run() {
                if (!ServiceObjectRegistry.isConfigured()) {
                    ServiceObjectRegistry.setConfigFileName("client-config-local.xml");
                }
                try {
                    UIutils.initialiseGuiSystem();
                } catch (UnsupportedLookAndFeelException e) {
                    e.printStackTrace();
                }
                threadInitiated.run();
            }
        });
        pushThread(mainThread);
        mainThread.start();
        return finder;
  }

  public static JTextComponentFixture setTextValue(JTextComponentFixture fixture, String value) {
    fixture.focus();
    DisplayProjectTestUtils.waitForIdle();
    fixture.deleteText();
    DisplayProjectTestUtils.waitForIdle();
    fixture.enterText(value);
    DisplayProjectTestUtils.waitForIdle();
    return fixture;
  }

  public static JTextComponentFixture checkTextValue(JTextComponentFixture fixture, String value) {
    DisplayProjectTestUtils.waitForIdle();
    return fixture.requireText(value);
  }

  public static JButtonFixture clickButton(JButtonFixture button) {
    DisplayProjectTestUtils.waitForIdle();
    return button.click();
  }

  /**
   * This method should be called when an asynchonous or root thread has finished being used.
   * This will clean up all the resources associated with the robot on the thread (keyboard,
   * mouse and ScreenLock) and then remove the thread from the thread stack.
   * @param frame
   */
  public static void finishWithAsyncWindow() {
        // Finished with the async window, remove the thread.
        DisplayProjectTestUtils.popThread();
  }

}
TOP

Related Classes of DisplayProject.DisplayProjectTestUtils

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.