// Copyright 2013 SICK AG. All rights reserved. package de.sick.guicheck.fx; import java.lang.reflect.Method; import javafx.collections.ObservableList; import javafx.stage.Stage; import com.sun.javafx.stage.StageHelper; import de.sick.guicheck.GcAssertException; import de.sick.guicheck.GcException; import de.sick.guicheck.GcUtils; /** * Base class of all GUIcheck tests based on JavaFX. * * @author linggol (created) */ public abstract class GcTestFX { private static final int FIRST_STAGE_VISIBLE_TIMEOUT = 60000; /** * Starts the given main class with the given arguments using the classloader of the current thread. */ protected static final void startApp(final String clazz, final String... args) { startApp(Thread.currentThread().getContextClassLoader(), clazz, args); } /** * Starts the given main class with the given arguments using the given classloader. */ protected static final void startApp(ClassLoader loader, final String clazz, final String... args) { Thread l_thread = new Thread("GUIcheck-FX-Runner") { @Override public void run() { try { // Load the class and invoke the main method Class<?> l_clazz = Thread.currentThread().getContextClassLoader().loadClass(clazz); Method l_method = l_clazz.getMethod("main", String[].class); l_method.invoke(null, new Object[] {args}); } catch (Exception e) { throw new GcException("Failed to invoke main method", e); } } }; l_thread.setContextClassLoader(loader); l_thread.start(); // Wait for platform to start and the first stage to become visible long l_start = System.currentTimeMillis(); boolean l_initialized = false; while (System.currentTimeMillis() - l_start < FIRST_STAGE_VISIBLE_TIMEOUT) { if (GcUtilsFX.isPlatformAlive()) { ObservableList<Stage> l_stages = StageHelper.getStages(); if (l_stages.size() > 0 && l_stages.get(0).isShowing()) { l_initialized = true; GcUtilsFX.waitForIdle(); break; } GcUtilsFX.waitForIdle(); } } if (!l_initialized) { throw new GcException("The JavaFX platform did not initialize"); } } /** * Return the stage with the given title. * * @param titleRegEx <code>null</code> means the title is not set */ public static final GcStageFX stage(final String titleRegEx) { return GcUtilsFX.eval(new GcUtils.IEvaluator<GcStageFX>() { @Override public GcStageFX eval() { for (Stage l_stage : StageHelper.getStages()) { if (GcUtils.startsWithOrMatches(l_stage.getTitle(), titleRegEx)) { return new GcStageFX(l_stage); } } throw new GcAssertException("Cannot find stage with title: " + titleRegEx); } }); } /** * Return the stage with the given title. * * @param titleRegEx <code>null</code> means the title is not set * @param evalRetries the number of retries * @param evalDelay the time in milliseconds per retry */ public static final GcStageFX stage(final String titleRegEx, int evalRetries, int evalDelay) { return GcUtilsFX.eval(new GcUtils.IEvaluator<GcStageFX>() { @Override public GcStageFX eval() { for (Stage l_stage : StageHelper.getStages()) { if (GcUtils.startsWithOrMatches(l_stage.getTitle(), titleRegEx)) { return new GcStageFX(l_stage); } } throw new GcAssertException("Cannot find stage with title: " + titleRegEx); } }, evalRetries, evalDelay); } }