package jmri.jmrit.logix; import java.io.File; import java.util.ArrayList; import java.util.List; import jmri.*; import jmri.jmrit.display.controlPanelEditor.ControlPanelEditor; import jmri.util.*; import jmri.util.junit.annotations.DisabledIfHeadless; import org.junit.jupiter.api.*; import org.netbeans.jemmy.operators.*; import static org.junit.jupiter.api.Assertions.*; /** * Tests for the Warrant creation * * @author Pete Cressman 2015 * * todo - test error conditions */ public class LearnWarrantTest { private OBlockManager _OBlockMgr; @Test @DisabledIfHeadless public void testLearnWarrant() throws JmriException { WarrantPreferences.getDefault().setShutdown(WarrantPreferences.Shutdown.NO_MERGE); // load and display File f = new File("java/test/jmri/jmrit/logix/valid/LearnWarrantTest.xml"); /* This layout was designed so that the block and path will define a unique * route from origin to destination. i.e. the review and select route * never needs to be displayed. All possible EastBound Routes: * OB1/Main - OB5/main (default) Route {OB1, OB2, OB3, OB4, OB5} * OB1/WestSiding - OB5/Main Route {OB1, OB6, OB3, OB4, OB5} * OB1/Main - OB5/EastSiding Route {OB1, OB2, OB3, OB7, OB5} * OB1/WestSiding - OB5/EastSiding Route {OB1, OB6, OB3, OB7, OB5} * OB1/Main - OB7/EastSiding Route {OB1, OB2, OB3, OB7} * OB1/WestSiding - OB7/EastSiding Route {OB1, OB6, OB3, OB7} * OB1/Main - OB6/EastSiding Route {OB1, OB6} * OB1/WestSiding - OB6/EastSiding Route {OB1, OB6} */ assertTrue(InstanceManager.getDefault(ConfigureManager.class).load(f)); JUnitAppender.suppressErrorMessage("Portal elem = null"); _OBlockMgr = InstanceManager.getDefault(OBlockManager.class); WarrantFrame frame = ThreadingUtil.runOnGUIwithReturn(() -> { return new WarrantFrame(null, null); }); frame._origin.blockBox.setText("OB1"); frame._destination.blockBox.setText("OB5"); String[] route = {"OB1", "OB2", "OB3", "OB4", "OB5"}; JFrameOperator jfo = new JFrameOperator(frame); pressButton(jfo, Bundle.getMessage("Calculate")); JUnitUtil.waitFor(() -> (frame.getOrders() != null), "Found orders"); List orders = frame.getOrders(); assertEquals(5, orders.size(), "5 BlockOrders"); frame._speedUtil.setAddress("99"); frame.setTrainInfo("Student"); JUnitUtil.waitFor(() -> (frame._speedUtil.getDccAddress() != null), "Found address"); jmri.DccLocoAddress address = frame._speedUtil.getDccAddress(); assertEquals(99, address.getNumber(),"address=99"); pressButton(jfo, Bundle.getMessage("Start")); // dismiss warning "starting block not occupied confirmJOptionPane(jfo, Bundle.getMessage("WarningTitle"), "OK"); // occupy starting block final OBlock block0 = _OBlockMgr.getOBlock(route[0]); assertNotNull(block0); Sensor sensor = block0.getSensor(); NXFrameTest.setAndConfirmSensorAction(sensor, Sensor.ACTIVE, block0); JUnitUtil.waitFor(() -> oBlockOccupiedOrAllocated(block0), "Train occupies block "); pressButton(jfo, Bundle.getMessage("Start")); JFrameOperator learnThrottleFrame = new JFrameOperator("Student - 99(S)"); assertNotNull(frame._speedUtil.getThrottle(),"Throttle not found"); Sensor lastSensor = recordtimes(route, frame._speedUtil.getThrottle()); // After stopping train, wait a bit before pressing stop JUnitUtil.waitFor(100); // waitEmpty(100) causes a lot of failures on Travis GUI // new org.netbeans.jemmy.QueueTool().waitEmpty(100); pressButton(jfo, Bundle.getMessage("Stop")); JUnitUtil.waitFor(() -> (block0.getState() & OBlock.ALLOCATED) == 0, "Warrant deallocated"); // warrant has been recorded using engine 99 List list = frame.getThrottleCommands(); assertEquals(12, list.size(),"12 ThrottleCommands"); // now playback using engine 111 NXFrameTest.setAndConfirmSensorAction(lastSensor, Sensor.INACTIVE, _OBlockMgr.getOBlock(route[route.length-1])); // change address and run frame._speedUtil.setAddress("111"); frame.setTrainInfo("111"); JUnitUtil.waitFor(() -> (frame._speedUtil.getDccAddress() != null), "Found address"); address = frame._speedUtil.getDccAddress(); assertEquals(111, address.getNumber(),"address=111"); NXFrameTest.setAndConfirmSensorAction(sensor, Sensor.ACTIVE, block0); JUnitUtil.waitFor(() -> oBlockOccupiedOrAllocated(block0), "Train 111 occupies first block "); // (new JRadioButtonOperator(jfo,"ARun")).push(); // start play back jmri.util.ThreadingUtil.runOnGUIEventually(() -> {frame.runTrain();}); // confirmJOptionPane(jfo, Bundle.getMessage("WarningTitle"), "OK"); sensor = NXFrameTest.runtimes(route, _OBlockMgr); assertNotNull(sensor,"Sensor not null"); final OBlock block4 = _OBlockMgr.getOBlock(route[4]); assertNotNull(block4); sensor = block4.getSensor(); NXFrameTest.setAndConfirmSensorAction(sensor, Sensor.ACTIVE, block4); JUnitUtil.waitFor(() -> oBlockOccupiedOrAllocated(block4), "Train 111 occupies last block "); JLabelOperator jlo = new JLabelOperator(jfo, Bundle.getMessage("LabelUserName")); ((javax.swing.JTextField) jlo.getLabelFor()).setText("SavedIt"); pressButton(jfo, Bundle.getMessage("ButtonSave")); WarrantTableFrame tableFrame = WarrantTableFrame.getDefault(); assertNotNull(tableFrame,"Warrant Table save"); // passed test - cleanup. Do it here so failure leaves traces. ControlPanelEditor panel = (ControlPanelEditor)jmri.util.JmriJFrame.getFrame("LearnWarrantTest"); Assertions.assertNotNull(panel); learnThrottleFrame.requestClose(); learnThrottleFrame.waitClosed(); // disposing this way allows test to be rerun (i.e. reload panel file) multiple times Boolean retVal = ThreadingUtil.runOnGUIwithReturn(() -> { panel.dispose(); tableFrame.dispose(); frame.dispose(); return true; }); assertTrue(retVal); } private boolean oBlockOccupiedOrAllocated(OBlock b){ return (b.getState() & (OBlock.ALLOCATED | OBlock.OCCUPIED)) != 0; } private void pressButton(WindowOperator frame, String text) { JButtonOperator jbo = new JButtonOperator(frame,text); jbo.push(); } private void confirmJOptionPane(WindowOperator wo, String title, String buttonLabel) { // the previous version of this message verified the text string // in the dialog matched the passed message value. We need to // determine how to do that using Jemmy. JDialogOperator jdo = new JDialogOperator(wo, title); JButtonOperator jbo = new JButtonOperator(jdo, buttonLabel); jbo.push(); } /** * @param route Array of OBlock names * @param throttle assigned to run the train * @return Active end sensor */ private Sensor recordtimes(String[] route, DccThrottle throttle) { JUnitUtil.waitFor(100); // waitEmpty(100) causes a lot of failures on Travis GUI // new org.netbeans.jemmy.QueueTool().waitEmpty(100); float speed = 0.1f; assertNotNull( throttle, "recordtimes: No Throttle"); throttle.setSpeedSetting(speed); OBlock block = _OBlockMgr.getBySystemName(route[0]); assertNotNull(block); Sensor sensor = block.getSensor(); for (int i=1; i list = new ArrayList<>(); ShutDownManager sm = InstanceManager.getDefault( ShutDownManager.class); for (Runnable r : sm.getRunnables()) { if (r instanceof jmri.jmrit.logix.WarrantShutdownTask) { list.add((ShutDownTask)r); } } for ( ShutDownTask t : list) { sm.deregister(t); } } JUnitUtil.deregisterBlockManagerShutdownTask(); JUnitUtil.tearDown(); } }