LCOV - code coverage report
Current view: top level - src/utils/tests - InternalTestStep.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 0.0 % 1716 0
Test Date: 2026-03-02 16:00:03 Functions: 0.0 % 133 0

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2001-2026 German Aerospace Center (DLR) and others.
       4              : // This program and the accompanying materials are made available under the
       5              : // terms of the Eclipse Public License 2.0 which is available at
       6              : // https://www.eclipse.org/legal/epl-2.0/
       7              : // This Source Code may also be made available under the following Secondary
       8              : // Licenses when the conditions for such availability set forth in the Eclipse
       9              : // Public License 2.0 are satisfied: GNU General Public License, version 2
      10              : // or later which is available at
      11              : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
      12              : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
      13              : /****************************************************************************/
      14              : /// @file    InternalTestStep.cpp
      15              : /// @author  Pablo Alvarez Lopez
      16              : /// @date    Mar 2025
      17              : ///
      18              : // Single operation used in InternalTests
      19              : /****************************************************************************/
      20              : #include <config.h>
      21              : 
      22              : #include <fxkeys.h>
      23              : 
      24              : #include <utils/gui/windows/GUIAppEnum.h>
      25              : #include <utils/gui/windows/GUISUMOAbstractView.h>
      26              : 
      27              : #include "InternalTestStep.h"
      28              : 
      29              : // ===========================================================================
      30              : // static member definitions
      31              : // ===========================================================================
      32              : 
      33              : // this offsets corresponds to the offset of the test magenta square
      34              : constexpr int MOUSE_OFFSET_X = 24;
      35              : constexpr int MOUSE_OFFSET_Y = 25;
      36              : constexpr int MOUSE_REFERENCE_X = 304;
      37              : constexpr int MOUSE_REFERENCE_Y = 168;
      38              : 
      39              : // ===========================================================================
      40              : // member method definitions
      41              : // ===========================================================================
      42              : 
      43              : // ---------------------------------------------------------------------------
      44              : // InternalTestStep::DialogArgument - public methods
      45              : // ---------------------------------------------------------------------------
      46              : 
      47            0 : InternalTestStep::DialogArgument::DialogArgument(DialogType type, Action action) :
      48            0 :     myType(type),
      49            0 :     myAction(action) {
      50            0 : }
      51              : 
      52              : 
      53            0 : InternalTestStep::DialogArgument::DialogArgument(DialogType type, const std::string& customAction) :
      54            0 :     myType(type),
      55            0 :     myAction(InternalTestStep::DialogArgument::Action::CUSTOM),
      56            0 :     myCustomAction(customAction) {
      57            0 : }
      58              : 
      59              : 
      60            0 : InternalTestStep::DialogArgument::DialogArgument(DialogType type, const std::string& customAction, const int index) :
      61            0 :     myType(type),
      62            0 :     myAction(InternalTestStep::DialogArgument::Action::CUSTOM),
      63            0 :     myCustomAction(customAction),
      64            0 :     myIndex(index) {
      65            0 : }
      66              : 
      67              : 
      68            0 : InternalTestStep::DialogArgument::DialogArgument(DialogType type, const std::string& prefixToRemove, const std::string& customAction) :
      69            0 :     myType(type),
      70            0 :     myAction(InternalTestStep::DialogArgument::Action::CUSTOM),
      71            0 :     myCustomAction(customAction) {
      72              :     // remove prefix from custom action
      73            0 :     if (prefixToRemove.size() > 0) {
      74              :         const auto pos = customAction.find(prefixToRemove);
      75            0 :         if (pos != std::string::npos) {
      76            0 :             myCustomAction.erase(pos, prefixToRemove.length());
      77              :         }
      78              :     }
      79            0 : }
      80              : 
      81              : 
      82              : DialogType
      83            0 : InternalTestStep::DialogArgument::getType() const {
      84            0 :     return myType;
      85              : }
      86              : 
      87              : 
      88              : InternalTestStep::DialogArgument::Action
      89            0 : InternalTestStep::DialogArgument::getAction() const {
      90            0 :     return myAction;
      91              : }
      92              : 
      93              : 
      94              : const std::string&
      95            0 : InternalTestStep::DialogArgument::getCustomAction() const {
      96            0 :     return myCustomAction;
      97              : }
      98              : 
      99              : 
     100              : int
     101            0 : InternalTestStep::DialogArgument::getIndex() const {
     102            0 :     return myIndex;
     103              : }
     104              : 
     105              : // ---------------------------------------------------------------------------
     106              : // InternalTestStep::TLSTableTest - public methods
     107              : // ---------------------------------------------------------------------------
     108              : 
     109            0 : InternalTestStep::TLSTableTest::TLSTableTest(FXSelector sel_, const int row_) :
     110            0 :     sel(sel_),
     111            0 :     row(row_) {
     112            0 : }
     113              : 
     114              : 
     115            0 : InternalTestStep::TLSTableTest::TLSTableTest(FXSelector sel_, const int row_, const int column_, const std::string& text_) :
     116            0 :     sel(sel_),
     117            0 :     row(row_),
     118            0 :     column(column_),
     119            0 :     text(text_) {
     120            0 : }
     121              : 
     122              : // ---------------------------------------------------------------------------
     123              : // InternalTestStep - public methods
     124              : // ---------------------------------------------------------------------------
     125              : 
     126            0 : InternalTestStep::InternalTestStep(InternalTest* testSystem, const std::string& step) :
     127            0 :     myTestSystem(testSystem) {
     128              :     // add this testStep to test system
     129            0 :     testSystem->addTestSteps(this);
     130              :     // get overlapped tabs
     131            0 :     const int overlappedTabs = myTestSystem->getAttributesEnum().at("netedit.attrs.editElements.overlapped");
     132              :     // parse step
     133            0 :     const auto function = parseStep(step);
     134              :     // set description based in function
     135            0 :     myDescription = "Process function: " + function;
     136              :     // continue depending of function
     137            0 :     if (function == "setupAndStart") {
     138            0 :         setupAndStart();
     139            0 :     } else if (function == "finish") {
     140            0 :         finish();
     141            0 :     } else if ((function == "leftClick") || (function == "leftClickData")) {
     142            0 :         mouseClick("left", "");
     143            0 :     } else if (function == "leftClickControl") {
     144            0 :         mouseClick("left", "control");
     145            0 :     } else if (function == "leftClickShift") {
     146            0 :         mouseClick("left", "shift");
     147            0 :     } else if (function == "rightClick") {
     148            0 :         mouseClick("right", "");
     149            0 :     } else if (function == "rightClickControl") {
     150            0 :         mouseClick("right", "control");
     151            0 :     } else if (function == "rightClickShift") {
     152            0 :         mouseClick("right", "shift");
     153            0 :     } else if (function == "leftClickOffset") {
     154            0 :         leftClickOffset("left");
     155            0 :     } else if (function == "typeKey") {
     156            0 :         typeKey();
     157            0 :     } else if (function == "moveElementHorizontal") {
     158            0 :         moveElementHorizontal();
     159            0 :     } else if (function == "moveElementVertical") {
     160            0 :         moveElementVertical();
     161            0 :     } else if (function == "moveElement") {
     162            0 :         moveElement();
     163            0 :     } else if (function == "focusOnFrame") {
     164            0 :         focusOnFrame();
     165            0 :     } else if (function == "contextualMenuOperation") {
     166            0 :         contextualMenuOperation();
     167            0 :     } else if (function == "protectElements") {
     168            0 :         protectElements();
     169            0 :     } else if (function == "waitDeleteWarning") {
     170            0 :         waitDeleteWarning();
     171            0 :     } else if (function == "modifyAttribute") {
     172            0 :         modifyAttribute(0);
     173            0 :     } else if (function == "modifyAttributeOverlapped") {
     174            0 :         modifyAttribute(overlappedTabs);
     175            0 :     } else if (function == "modifyBoolAttribute") {
     176            0 :         modifyBoolAttribute(0);
     177            0 :     } else if (function == "modifyBoolAttributeOverlapped") {
     178            0 :         modifyBoolAttribute(overlappedTabs);
     179            0 :     } else if (function == "modifyColorAttribute") {
     180            0 :         modifyColorAttribute(0);
     181            0 :     } else if (function == "modifyColorAttributeOverlapped") {
     182            0 :         modifyColorAttribute(overlappedTabs);
     183            0 :     } else if (function == "modifyVClassDialog_NoDisallowAll") {
     184            0 :         modifyVClassDialog_NoDisallowAll(0);
     185            0 :     } else if (function == "modifyVClassDialogOverlapped_NoDisallowAll") {
     186            0 :         modifyVClassDialog_NoDisallowAll(overlappedTabs);
     187            0 :     } else if (function == "modifyVClassDialog_DisallowAll") {
     188            0 :         modifyVClassDialog_DisallowAll(0);
     189            0 :     } else if (function == "modifyVClassDialogOverlapped_DisallowAll") {
     190            0 :         modifyVClassDialog_DisallowAll(overlappedTabs);
     191            0 :     } else if (function == "modifyVClassDialog_Cancel") {
     192            0 :         modifyVClassDialog_Cancel(0);
     193            0 :     } else if (function == "modifyVClassDialogOverlapped_Cancel") {
     194            0 :         modifyVClassDialog_Cancel(overlappedTabs);
     195            0 :     } else if (function == "modifyVClassDialog_Reset") {
     196            0 :         modifyVClassDialog_Reset(0);
     197            0 :     } else if (function == "modifyVClassDialogOverlapped_Reset") {
     198            0 :         modifyVClassDialog_Reset(overlappedTabs);
     199            0 :     } else if (function == "modifyVTypeDialogAttribute") {
     200            0 :         modifyVTypeDialogAttribute();
     201            0 :     } else if (function == "createConnection") {
     202            0 :         createConnection("");
     203            0 :     } else if (function == "createCrossing") {
     204            0 :         createCrossing();
     205            0 :     } else if (function == "modifyCrossingDefaultValue") {
     206            0 :         modifyCrossingDefaultValue();
     207            0 :     } else if (function == "modifyCrossingDefaultBoolValue") {
     208            0 :         modifyCrossingDefaultBoolValue();
     209            0 :     } else if (function == "crossingClearEdges") {
     210            0 :         crossingClearEdges();
     211            0 :     } else if (function == "crossingInvertEdges") {
     212            0 :         crossingInvertEdges();
     213            0 :     } else if (function == "createConnectionConflict") {
     214            0 :         createConnection("control");
     215            0 :     } else if (function == "createConnectionYield") {
     216            0 :         createConnection("shift");
     217            0 :     } else if (function == "saveConnectionEdit") {
     218            0 :         saveConnectionEdit();
     219            0 :     } else if (function == "fixCrossings") {
     220            0 :         fixCrossings();
     221            0 :     } else if (function == "fixStoppingPlace") {
     222            0 :         fixStoppingPlace();
     223            0 :     } else if (function == "fixRoute") {
     224            0 :         fixRoute();
     225            0 :     } else if (function == "createTLS") {
     226            0 :         createTLS(0);
     227            0 :     } else if (function == "createTLSOverlapped") {
     228            0 :         createTLS(overlappedTabs);
     229            0 :     } else if (function == "copyTLS") {
     230            0 :         copyTLS();
     231            0 :     } else if (function == "joinTSL") {
     232            0 :         joinTSL();
     233            0 :     } else if (function == "disJoinTLS") {
     234            0 :         disJoinTLS();
     235            0 :     } else if (function == "deleteTLS") {
     236            0 :         deleteTLS();
     237            0 :     } else if (function == "modifyTLSTable") {
     238            0 :         modifyTLSTable();
     239            0 :     } else if (function == "resetSingleTLSPhases") {
     240            0 :         resetSingleTLSPhases();
     241            0 :     } else if (function == "resetAllTLSPhases") {
     242            0 :         resetAllTLSPhases();
     243            0 :     } else if (function == "pressTLSPhaseButton") {
     244            0 :         pressTLSPhaseButton();
     245            0 :     } else if (function == "addDefaultPhase") {
     246            0 :         addPhase("default");
     247            0 :     } else if (function == "addDuplicatePhase") {
     248            0 :         addPhase("duplicate");
     249            0 :     } else if (function == "addRedPhase") {
     250            0 :         addPhase("red");
     251            0 :     } else if (function == "addYellowPhase") {
     252            0 :         addPhase("yellow");
     253            0 :     } else if (function == "addGreenPhase") {
     254            0 :         addPhase("green");
     255            0 :     } else if (function == "addGreenPriorityPhase") {
     256            0 :         addPhase("priorityGreen");
     257            0 :     } else if (function == "tlsDeletePhase") {
     258            0 :         addPhase("deletePhase");
     259            0 :     } else if (function == "tlsMoveUp") {
     260            0 :         addPhase("moveUp");
     261            0 :     } else if (function == "tlsMoveDown") {
     262            0 :         addPhase("moveDown");
     263            0 :     } else if (function == "tlsCleanStates") {
     264            0 :         pressTLSButton("cleanStates");
     265            0 :     } else if (function == "tlsAddStates") {
     266            0 :         pressTLSButton("addStates");
     267            0 :     } else if (function == "tlsGroupSignal") {
     268            0 :         pressTLSButton("groupSignal");
     269            0 :     } else if (function == "tlsUngroupSignal") {
     270            0 :         pressTLSButton("ungroupSignal");
     271            0 :     } else if (function == "checkParameters") {
     272            0 :         checkParameters(0);
     273            0 :     } else if (function == "checkParametersOverlapped") {
     274            0 :         checkParameters(overlappedTabs);
     275            0 :     } else if (function == "checkDoubleParameters") {
     276            0 :         checkDoubleParameters(0);
     277            0 :     } else if (function == "checkDoubleParametersOverlapped") {
     278            0 :         checkDoubleParameters(overlappedTabs);
     279            0 :     } else if (function == "changeEditMode") {
     280            0 :         changeEditMode();
     281            0 :     } else if (function == "changeSupermode") {
     282            0 :         changeSupermode();
     283            0 :     } else if (function == "changeMode") {
     284            0 :         changeMode();
     285            0 :     } else if (function == "changeElement") {
     286            0 :         changeElement();
     287            0 :     } else if (function == "changePlan") {
     288            0 :         changePlan();
     289            0 :     } else if (function == "computeJunctions") {
     290            0 :         computeJunctions();
     291            0 :     } else if (function == "computeJunctionsVolatileOptions") {
     292            0 :         computeJunctionsVolatileOptions();
     293            0 :     } else if (function == "joinJunctions") {
     294            0 :         joinJunctions();
     295            0 :     } else if (function == "selectAdditionalChild") {
     296            0 :         selectAdditionalChild();
     297            0 :     } else if (function == "createRectangledShape") {
     298            0 :         createRectangledShape();
     299            0 :     } else if (function == "createSquaredShape") {
     300            0 :         createSquaredShape();
     301            0 :     } else if (function == "createLineShape") {
     302            0 :         createLineShape();
     303            0 :     } else if (function == "createMeanData") {
     304            0 :         createMeanData();
     305            0 :     } else if (function == "deleteMeanData") {
     306            0 :         deleteMeanData();
     307            0 :     } else if (function == "copyMeanData") {
     308            0 :         copyMeanData();
     309            0 :     } else if (function == "saveExistentFile") {
     310            0 :         saveExistentFile();
     311            0 :     } else if (function == "checkUndoRedo") {
     312            0 :         checkUndoRedo();
     313            0 :     } else if (function == "delete") {
     314            0 :         deleteFunction();
     315            0 :     } else if (function == "selection") {
     316            0 :         selection();
     317            0 :     } else if (function == "selectNetworkItems") {
     318            0 :         selectNetworkItems();
     319            0 :     } else if (function == "lockSelection") {
     320            0 :         lockSelection();
     321            0 :     } else if (function == "selectionRectangle") {
     322            0 :         selectionRectangle();
     323            0 :     } else if (function == "createDataSet") {
     324            0 :         createDataSet();
     325            0 :     } else if (function == "createDataInterval") {
     326            0 :         createDataInterval();
     327            0 :     } else if (function == "openAboutDialog") {
     328            0 :         openAboutDialog();
     329            0 :     } else if (function == "loadFile") {
     330            0 :         loadFile();
     331            0 :     } else if (function == "saveNewFile") {
     332            0 :         saveNewFile();
     333            0 :     } else if (function == "saveFileAs") {
     334            0 :         saveFileAs();
     335            0 :     } else if (function == "saveUnifiedFileAs") {
     336            0 :         saveUnifiedFileAs();
     337            0 :     } else if (function == "reloadFile") {
     338            0 :         reloadFile();
     339            0 :     } else if (function == "selectEdgeType") {
     340            0 :         selectEdgeType();
     341            0 :     } else if (function == "createNewEdgeType") {
     342            0 :         createNewEdgeType();
     343            0 :     } else if (function == "overwritingAccept") {
     344            0 :         overwritingAccept();
     345            0 :     } else if (function == "overwritingCancel") {
     346            0 :         overwritingCancel();
     347            0 :     } else if (function == "overwritingAbort") {
     348            0 :         overwritingAbort();
     349            0 :     } else if (function == "overwritingApplyToAll") {
     350            0 :         overwritingApplyToAll();
     351            0 :     } else if (function == "undo") {
     352            0 :         undo();
     353            0 :     } else if (function == "redo") {
     354            0 :         redo();
     355            0 :     } else if (function == "quit") {
     356            0 :         quit();
     357            0 :     } else if (function.size() > 0) {
     358            0 :         std::cout << "Function " + function + " not implemented in InternalTestStep" << std::endl;
     359            0 :         throw ProcessError();
     360              :     }
     361            0 : }
     362              : 
     363              : 
     364            0 : InternalTestStep::InternalTestStep(InternalTest* testSystem, FXSelector messageType,
     365              :                                    FXSelector messageID, Category category,
     366            0 :                                    const std::string& description) :
     367            0 :     myTestSystem(testSystem),
     368            0 :     myMessageType(messageType),
     369            0 :     myMessageID(messageID),
     370            0 :     myCategory(category),
     371            0 :     myDescription(description) {
     372              :     // add this testStep to test system
     373            0 :     testSystem->addTestSteps(this);
     374            0 : }
     375              : 
     376              : 
     377            0 : InternalTestStep::InternalTestStep(InternalTest* testSystem, FXSelector messageType,
     378              :                                    Category category, FXEvent* event, const bool updateView,
     379            0 :                                    const std::string& description) :
     380            0 :     myTestSystem(testSystem),
     381            0 :     myMessageType(messageType),
     382            0 :     myCategory(category),
     383            0 :     myUpdateView(updateView),
     384            0 :     myDescription(description),
     385            0 :     myEvent(event) {
     386              :     // add this testStep to test system
     387            0 :     testSystem->addTestSteps(this);
     388            0 : }
     389              : 
     390              : 
     391            0 : InternalTestStep::InternalTestStep(InternalTest* testSystem, DialogArgument* dialogArgument,
     392            0 :                                    const std::string& description) :
     393            0 :     myTestSystem(testSystem),
     394            0 :     myCategory(InternalTestStep::Category::DIALOG),
     395            0 :     myUpdateView(false),
     396            0 :     myDescription(description),
     397            0 :     myDialogArgument(dialogArgument) {
     398              :     // add this testStep to test system
     399            0 :     testSystem->addTestSteps(this);
     400            0 : }
     401              : 
     402              : 
     403            0 : InternalTestStep::~InternalTestStep() {
     404            0 :     if (myEvent) {
     405            0 :         delete myEvent;
     406              :     }
     407            0 :     if (myDialogArgument) {
     408            0 :         delete myDialogArgument;
     409              :     }
     410            0 :     if (myTLSTableTest) {
     411            0 :         delete myTLSTableTest;
     412              :     }
     413            0 : }
     414              : 
     415              : 
     416              : InternalTestStep*
     417            0 : InternalTestStep::getNextStep() const {
     418            0 :     return myNextStep;
     419              : }
     420              : 
     421              : 
     422              : void
     423            0 : InternalTestStep::setNextStep(InternalTestStep* nextStep) {
     424            0 :     myNextStep = nextStep;
     425            0 : }
     426              : 
     427              : 
     428              : FXSelector
     429            0 : InternalTestStep::getMessageType() const {
     430            0 :     return myMessageType;
     431              : }
     432              : 
     433              : 
     434              : FXSelector
     435            0 : InternalTestStep::getMessageID() const {
     436            0 :     return myMessageID;
     437              : }
     438              : 
     439              : 
     440              : InternalTestStep::DialogArgument*
     441            0 : InternalTestStep::getDialogArgument() const {
     442            0 :     return myDialogArgument;
     443              : }
     444              : 
     445              : 
     446              : InternalTestStep::TLSTableTest*
     447            0 : InternalTestStep::getTLSTableTest() const {
     448            0 :     return myTLSTableTest;
     449              : }
     450              : 
     451              : 
     452              : FXSelector
     453            0 : InternalTestStep::getSelector() const {
     454            0 :     return FXSEL(myMessageType, myMessageID);
     455              : }
     456              : 
     457              : 
     458              : bool
     459            0 : InternalTestStep::updateView() const {
     460            0 :     return myUpdateView;
     461              : }
     462              : 
     463              : 
     464              : InternalTestStep::Category
     465            0 : InternalTestStep::getCategory() const {
     466            0 :     return myCategory;
     467              : }
     468              : 
     469              : 
     470              : void*
     471            0 : InternalTestStep::getEvent() const {
     472            0 :     return myEvent;
     473              : }
     474              : 
     475              : 
     476              : const std::string&
     477            0 : InternalTestStep::getDescription() const {
     478            0 :     return myDescription;
     479              : }
     480              : 
     481              : 
     482              : std::string
     483            0 : InternalTestStep::parseStep(const std::string& rowText) {
     484              :     // first check if this is the netedit.setupAndStart function
     485            0 :     if (rowText.find("netedit.setupAndStart") != std::string::npos) {
     486            0 :         return "setupAndStart";
     487            0 :     } else if (rowText.find("netedit.finish") != std::string::npos) {
     488            0 :         return "finish";
     489            0 :     } else if (rowText.compare(0, 8, "netedit.") != 0) {
     490              :         // proces only lines that start with "netedit."
     491            0 :         return "";
     492              :     } else {
     493              :         std::string functionName;
     494              :         // make a copy to help editing row
     495              :         std::string rowStr = rowText;
     496              :         // every function has the format <function>(<argument1>, <argument2>,....,)
     497            0 :         if (rowText.empty() || (rowText.front() == '(') || (rowText.back() != ')')) {
     498            0 :             writeError("parseStep", 0, "function(arguments)");
     499            0 :             return "";
     500              :         }
     501              :         // first extract function
     502            0 :         while (rowStr.size() > 0) {
     503            0 :             if (rowStr.front() == '(') {
     504              :                 break;
     505              :             } else {
     506            0 :                 functionName.push_back(rowStr.front());
     507              :                 rowStr.erase(rowStr.begin());
     508              :             }
     509              :         }
     510              :         // remove prefix "netedit." (size 8) from function
     511            0 :         functionName = functionName.substr(8);
     512              :         // check if there are at least two characters (to avoid cases like 'function)')
     513            0 :         if (rowStr.size() < 2) {
     514            0 :             writeError("parseStep", 0, "function(arguments)");
     515            0 :             return functionName;
     516              :         }
     517              :         // remove both pharentesis
     518              :         rowStr.erase(rowStr.begin());
     519              :         rowStr.pop_back();
     520              :         // now parse arguments
     521            0 :         parseArguments(rowStr);
     522              :         // remove "netedit." from frunction
     523            0 :         return functionName;
     524              :     }
     525              : }
     526              : 
     527              : 
     528              : void
     529            0 : InternalTestStep::parseArguments(const std::string& arguments) {
     530              :     std::string current;
     531              :     bool inQuotes = false;
     532            0 :     for (size_t i = 0; i < arguments.length(); ++i) {
     533            0 :         char c = arguments[i];
     534            0 :         if (c == '\"' || c == '\'') {
     535              :             // Toggle quote state
     536            0 :             inQuotes = !inQuotes;
     537            0 :             current.push_back(c);
     538            0 :         } else if (c == ',' && !inQuotes) {
     539              :             // End of argument
     540            0 :             if (!current.empty()) {
     541              :                 // Trim leading/trailing whitespace
     542              :                 size_t start = current.find_first_not_of(" \t");
     543              :                 size_t end = current.find_last_not_of(" \t");
     544            0 :                 myArguments.push_back(current.substr(start, end - start + 1));
     545              :                 current.clear();
     546              :             }
     547              :         } else {
     548              :             current += c;
     549              :         }
     550              :     }
     551              :     // Add the last argument
     552            0 :     if (!current.empty()) {
     553              :         size_t start = current.find_first_not_of(" \t");
     554              :         size_t end = current.find_last_not_of(" \t");
     555            0 :         myArguments.push_back(current.substr(start, end - start + 1));
     556              :     }
     557              :     // inQuotes MUST be false, in other case we have a case like < "argument1", argument2, "argument3 >
     558            0 :     if (inQuotes) {
     559            0 :         writeError("parseArguments", 0, "<\"argument\", \"argument\">");
     560              :         myArguments.clear();
     561              :     }
     562            0 : }
     563              : 
     564              : 
     565              : void
     566            0 : InternalTestStep::setupAndStart() {
     567            0 :     myCategory = Category::INIT;
     568              :     // print in console the following lines
     569              :     std::cout << "TestFunctions: Netedit opened successfully" << std::endl;
     570              :     std::cout << "Finding reference" << std::endl;
     571              :     std::cout << "TestFunctions: 'reference.png' found. Position: " <<
     572            0 :               toString(MOUSE_REFERENCE_X) << " - " <<
     573            0 :               toString(MOUSE_REFERENCE_Y) << std::endl;
     574              :     // set first mouse position
     575            0 :     myTestSystem->updateLastMovedPosition(MOUSE_REFERENCE_X, MOUSE_REFERENCE_Y);
     576            0 : }
     577              : 
     578              : 
     579              : void
     580            0 : InternalTestStep::finish() {
     581            0 :     myCategory = Category::FINISH;
     582            0 :     myUpdateView = false;
     583              :     std::cout << "TestFunctions: Netedit closed successfully" << std::endl;
     584            0 : }
     585              : 
     586              : 
     587              : void
     588            0 : InternalTestStep::mouseClick(const std::string& button, const std::string& modifier) const {
     589            0 :     if ((myArguments.size() != 2) || (myTestSystem->getViewPositions().count(myArguments[1]) == 0)) {
     590            0 :         writeError("leftClick", 0, "<reference, position>");
     591              :     } else {
     592              :         // parse view position
     593            0 :         const auto& viewPosition = myTestSystem->getViewPositions().at(myArguments[1]);
     594              :         // build mouse click
     595            0 :         buildMouseClick(viewPosition, 0, 0, button, modifier);
     596              :         // print info
     597            0 :         writeClickInfo(viewPosition, 0, 0, modifier);
     598              :     }
     599            0 : }
     600              : 
     601              : 
     602              : void
     603            0 : InternalTestStep::leftClickOffset(const std::string& button) const {
     604            0 :     if ((myArguments.size() != 4) || (myTestSystem->getViewPositions().count(myArguments[1]) == 0) ||
     605            0 :             !checkIntArgument(myArguments[2]) || !checkIntArgument(myArguments[3])) {
     606            0 :         writeError("leftClickOffset", 0, "<reference, position, int, int>");
     607              :     } else {
     608              :         // parse view position
     609            0 :         const auto& viewPosition = myTestSystem->getViewPositions().at(myArguments[1]);
     610            0 :         const int x = getIntArgument(myArguments[2]);
     611            0 :         const int y = getIntArgument(myArguments[3]);
     612              :         // build mouse click
     613            0 :         buildMouseClick(viewPosition, x, y, button, "");
     614              :         // print info
     615            0 :         writeClickInfo(viewPosition, x, y, button);
     616              :     }
     617            0 : }
     618              : 
     619              : 
     620              : void
     621            0 : InternalTestStep::moveElementHorizontal() const {
     622            0 :     if ((myArguments.size() != 3) || (myTestSystem->getViewPositions().count(myArguments[1]) == 0) ||
     623            0 :             (myTestSystem->getMovements().count(myArguments[2]) == 0)) {
     624            0 :         writeError("moveElementHorizontal", 0, "<reference, position, radius>");
     625              :     } else {
     626              :         // get parameters
     627            0 :         const auto& referencePosition = myTestSystem->getViewPositions().at("netedit.positions.reference");
     628            0 :         const auto& position = myTestSystem->getViewPositions().at(myArguments[1]);
     629            0 :         const auto& radius = myTestSystem->getMovements().at(myArguments[2]);
     630              :         // click over reference
     631            0 :         buildMouseClick(referencePosition, 0, 0, "left", "");
     632              :         // drag and drop
     633            0 :         buildMouseDragDrop(position, 0, 0, position, radius.getRight(), 0, "");
     634            0 :         buildMouseDragDrop(position, radius.getRight(), 0, position, radius.getLeft(), 0, "");
     635              :         // write info
     636            0 :         writeClickInfo(position, 0, 0, "");
     637              :     }
     638            0 : }
     639              : 
     640              : 
     641              : void
     642            0 : InternalTestStep::moveElementVertical() const {
     643            0 :     if ((myArguments.size() != 3) || (myTestSystem->getViewPositions().count(myArguments[1]) == 0) ||
     644            0 :             (myTestSystem->getMovements().count(myArguments[2]) == 0)) {
     645            0 :         writeError("moveElementVertical", 0, "<reference, position, radius>");
     646              :     } else {
     647              :         // get parameters
     648            0 :         const auto& referencePosition = myTestSystem->getViewPositions().at("netedit.positions.reference");
     649            0 :         const auto& position = myTestSystem->getViewPositions().at(myArguments[1]);
     650            0 :         const auto& radius = myTestSystem->getMovements().at(myArguments[2]);
     651              :         // click over reference
     652            0 :         buildMouseClick(referencePosition, 0, 0, "left", "");
     653              :         // drag and drop
     654            0 :         buildMouseDragDrop(position, 0, 0, position, 0, radius.getUp(), "");
     655            0 :         buildMouseDragDrop(position, radius.getRight(), 0, position, 0, radius.getDown(), "");
     656              :         // write info
     657            0 :         writeClickInfo(position, 0, 0, "");
     658              :     }
     659            0 : }
     660              : 
     661              : 
     662              : void
     663            0 : InternalTestStep::moveElement() const {
     664            0 :     if ((myArguments.size() != 3) || (myTestSystem->getViewPositions().count(myArguments[1]) == 0) ||
     665            0 :             (myTestSystem->getMovements().count(myArguments[2]) == 0)) {
     666            0 :         writeError("moveElement", 0, "<reference, position, radius>");
     667              :     } else {
     668              :         // get parameters
     669            0 :         const auto& referencePosition = myTestSystem->getViewPositions().at("netedit.positions.reference");
     670            0 :         const auto& position = myTestSystem->getViewPositions().at(myArguments[1]);
     671            0 :         const auto& radius = myTestSystem->getMovements().at(myArguments[2]);
     672              :         // click over reference
     673            0 :         buildMouseClick(referencePosition, 0, 0, "left", "");
     674              :         // drag and drop
     675            0 :         buildMouseDragDrop(position, 0, 0, position, radius.getRight(), 0, "");
     676            0 :         buildMouseDragDrop(position, radius.getRight(), 0, position, radius.getRight(), radius.getDown(), "");
     677              :         // drag and drop
     678            0 :         buildMouseDragDrop(position, radius.getRight(), radius.getDown(), position, radius.getLeft(), radius.getDown(), "");
     679            0 :         buildMouseDragDrop(position, radius.getLeft(), radius.getDown(), position, radius.getLeft(), radius.getUp(), "");
     680              :     }
     681            0 : }
     682              : 
     683              : 
     684              : void
     685            0 : InternalTestStep::focusOnFrame() const {
     686            0 :     if (myArguments.size() != 0) {
     687            0 :         writeError("focusOnFrame", 0, "<>");
     688              :     } else {
     689              :         // focus frame
     690            0 :         new InternalTestStep(myTestSystem, SEL_COMMAND, MID_HOTKEY_SHIFT_F12_FOCUSUPPERELEMENT, Category::APP, "focus current frame");
     691              :     }
     692            0 : }
     693              : 
     694              : 
     695              : void
     696            0 : InternalTestStep::typeKey() const {
     697            0 :     if (myArguments.size() != 1) {
     698            0 :         writeError("typeKey", 0, "<key>");
     699              :     } else {
     700            0 :         buildPressKeyEvent(Category::APP, getStringArgument(myArguments[0]), true);
     701              :     }
     702            0 : }
     703              : 
     704              : 
     705              : void
     706            0 : InternalTestStep::contextualMenuOperation() const {
     707            0 :     if ((myArguments.size() != 3) || (myTestSystem->getViewPositions().count(myArguments[1]) == 0) ||
     708            0 :             (myTestSystem->getContextualMenuOperations().count(myArguments[2]) == 0)) {
     709            0 :         writeError("contextualMenuOperation", 0, "<reference, position, contextualMenuOperations>");
     710              :     } else {
     711              :         // parse arguments
     712            0 :         const auto& viewPosition = myTestSystem->getViewPositions().at(myArguments[1]);
     713            0 :         const auto& contextualMenu = myTestSystem->getContextualMenuOperations().at(myArguments[2]);
     714              :         // build mouse click
     715            0 :         buildMouseClick(viewPosition, 0, 0, "right", "");
     716              :         // jump to the element
     717            0 :         for (int i = 0; i < contextualMenu.getMainMenuPosition(); i++) {
     718            0 :             buildPressKeyEvent(Category::APP, "down", false);
     719              :         }
     720              :         // type space for select
     721            0 :         buildPressKeyEvent(Category::APP, "space", false);
     722              :         // jump to the subMenuA
     723            0 :         if (contextualMenu.getSubMenuAPosition() > 0) {
     724            0 :             for (int i = 0; i < contextualMenu.getSubMenuAPosition(); i++) {
     725            0 :                 buildPressKeyEvent(Category::APP, "down", false);
     726              :             }
     727              :             // type space for select
     728            0 :             buildPressKeyEvent(Category::APP, "space", false);
     729              :         }
     730              :         // jump to the subMenuB
     731            0 :         if (contextualMenu.getSubMenuBPosition() > 0) {
     732            0 :             for (int i = 0; i < contextualMenu.getSubMenuBPosition(); i++) {
     733            0 :                 buildPressKeyEvent(Category::APP, "down", false);
     734              :             }
     735              :             // type space for select
     736            0 :             buildPressKeyEvent(Category::APP, "space", false);
     737              :         }
     738              :     }
     739            0 : }
     740              : 
     741              : 
     742              : void
     743            0 : InternalTestStep::protectElements() const {
     744            0 :     if (myArguments.size() != 0) {
     745            0 :         writeError("protectElements", 0, "<>");
     746              :     } else {
     747              :         // go to delete mode
     748            0 :         new InternalTestStep(myTestSystem, SEL_COMMAND, MID_HOTKEY_D_MODE_SINGLESIMULATIONSTEP_DELETE, Category::APP, "delete mode");
     749              :         // focus frame
     750            0 :         new InternalTestStep(myTestSystem, SEL_COMMAND, MID_HOTKEY_SHIFT_F12_FOCUSUPPERELEMENT, Category::APP, "focus delete frame");
     751              :         // jump to the element
     752            0 :         for (int i = 0; i < myTestSystem->getAttributesEnum().at("netedit.attrs.frames.delete.protectElements"); i++) {
     753            0 :             buildPressKeyEvent(Category::APP, "tab", false);
     754              :         }
     755              :         // press enter to confirm changes (updating view)
     756            0 :         buildPressKeyEvent(Category::APP, "space", true);
     757              :     }
     758            0 : }
     759              : 
     760              : 
     761              : void
     762            0 : InternalTestStep::waitDeleteWarning() const {
     763            0 :     if (myArguments.size() != 0) {
     764            0 :         writeError("waitDeleteWarning", 0, "<>");
     765              :     } else {
     766              :         // nothing to do (wait for delete warning doesnt' appear in internal test)
     767              :     }
     768            0 : }
     769              : 
     770              : 
     771              : void
     772            0 : InternalTestStep::modifyAttribute(const int overlappedTabs) const {
     773            0 :     if ((myArguments.size() != 2) || !checkIntArgument(myArguments[0]) ||
     774            0 :             !checkStringArgument(myArguments[1])) {
     775            0 :         writeError("modifyAttribute", overlappedTabs, "<int/attributeEnum, \"string\">");
     776              :     } else {
     777              :         // modify attribute
     778            0 :         modifyStringAttribute(Category::APP, getIntArgument(myArguments[0]), overlappedTabs, getStringArgument(myArguments[1]));
     779              :     }
     780            0 : }
     781              : 
     782              : 
     783              : void
     784            0 : InternalTestStep::modifyBoolAttribute(const int overlappedTabs) const {
     785            0 :     if ((myArguments.size() != 1) || !checkIntArgument(myArguments[0])) {
     786            0 :         writeError("modifyBoolAttribute", overlappedTabs, "<int/attributeEnum>");
     787              :     } else {
     788              :         // modify bool attribute
     789            0 :         modifyBoolAttribute(Category::APP, getIntArgument(myArguments[0]), overlappedTabs);
     790              :     }
     791            0 : }
     792              : 
     793              : 
     794              : void
     795            0 : InternalTestStep::modifyColorAttribute(const int overlappedTabs) const {
     796            0 :     if ((myArguments.size() != 1) || !checkIntArgument(myArguments[0])) {
     797            0 :         writeError("modifyColorAttribute", overlappedTabs, "<int/attributeEnum>");
     798              :     } else {
     799              :         // open dialog
     800            0 :         modifyBoolAttribute(Category::APP, getIntArgument(myArguments[0]), overlappedTabs);
     801              :         // select vClass
     802            0 :         new InternalTestStep(myTestSystem, new DialogArgument(DialogType::COLOR, "139,131,120"), "set color");
     803              :         // press accept
     804            0 :         new InternalTestStep(myTestSystem, new DialogArgument(DialogType::COLOR, DialogArgument::Action::ACCEPT), "accept vClasses");
     805              :     }
     806            0 : }
     807              : 
     808              : 
     809              : void
     810            0 : InternalTestStep::modifyVClassDialog_NoDisallowAll(const int overlappedTabs) const {
     811            0 :     if ((myArguments.size() != 2) || !checkIntArgument(myArguments[0]) ||
     812            0 :             !checkIntArgument(myArguments[1])) {
     813            0 :         writeError("modifyVClassDialog_NoDisallowAll", overlappedTabs, "<int/attributeEnum, int/attributeEnum>");
     814              :     } else {
     815              :         // open dialog
     816            0 :         modifyBoolAttribute(Category::APP, getIntArgument(myArguments[0]), overlappedTabs);
     817              :         // select vClass
     818            0 :         new InternalTestStep(myTestSystem, new DialogArgument(DialogType::VCLASS, "netedit.attrs.dialog.allowVClass.", myArguments[1]), "select vClass");
     819              :         // press accept
     820            0 :         new InternalTestStep(myTestSystem, new DialogArgument(DialogType::VCLASS, DialogArgument::Action::ACCEPT), "accept vClasses");
     821              :     }
     822            0 : }
     823              : 
     824              : 
     825              : void
     826            0 : InternalTestStep::modifyVClassDialog_DisallowAll(const int overlappedTabs) const {
     827            0 :     if ((myArguments.size() != 2) || !checkIntArgument(myArguments[0]) ||
     828            0 :             !checkIntArgument(myArguments[1])) {
     829            0 :         writeError("modifyVClassDialog_DisallowAll", overlappedTabs, "<int/attributeEnum, int/attributeEnum>");
     830              :     } else {
     831              :         // open dialog
     832            0 :         modifyBoolAttribute(Category::APP, getIntArgument(myArguments[0]), overlappedTabs);
     833              :         // select vClass
     834            0 :         new InternalTestStep(myTestSystem, new DialogArgument(DialogType::VCLASS, "disallowAll"), "disallow all");
     835              :         // select vClass
     836            0 :         new InternalTestStep(myTestSystem, new DialogArgument(DialogType::VCLASS, "netedit.attrs.dialog.allowVClass.", myArguments[1]), "select vClass");
     837              :         // press accept
     838            0 :         new InternalTestStep(myTestSystem, new DialogArgument(DialogType::VCLASS, DialogArgument::Action::ACCEPT), "accept vClasses");
     839              :     }
     840            0 : }
     841              : 
     842              : 
     843              : void
     844            0 : InternalTestStep::modifyVClassDialog_Cancel(const int overlappedTabs) const {
     845            0 :     if ((myArguments.size() != 2) ||
     846            0 :             !checkIntArgument(myArguments[0]) ||
     847            0 :             !checkIntArgument(myArguments[1])) {
     848            0 :         writeError("modifyVClassDialog_Cancel", overlappedTabs, "<int/attributeEnum, int/attributeEnum>");
     849              :     } else {
     850              :         // open dialog
     851            0 :         modifyBoolAttribute(Category::APP, getIntArgument(myArguments[0]), overlappedTabs);
     852              :         // select vClass
     853            0 :         new InternalTestStep(myTestSystem, new DialogArgument(DialogType::VCLASS, "disallowAll"), "disallow all");
     854              :         // select vClass
     855            0 :         new InternalTestStep(myTestSystem, new DialogArgument(DialogType::VCLASS, "netedit.attrs.dialog.allowVClass.", myArguments[1]), "select vClass");
     856              :         // press accept
     857            0 :         new InternalTestStep(myTestSystem, new DialogArgument(DialogType::VCLASS, DialogArgument::Action::CANCEL), "accept vClasses");
     858              :     }
     859            0 : }
     860              : 
     861              : 
     862              : void
     863            0 : InternalTestStep::modifyVClassDialog_Reset(const int overlappedTabs) const {
     864            0 :     if ((myArguments.size() != 2) || !checkIntArgument(myArguments[0]) ||
     865            0 :             !checkIntArgument(myArguments[1])) {
     866            0 :         writeError("modifyVClassDialog_Reset", overlappedTabs, "<int/attributeEnum, int/attributeEnum>");
     867              :     } else {
     868              :         // open dialog
     869            0 :         modifyBoolAttribute(Category::APP, getIntArgument(myArguments[0]), overlappedTabs);
     870              :         // select vClass
     871            0 :         new InternalTestStep(myTestSystem, new DialogArgument(DialogType::VCLASS, "disallowAll"), "disallow all");
     872              :         // select vClass
     873            0 :         new InternalTestStep(myTestSystem, new DialogArgument(DialogType::VCLASS, "netedit.attrs.dialog.allowVClass.", myArguments[1]), "select vClass");
     874              :         // press reset
     875            0 :         new InternalTestStep(myTestSystem, new DialogArgument(DialogType::VCLASS, DialogArgument::Action::RESET), "accept vClasses");
     876              :         // press accept
     877            0 :         new InternalTestStep(myTestSystem, new DialogArgument(DialogType::VCLASS, DialogArgument::Action::ACCEPT), "accept vClasses");
     878              :     }
     879            0 : }
     880              : 
     881              : 
     882              : void
     883            0 : InternalTestStep::modifyVTypeDialogAttribute() const {
     884            0 :     if ((myArguments.size() != 3) || !checkStringArgument(myArguments[0]) ||
     885            0 :             !checkIntArgument(myArguments[1]) || !checkStringArgument(myArguments[2])) {
     886            0 :         writeError("modifyVTypeDialogAttribute", 0, "<str, int/attributeEnum, str>");
     887              :     } else {
     888              :         // get arguments
     889            0 :         const auto operation = getStringArgument(myArguments[0]);
     890            0 :         const auto tabs = getIntArgument(myArguments[1]);
     891            0 :         const auto value = getStringArgument(myArguments[2]);
     892              :         // first check if open dialog
     893            0 :         if (operation == "open") {
     894            0 :             modifyBoolAttribute(Category::APP, myTestSystem->getAttributesEnum().at("netedit.attrs.type.buttons.dialog"), 0);
     895              :         }
     896              :         // print info
     897              :         std::cout << value << std::endl;
     898              :         // focus dialog
     899            0 :         buildTwoPressKeyEvent(Category::DIALOG, "alt", "f", false);
     900              :         // jump to the element
     901            0 :         for (int i = 0; i < tabs; i++) {
     902            0 :             buildPressKeyEvent(Category::DIALOG, "tab", false);
     903              :         }
     904              :         // write attribute character by character
     905            0 :         if (value.empty()) {
     906            0 :             buildPressKeyEvent(Category::DIALOG, "delete", false);
     907              :         } else {
     908            0 :             for (const char c : value) {
     909            0 :                 buildPressKeyEvent(Category::DIALOG, {c}, false);
     910              :             }
     911              :         }
     912              :         // press enter to confirm changes (updating view)
     913            0 :         buildPressKeyEvent(Category::DIALOG, "enter", false);
     914              :         // finally check if close dialog
     915            0 :         if (operation == "close") {
     916            0 :             buildTwoPressKeyEvent(Category::DIALOG, "alt", "a", false);
     917            0 :             buildPressKeyEvent(Category::DIALOG, "enter", false);
     918              :         }
     919              :     }
     920            0 : }
     921              : 
     922              : 
     923              : void
     924            0 : InternalTestStep::createConnection(const std::string& keyModifier) const {
     925              :     if ((myArguments.size() != 3) ||
     926            0 :             (myTestSystem->getViewPositions().count(myArguments[1]) == 0) ||
     927            0 :             (myTestSystem->getViewPositions().count(myArguments[2]) == 0)) {
     928            0 :         writeError("createConnection", 0, "<reference, position, position>");
     929              :     } else {
     930              :         // parse view position
     931            0 :         const auto& fromLane = myTestSystem->getViewPositions().at(myArguments[1]);
     932            0 :         const auto& toLane = myTestSystem->getViewPositions().at(myArguments[2]);
     933              :         // build mouse click from
     934            0 :         buildMouseClick(fromLane, 0, 0, "left", keyModifier);
     935            0 :         writeClickInfo(fromLane, 0, 0, "");
     936              :         // build mouse click from
     937            0 :         buildMouseClick(toLane, 0, 0, "left", keyModifier);
     938            0 :         writeClickInfo(toLane, 0, 0, "");
     939              :     }
     940            0 : }
     941              : 
     942              : 
     943              : void
     944            0 : InternalTestStep::createCrossing() const {
     945            0 :     if ((myArguments.size() != 1) || !checkBoolArgument(myArguments[0])) {
     946            0 :         writeError("createCrossing", 0, "<bool>");
     947              :     } else {
     948            0 :         if (getBoolArgument(myArguments[0])) {
     949            0 :             modifyBoolAttribute(Category::APP, myTestSystem->getAttributesEnum().at("netedit.attrs.crossing.createTLS.button"), 0);
     950              :         } else {
     951            0 :             modifyBoolAttribute(Category::APP, myTestSystem->getAttributesEnum().at("netedit.attrs.crossing.create.button"), 0);
     952              :         }
     953              :     }
     954            0 : }
     955              : 
     956              : 
     957              : void
     958            0 : InternalTestStep::modifyCrossingDefaultValue() const {
     959            0 :     if ((myArguments.size() != 2) || !checkIntArgument(myArguments[0]) || !checkStringArgument(myArguments[1])) {
     960            0 :         writeError("modifyCrossingDefaultValue", 0, "<int, value>");
     961              :     } else {
     962            0 :         const int tabs = getIntArgument(myArguments[0]);
     963            0 :         const auto value = getStringArgument(myArguments[1]);
     964            0 :         modifyStringAttribute(Category::APP, tabs, myTestSystem->getAttributesEnum().at("netedit.attrs.crossing.firstField"), value);
     965              :     }
     966            0 : }
     967              : 
     968              : 
     969              : void
     970            0 : InternalTestStep::modifyCrossingDefaultBoolValue() const {
     971            0 :     if ((myArguments.size() != 1) || !checkIntArgument(myArguments[0])) {
     972            0 :         writeError("modifyCrossingDefaultBoolValue", 0, "<int>");
     973              :     } else {
     974            0 :         const int tabs = getIntArgument(myArguments[0]);
     975            0 :         modifyBoolAttribute(Category::APP, tabs, myTestSystem->getAttributesEnum().at("netedit.attrs.crossing.firstField"));
     976              :     }
     977            0 : }
     978              : 
     979              : 
     980              : void
     981            0 : InternalTestStep::crossingClearEdges() const {
     982            0 :     if (myArguments.size() != 0) {
     983            0 :         writeError("crossingClearEdges", 0, "<>");
     984              :     } else {
     985            0 :         modifyBoolAttribute(Category::APP, myTestSystem->getAttributesEnum().at("netedit.attrs.crossing.clearEdges"), 0);
     986              :     }
     987            0 : }
     988              : 
     989              : 
     990              : void
     991            0 : InternalTestStep::crossingInvertEdges() const {
     992            0 :     if (myArguments.size() != 0) {
     993            0 :         writeError("crossingInvertEdges", 0, "<>");
     994              :     } else {
     995            0 :         modifyBoolAttribute(Category::APP, myTestSystem->getAttributesEnum().at("netedit.attrs.crossing.invertEdges"), 0);
     996              :     }
     997            0 : }
     998              : 
     999              : 
    1000              : void
    1001            0 : InternalTestStep::saveConnectionEdit() const {
    1002            0 :     if (myArguments.size() != 0) {
    1003            0 :         writeError("saveConnectionEdit", 0, "<>");
    1004              :     } else {
    1005            0 :         modifyBoolAttribute(Category::APP, myTestSystem->getAttributesEnum().at("netedit.attrs.connection.saveConnections"), 0);
    1006              :     }
    1007            0 : }
    1008              : 
    1009              : 
    1010              : void
    1011            0 : InternalTestStep::fixCrossings() {
    1012            0 :     if ((myArguments.size() != 1) || !checkStringArgument(myArguments[0])) {
    1013            0 :         writeError("fixCrossings", 0, "<str>");
    1014              :     } else {
    1015              :         // save config
    1016              :         new InternalTestStep(myTestSystem, SEL_COMMAND, MID_HOTKEY_CTRL_SHIFT_E_SAVENETEDITCONFIG,
    1017            0 :                              Category::APP, "save netedit config");
    1018              :         // fix crossings
    1019            0 :         new InternalTestStep(myTestSystem, new DialogArgument(DialogType::FIX_NETWORKELEMENTS, getStringArgument(myArguments[0])), "fix crossings");
    1020              :         // accept changes
    1021            0 :         new InternalTestStep(myTestSystem, new DialogArgument(DialogType::FIX_NETWORKELEMENTS, DialogArgument::Action::ACCEPT), "accept fix");
    1022              :     }
    1023            0 : }
    1024              : 
    1025              : 
    1026              : void
    1027            0 : InternalTestStep::fixStoppingPlace() {
    1028            0 :     if ((myArguments.size() != 1) || !checkStringArgument(myArguments[0])) {
    1029            0 :         writeError("fixStoppingPlace", 0, "<str>");
    1030              :     } else {
    1031              :         // save config
    1032              :         new InternalTestStep(myTestSystem, SEL_COMMAND, MID_HOTKEY_CTRL_SHIFT_E_SAVENETEDITCONFIG,
    1033            0 :                              Category::APP, "save netedit config");
    1034              :         // fix stoppingPlace
    1035            0 :         new InternalTestStep(myTestSystem, new DialogArgument(DialogType::FIX_ADDITIONALELEMENTS, getStringArgument(myArguments[0])), "fix stoppingPlace in dialog");
    1036              :         // accept changes
    1037            0 :         new InternalTestStep(myTestSystem, new DialogArgument(DialogType::FIX_ADDITIONALELEMENTS, DialogArgument::Action::ACCEPT), "accept fix");
    1038              :     }
    1039            0 : }
    1040              : 
    1041              : 
    1042              : void
    1043            0 : InternalTestStep::fixRoute() {
    1044            0 :     if ((myArguments.size() != 1) || !checkStringArgument(myArguments[0])) {
    1045            0 :         writeError("fixRoute", 0, "<str>");
    1046              :     } else {
    1047              :         // save config
    1048              :         new InternalTestStep(myTestSystem, SEL_COMMAND, MID_HOTKEY_CTRL_SHIFT_E_SAVENETEDITCONFIG,
    1049            0 :                              Category::APP, "save netedit config");
    1050              :         // fix route
    1051            0 :         new InternalTestStep(myTestSystem, new DialogArgument(DialogType::FIX_DEMANDELEMENTS, getStringArgument(myArguments[0])), "fix route in dialog");
    1052              :         // accept changes
    1053            0 :         new InternalTestStep(myTestSystem, new DialogArgument(DialogType::FIX_DEMANDELEMENTS, DialogArgument::Action::ACCEPT), "accept fix");
    1054              :     }
    1055            0 : }
    1056              : 
    1057              : 
    1058              : void
    1059            0 : InternalTestStep::createTLS(const int overlappedTabs) const {
    1060            0 :     if (myArguments.size() != 0) {
    1061            0 :         writeError("createTLS", overlappedTabs, "<>");
    1062              :     } else {
    1063            0 :         modifyBoolAttribute(Category::APP, myTestSystem->getAttributesEnum().at("netedit.attrs.TLS.create"), overlappedTabs);
    1064              :     }
    1065            0 : }
    1066              : 
    1067              : 
    1068              : void
    1069            0 : InternalTestStep::copyTLS() const {
    1070            0 :     if ((myArguments.size() != 1) || !checkBoolArgument(myArguments[0])) {
    1071            0 :         writeError("copyTLS", 0, "<bool>");
    1072              :     } else {
    1073            0 :         if (getBoolArgument(myArguments[0])) {
    1074            0 :             modifyBoolAttribute(Category::APP, myTestSystem->getAttributesEnum().at("netedit.attrs.TLS.copyJoined"), 0);
    1075              :         } else {
    1076            0 :             modifyBoolAttribute(Category::APP, myTestSystem->getAttributesEnum().at("netedit.attrs.TLS.copySingle"), 0);
    1077              :         }
    1078              :     }
    1079            0 : }
    1080              : 
    1081              : 
    1082              : void
    1083            0 : InternalTestStep::joinTSL() const {
    1084            0 :     if (myArguments.size() != 0) {
    1085            0 :         writeError("joinTSL", 0, "<>");
    1086              :     } else {
    1087            0 :         modifyBoolAttribute(Category::APP, myTestSystem->getAttributesEnum().at("netedit.attrs.TLS.joinTLS"), 0);
    1088              :     }
    1089            0 : }
    1090              : 
    1091              : 
    1092              : void
    1093            0 : InternalTestStep::disJoinTLS() const {
    1094            0 :     if (myArguments.size() != 0) {
    1095            0 :         writeError("disJoinTLS", 0, "<>");
    1096              :     } else {
    1097            0 :         modifyBoolAttribute(Category::APP, myTestSystem->getAttributesEnum().at("netedit.attrs.TLS.disjoinTLS"), 0);
    1098              :     }
    1099            0 : }
    1100              : 
    1101              : 
    1102              : void
    1103            0 : InternalTestStep::deleteTLS() const {
    1104            0 :     if ((myArguments.size() != 1) || !checkBoolArgument(myArguments[0])) {
    1105            0 :         writeError("deleteTLS", 0, "<bool>");
    1106              :     } else {
    1107            0 :         if (getBoolArgument(myArguments[0])) {
    1108            0 :             modifyBoolAttribute(Category::APP, myTestSystem->getAttributesEnum().at("netedit.attrs.TLS.deleteJoined"), 0);
    1109              :         } else {
    1110            0 :             modifyBoolAttribute(Category::APP, myTestSystem->getAttributesEnum().at("netedit.attrs.TLS.deleteSingle"), 0);
    1111              :         }
    1112              :     }
    1113            0 : }
    1114              : 
    1115              : 
    1116              : void
    1117            0 : InternalTestStep::modifyTLSTable() {
    1118            0 :     if ((myArguments.size() != 3) || !checkIntArgument(myArguments[0]) ||
    1119            0 :             !checkIntArgument(myArguments[1]) || !checkStringArgument(myArguments[2])) {
    1120            0 :         writeError("modifyTLSTable", 0, "<row, int/attributeEnum, \"string\">");
    1121              :     } else {
    1122            0 :         myCategory = Category::TLS_PHASETABLE;
    1123              :         // get row
    1124            0 :         const int row = getIntArgument(myArguments[0]);
    1125            0 :         const int column = getIntArgument(myArguments[1]);
    1126            0 :         const std::string text = getStringArgument(myArguments[2]);
    1127              :         // modify attribute
    1128            0 :         myTLSTableTest = new TLSTableTest(MID_GNE_TLSTABLE_TEXTFIELD, row, column, text);
    1129              :         // show text
    1130              :         std::cout << text << std::endl;
    1131              :     }
    1132            0 : }
    1133              : 
    1134              : 
    1135              : void
    1136            0 : InternalTestStep::resetSingleTLSPhases() const {
    1137            0 :     if ((myArguments.size() != 1) || !checkBoolArgument(myArguments[0])) {
    1138            0 :         writeError("resetSingleTLSPhases", 0, "<bool>");
    1139              :     } else {
    1140            0 :         if (getBoolArgument(myArguments[0])) {
    1141            0 :             modifyBoolAttribute(myTestSystem->getAttributesEnum().at("netedit.attrs.TLS.resetPhaseSingle"));
    1142              :         } else {
    1143            0 :             modifyBoolAttribute(myTestSystem->getAttributesEnum().at("netedit.attrs.TLS.resetPhaseJoined"));
    1144              :         }
    1145              :     }
    1146            0 : }
    1147              : 
    1148              : 
    1149              : void
    1150            0 : InternalTestStep::resetAllTLSPhases() const {
    1151            0 :     if ((myArguments.size() != 1) || !checkBoolArgument(myArguments[0])) {
    1152            0 :         writeError("resetAllTLSPhases", 0, "<bool>");
    1153              :     } else {
    1154            0 :         if (getBoolArgument(myArguments[0])) {
    1155            0 :             modifyBoolAttribute(myTestSystem->getAttributesEnum().at("netedit.attrs.TLS.resetAllJoined"));
    1156              :         } else {
    1157            0 :             modifyBoolAttribute(myTestSystem->getAttributesEnum().at("netedit.attrs.TLS.resetAllSingle"));
    1158              :         }
    1159              :     }
    1160            0 : }
    1161              : 
    1162              : 
    1163              : void
    1164            0 : InternalTestStep::pressTLSPhaseButton() const {
    1165            0 :     if ((myArguments.size() != 1) || !checkIntArgument(myArguments[0])) {
    1166            0 :         writeError("pressTLSPhaseButton", 0, "<int/attributeEnum>");
    1167              :     } else {
    1168            0 :         modifyBoolAttribute(getIntArgument(myArguments[0]));
    1169              :     }
    1170            0 : }
    1171              : 
    1172              : 
    1173              : void
    1174            0 : InternalTestStep::addPhase(const std::string& type) {
    1175            0 :     if ((myArguments.size() != 1) || !checkIntArgument(myArguments[0])) {
    1176            0 :         writeError("addPhase" + type, 0, "<int/attributeEnum>");
    1177              :     } else {
    1178            0 :         myCategory = Category::TLS_PHASETABLE;
    1179              :         // get row
    1180            0 :         const int row = getIntArgument(myArguments[0]);
    1181              :         // continue depending of the type of phase
    1182            0 :         if (type == "default") {
    1183            0 :             myTLSTableTest = new TLSTableTest(MID_GNE_TLSTABLE_ADDPHASE, row);
    1184            0 :         } else if (type == "duplicate") {
    1185            0 :             myTLSTableTest = new TLSTableTest(MID_GNE_TLSTABLE_COPYPHASE, row);
    1186            0 :         } else if (type == "red") {
    1187            0 :             myTLSTableTest = new TLSTableTest(MID_GNE_TLSTABLE_ADDPHASEALLRED, row);
    1188            0 :         } else if (type == "yellow") {
    1189            0 :             myTLSTableTest = new TLSTableTest(MID_GNE_TLSTABLE_ADDPHASEALLYELLOW, row);
    1190            0 :         } else if (type == "green") {
    1191            0 :             myTLSTableTest = new TLSTableTest(MID_GNE_TLSTABLE_ADDPHASEALLGREEN, row);
    1192            0 :         } else if (type == "priorityGreen") {
    1193            0 :             myTLSTableTest = new TLSTableTest(MID_GNE_TLSTABLE_ADDPHASEALLGREENPRIORITY, row);
    1194            0 :         } else if (type == "deletePhase") {
    1195            0 :             myTLSTableTest = new TLSTableTest(MID_GNE_TLSTABLE_REMOVEPHASE, row);
    1196            0 :         } else if (type == "moveUp") {
    1197            0 :             myTLSTableTest = new TLSTableTest(MID_GNE_TLSTABLE_MOVEUPPHASE, row);
    1198            0 :         } else if (type == "moveDown") {
    1199            0 :             myTLSTableTest = new TLSTableTest(MID_GNE_TLSTABLE_MOVEDOWNPHASE, row);
    1200              :         }
    1201              :     }
    1202            0 : }
    1203              : 
    1204              : 
    1205              : void
    1206            0 : InternalTestStep::pressTLSButton(const std::string& type) {
    1207            0 :     if (myArguments.size() != 0) {
    1208            0 :         writeError("pressTLSButton" + type, 0, "<>");
    1209              :     } else {
    1210            0 :         myCategory = Category::TLS_PHASES;
    1211              :         // continue depending of the type of phase
    1212            0 :         if (type == "cleanStates") {
    1213            0 :             myMessageID = MID_GNE_TLSFRAME_PHASES_CLEANUP;
    1214            0 :         } else if (type == "addStates") {
    1215            0 :             myMessageID = MID_GNE_TLSFRAME_PHASES_ADDUNUSED;
    1216            0 :         } else if (type == "groupSignal") {
    1217            0 :             myMessageID = MID_GNE_TLSFRAME_PHASES_GROUPSTATES;
    1218            0 :         } else if (type == "ungroupSignal") {
    1219            0 :             myMessageID = MID_GNE_TLSFRAME_PHASES_UNGROUPSTATES;
    1220              :         }
    1221              :     }
    1222            0 : }
    1223              : 
    1224              : 
    1225              : void
    1226            0 : InternalTestStep::checkParameters(const int overlappedTabs) const {
    1227            0 :     if ((myArguments.size() != 2) || !checkIntArgument(myArguments[1])) {
    1228            0 :         writeError("checkParameters", overlappedTabs, "<int/attributeEnum>");
    1229              :     } else {
    1230            0 :         const int tabs = getIntArgument(myArguments[1]);
    1231              :         // check different values
    1232            0 :         modifyStringAttribute(Category::APP, tabs, overlappedTabs, "dummyGenericParameters");
    1233            0 :         modifyStringAttribute(Category::APP, tabs, overlappedTabs, "key1|key2|key3");
    1234            0 :         modifyStringAttribute(Category::APP, tabs, overlappedTabs, "key1=value1|key2=value2|key3=value3");
    1235            0 :         modifyStringAttribute(Category::APP, tabs, overlappedTabs, "key1=|key2=|key3=");
    1236            0 :         modifyStringAttribute(Category::APP, tabs, overlappedTabs, "");
    1237            0 :         modifyStringAttribute(Category::APP, tabs, overlappedTabs, "key1duplicated=value1|key1duplicated=value2|key3=value3");
    1238            0 :         modifyStringAttribute(Category::APP, tabs, overlappedTabs, "key1=valueDuplicated|key2=valueDuplicated|key3=valueDuplicated");
    1239            0 :         modifyStringAttribute(Category::APP, tabs, overlappedTabs, "keyInvalid.;%>%$$=value1|key2=value2|key3=value3");
    1240            0 :         modifyStringAttribute(Category::APP, tabs, overlappedTabs, "key1=valueInvalid%;%$<>$$%|key2=value2|key3=value3");
    1241            0 :         modifyStringAttribute(Category::APP, tabs, overlappedTabs, "keyFinal1=value1|keyFinal2=value2|keyFinal3=value3");
    1242              :         // check undo-redo
    1243            0 :         buildUndo(9);
    1244            0 :         buildRedo(9);
    1245              :     }
    1246            0 : }
    1247              : 
    1248              : 
    1249              : void
    1250            0 : InternalTestStep::checkDoubleParameters(const int overlappedTabs) const {
    1251            0 :     if ((myArguments.size() != 2) || !checkIntArgument(myArguments[1])) {
    1252            0 :         writeError("checkDoubleParameters", overlappedTabs, "<int/attributeEnum>");
    1253              :     } else {
    1254            0 :         const int tabs = getIntArgument(myArguments[1]);
    1255              :         // check different values
    1256            0 :         modifyStringAttribute(Category::APP, tabs, overlappedTabs, "dummyGenericParameters");
    1257            0 :         modifyStringAttribute(Category::APP, tabs, overlappedTabs, "key1|key2|key3");
    1258            0 :         modifyStringAttribute(Category::APP, tabs, overlappedTabs, "key1=1|key2=2|key3=3");
    1259            0 :         modifyStringAttribute(Category::APP, tabs, overlappedTabs, "key1=|key2=|key3=");
    1260            0 :         modifyStringAttribute(Category::APP, tabs, overlappedTabs, "");
    1261            0 :         modifyStringAttribute(Category::APP, tabs, overlappedTabs, "key1duplicated=1|key1duplicated=2|key3=3");
    1262            0 :         modifyStringAttribute(Category::APP, tabs, overlappedTabs, "key1=Duplicated|key2=Duplicated|key3=Duplicated");
    1263            0 :         modifyStringAttribute(Category::APP, tabs, overlappedTabs, "keyInvalid.;%>%$$=1|key2=2|key3=3");
    1264            0 :         modifyStringAttribute(Category::APP, tabs, overlappedTabs, "key1=Invalid%;%$<>$$%|key2=2|key3=3");
    1265            0 :         modifyStringAttribute(Category::APP, tabs, overlappedTabs, "keyFinal1=1|keyFinal2=2|keyFinal3=3");
    1266              :         // check undo-redo
    1267            0 :         buildUndo(9);
    1268            0 :         buildRedo(9);
    1269              :     }
    1270            0 : }
    1271              : 
    1272              : 
    1273              : void
    1274            0 : InternalTestStep::changeEditMode() {
    1275            0 :     if ((myArguments.size() != 1) || (myTestSystem->getAttributesEnum().count(myArguments[0]) == 0)) {
    1276            0 :         writeError("changeEditMode", 0, "<int/attributeEnum>");
    1277              :     } else {
    1278            0 :         myCategory = Category::APP;
    1279              :         // network
    1280            0 :         if (myArguments[0] == "netedit.attrs.modes.network.grid") {
    1281            0 :             myMessageID = MID_GNE_NETWORKVIEWOPTIONS_TOGGLEGRID;
    1282            0 :         } else if (myArguments[0] == "netedit.attrs.modes.network.junctionShape") {
    1283            0 :             myMessageID = MID_GNE_NETWORKVIEWOPTIONS_TOGGLEDRAWJUNCTIONSHAPE;
    1284            0 :         } else if (myArguments[0] == "netedit.attrs.modes.network.spreadVehicle") {
    1285            0 :             myMessageID = MID_GNE_NETWORKVIEWOPTIONS_DRAWSPREADVEHICLES;
    1286            0 :         } else if (myArguments[0] == "netedit.attrs.modes.network.showDemandElements") {
    1287            0 :             myMessageID = MID_GNE_NETWORKVIEWOPTIONS_SHOWDEMANDELEMENTS;
    1288            0 :         } else if (myArguments[0] == "netedit.attrs.modes.network.selectLane") {
    1289            0 :             myMessageID = MID_GNE_NETWORKVIEWOPTIONS_SELECTEDGES;
    1290            0 :         } else if (myArguments[0] == "netedit.attrs.modes.network.showConnections") {
    1291            0 :             myMessageID = MID_GNE_NETWORKVIEWOPTIONS_SHOWCONNECTIONS;
    1292            0 :         } else if (myArguments[0] == "netedit.attrs.modes.network.hideConnetions") {
    1293            0 :             myMessageID = MID_GNE_NETWORKVIEWOPTIONS_HIDECONNECTIONS;
    1294            0 :         } else if (myArguments[0] == "netedit.attrs.modes.network.showSubAdditionals") {
    1295            0 :             myMessageID = MID_GNE_NETWORKVIEWOPTIONS_SHOWSUBADDITIONALS;
    1296            0 :         } else if (myArguments[0] == "netedit.attrs.modes.network.showTAZElements") {
    1297            0 :             myMessageID = MID_GNE_NETWORKVIEWOPTIONS_SHOWTAZELEMENTS;
    1298            0 :         } else if (myArguments[0] == "netedit.attrs.modes.network.automaticSelectJunctions") {
    1299            0 :             myMessageID = MID_GNE_NETWORKVIEWOPTIONS_EXTENDSELECTION;
    1300            0 :         } else if (myArguments[0] == "netedit.attrs.modes.network.applyAllPhases") {
    1301            0 :             myMessageID = MID_GNE_NETWORKVIEWOPTIONS_CHANGEALLPHASES;
    1302            0 :         } else if (myArguments[0] == "netedit.attrs.modes.network.mergingJunction") {
    1303            0 :             myMessageID = MID_GNE_NETWORKVIEWOPTIONS_MERGEAUTOMATICALLY;
    1304            0 :         } else if (myArguments[0] == "netedit.attrs.modes.network.showBubbles") {
    1305            0 :             myMessageID = MID_GNE_NETWORKVIEWOPTIONS_SHOWBUBBLES;
    1306            0 :         } else if (myArguments[0] == "netedit.attrs.modes.network.moveElevation") {
    1307            0 :             myMessageID = MID_GNE_NETWORKVIEWOPTIONS_MOVEELEVATION;
    1308            0 :         } else if (myArguments[0] == "netedit.attrs.modes.network.chainMode") {
    1309            0 :             myMessageID = MID_GNE_NETWORKVIEWOPTIONS_CHAINEDGES;
    1310            0 :         } else if (myArguments[0] == "netedit.attrs.modes.network.twoWayMode") {
    1311            0 :             myMessageID = MID_GNE_NETWORKVIEWOPTIONS_AUTOOPPOSITEEDGES;
    1312              :             // demand
    1313            0 :         } else if (myArguments[0] == "netedit.attrs.modes.demand.grid") {
    1314            0 :             myMessageID = MID_GNE_DEMANDVIEWOPTIONS_SHOWGRID;
    1315            0 :         } else if (myArguments[0] == "netedit.attrs.modes.demand.junctionShape") {
    1316            0 :             myMessageID = MID_GNE_DEMANDVIEWOPTIONS_TOGGLEDRAWJUNCTIONSHAPE;
    1317            0 :         } else if (myArguments[0] == "netedit.attrs.modes.demand.spreadVehicle") {
    1318            0 :             myMessageID = MID_GNE_DEMANDVIEWOPTIONS_DRAWSPREADVEHICLES;
    1319            0 :         } else if (myArguments[0] == "netedit.attrs.modes.demand.showNonInspected") {
    1320            0 :             myMessageID = MID_GNE_DEMANDVIEWOPTIONS_HIDENONINSPECTED;
    1321            0 :         } else if (myArguments[0] == "netedit.attrs.modes.demand.showShapes") {
    1322            0 :             myMessageID = MID_GNE_DEMANDVIEWOPTIONS_HIDESHAPES;
    1323            0 :         } else if (myArguments[0] == "netedit.attrs.modes.demand.showAllTrips") {
    1324            0 :             myMessageID = MID_GNE_DEMANDVIEWOPTIONS_SHOWTRIPS;
    1325            0 :         } else if (myArguments[0] == "netedit.attrs.modes.demand.showPersonPlans") {
    1326            0 :             myMessageID = MID_GNE_DEMANDVIEWOPTIONS_SHOWALLPERSONPLANS;
    1327            0 :         } else if (myArguments[0] == "netedit.attrs.modes.demand.lockPerson") {
    1328            0 :             myMessageID = MID_GNE_DEMANDVIEWOPTIONS_LOCKPERSON;
    1329            0 :         } else if (myArguments[0] == "netedit.attrs.modes.demand.showContainerPlans") {
    1330            0 :             myMessageID = MID_GNE_DEMANDVIEWOPTIONS_SHOWALLCONTAINERPLANS;
    1331            0 :         } else if (myArguments[0] == "netedit.attrs.modes.demand.lockContainer") {
    1332            0 :             myMessageID = MID_GNE_DEMANDVIEWOPTIONS_LOCKCONTAINER;
    1333            0 :         } else if (myArguments[0] == "netedit.attrs.modes.demand.showOverlappedRoutes") {
    1334            0 :             myMessageID = MID_GNE_DEMANDVIEWOPTIONS_SHOWOVERLAPPEDROUTES;
    1335              :             // data
    1336            0 :         } else if (myArguments[0] == "netedit.attrs.modes.data.junctionShape") {
    1337            0 :             myMessageID = MID_GNE_DATAVIEWOPTIONS_TOGGLEDRAWJUNCTIONSHAPE;
    1338            0 :         } else if (myArguments[0] == "netedit.attrs.modes.data.showAdditionals") {
    1339            0 :             myMessageID = MID_GNE_DATAVIEWOPTIONS_SHOWADDITIONALS;
    1340            0 :         } else if (myArguments[0] == "netedit.attrs.modes.data.showShapes") {
    1341            0 :             myMessageID = MID_GNE_DATAVIEWOPTIONS_SHOWSHAPES;
    1342            0 :         } else if (myArguments[0] == "netedit.attrs.modes.data.showDemandElements") {
    1343            0 :             myMessageID = MID_GNE_DATAVIEWOPTIONS_SHOWDEMANDELEMENTS;
    1344            0 :         } else if (myArguments[0] == "netedit.attrs.modes.data.TAZRelDrawingMode") {
    1345            0 :             myMessageID = MID_GNE_DATAVIEWOPTIONS_TAZRELDRAWING;
    1346            0 :         } else if (myArguments[0] == "netedit.attrs.modes.data.TAZFill") {
    1347            0 :             myMessageID = MID_GNE_DATAVIEWOPTIONS_TAZDRAWFILL;
    1348            0 :         } else if (myArguments[0] == "netedit.attrs.modes.data.TAZRelOnlyFrom") {
    1349            0 :             myMessageID = MID_GNE_DATAVIEWOPTIONS_TAZRELONLYFROM;
    1350            0 :         } else if (myArguments[0] == "netedit.attrs.modes.data.TAZRelOnlyTo") {
    1351            0 :             myMessageID = MID_GNE_DATAVIEWOPTIONS_TAZRELONLYTO;
    1352              :         } else {
    1353            0 :             writeError("changeEditMode", 0, "<enum>");
    1354              :         }
    1355              :     }
    1356            0 : }
    1357              : 
    1358              : 
    1359              : void
    1360            0 : InternalTestStep::saveExistentFile() {
    1361            0 :     if ((myArguments.size() != 1) ||
    1362            0 :             !checkStringArgument(myArguments[0])) {
    1363            0 :         writeError("save", 0, "<\"string\">");
    1364              :     } else {
    1365            0 :         myCategory = Category::APP;
    1366            0 :         const auto savingType = getStringArgument(myArguments[0]);
    1367            0 :         if (savingType == "network") {
    1368            0 :             myMessageID = MID_HOTKEY_CTRL_S_STOPSIMULATION_SAVENETWORK;
    1369            0 :         } else if (savingType == "additionals") {
    1370            0 :             myMessageID = MID_HOTKEY_CTRL_SHIFT_A_SAVEADDITIONALELEMENTS;
    1371            0 :         } else if (savingType == "demands") {
    1372            0 :             myMessageID = MID_HOTKEY_CTRL_SHIFT_D_SAVEDEMANDELEMENTS;
    1373            0 :         } else if (savingType == "datas") {
    1374            0 :             myMessageID = MID_HOTKEY_CTRL_SHIFT_B_SAVEDATAELEMENTS;
    1375            0 :         } else if (savingType == "meanDatas") {
    1376            0 :             myMessageID = MID_HOTKEY_CTRL_SHIFT_M_SAVEMEANDATAELEMENTS;
    1377            0 :         } else if (savingType == "sumoConfig") {
    1378            0 :             myMessageID = MID_HOTKEY_CTRL_SHIFT_S_SAVESUMOCONFIG;
    1379            0 :         } else if (savingType == "neteditConfig") {
    1380            0 :             myMessageID = MID_HOTKEY_CTRL_SHIFT_E_SAVENETEDITCONFIG;
    1381              :         } else {
    1382            0 :             writeError("save", 0, "<neteditConfig>");
    1383              :         }
    1384              :     }
    1385            0 : }
    1386              : 
    1387              : 
    1388              : void
    1389            0 : InternalTestStep::checkUndoRedo() const {
    1390            0 :     if (myArguments.size() != 1) {
    1391            0 :         writeError("checkUndoRedo", 0, "<referencePosition>");
    1392              :     } else {
    1393              :         const int numUndoRedos = 9;
    1394            0 :         buildUndo(numUndoRedos);
    1395            0 :         buildRedo(numUndoRedos);
    1396              :     }
    1397            0 : }
    1398              : 
    1399              : 
    1400              : void
    1401            0 : InternalTestStep::deleteFunction() const {
    1402            0 :     if (myArguments.size() != 0) {
    1403            0 :         writeError("delete", 0, "<>");
    1404              :     } else {
    1405            0 :         new InternalTestStep(myTestSystem, SEL_COMMAND, MID_HOTKEY_DEL, Category::APP, "delete element");
    1406              :     }
    1407            0 : }
    1408              : 
    1409              : 
    1410              : void
    1411            0 : InternalTestStep::selection() const {
    1412            0 :     if (myArguments.size() != 1 || !checkStringArgument(myArguments[0])) {
    1413            0 :         writeError("selection", 0, "<selection operation>");
    1414              :     } else {
    1415            0 :         const std::string selectionType = getStringArgument(myArguments[0]);
    1416              :         // get number of tabls
    1417              :         int numTabs = 0;
    1418            0 :         if (selectionType == "default") {
    1419            0 :             numTabs = myTestSystem->getAttributesEnum().at("netedit.attrs.frames.selection.basic.default");
    1420            0 :         } else if (selectionType == "save") {
    1421            0 :             numTabs = myTestSystem->getAttributesEnum().at("netedit.attrs.frames.selection.basic.save");
    1422            0 :         } else if (selectionType == "load") {
    1423            0 :             numTabs = myTestSystem->getAttributesEnum().at("netedit.attrs.frames.selection.basic.load");
    1424            0 :         } else if (selectionType == "add") {
    1425            0 :             numTabs = myTestSystem->getAttributesEnum().at("netedit.attrs.frames.selection.basic.add");
    1426            0 :         } else if (selectionType == "remove") {
    1427            0 :             numTabs = myTestSystem->getAttributesEnum().at("netedit.attrs.frames.selection.basic.remove");
    1428            0 :         } else if (selectionType == "keep") {
    1429            0 :             numTabs = myTestSystem->getAttributesEnum().at("netedit.attrs.frames.selection.basic.keep");
    1430            0 :         } else if (selectionType == "replace") {
    1431            0 :             numTabs = myTestSystem->getAttributesEnum().at("netedit.attrs.frames.selection.basic.replace");
    1432            0 :         } else if (selectionType == "clear") {
    1433            0 :             numTabs = myTestSystem->getAttributesEnum().at("netedit.attrs.frames.selection.basic.clear");
    1434            0 :         } else if (selectionType == "invert") {
    1435            0 :             numTabs = myTestSystem->getAttributesEnum().at("netedit.attrs.frames.selection.basic.invert");
    1436            0 :         } else if (selectionType == "invertData") {
    1437            0 :             numTabs = myTestSystem->getAttributesEnum().at("netedit.attrs.frames.selection.basic.invertData");
    1438            0 :         } else if (selectionType == "delete") {
    1439            0 :             numTabs = myTestSystem->getAttributesEnum().at("netedit.attrs.frames.selection.basic.delete");
    1440              :         }
    1441              :         // focus frame
    1442            0 :         new InternalTestStep(myTestSystem, SEL_COMMAND, MID_HOTKEY_SHIFT_F12_FOCUSUPPERELEMENT, Category::APP, "focus selection frame");
    1443              :         // jump to the element
    1444            0 :         for (int i = 0; i < numTabs; i++) {
    1445            0 :             buildPressKeyEvent(Category::APP, "tab", false);
    1446              :         }
    1447            0 :         if (selectionType == "save") {
    1448            0 :             buildPressKeyEvent(Category::APP, "enter", false);
    1449              :             // complete
    1450            0 :         } else if (selectionType == "load") {
    1451            0 :             buildPressKeyEvent(Category::APP, "enter", false);
    1452              :             // complete
    1453              :         } else {
    1454            0 :             buildPressKeyEvent(Category::APP, "space", true);
    1455              :         }
    1456              :     }
    1457            0 : }
    1458              : 
    1459              : 
    1460              : void
    1461            0 : InternalTestStep::selectNetworkItems() const  {
    1462            0 :     if (myArguments.size() != 3 || !checkStringArgument(myArguments[0]) ||
    1463            0 :             !checkStringArgument(myArguments[1]) || !checkStringArgument(myArguments[2])) {
    1464            0 :         writeError("selectNetworkItems", 0, "<element/int, \"attribute\", \"value\">");
    1465              :     } else {
    1466            0 :         const std::string element = getStringArgument(myArguments[0]);
    1467            0 :         const std::string attribute = getStringArgument(myArguments[1]);
    1468            0 :         const std::string value = getStringArgument(myArguments[2]);
    1469              :         // focus frame
    1470            0 :         new InternalTestStep(myTestSystem, SEL_COMMAND, MID_HOTKEY_SHIFT_F12_FOCUSUPPERELEMENT, Category::APP, "focus selelection frame");
    1471              :         // got to type
    1472            0 :         for (int i = 0; i < myTestSystem->getAttributesEnum().at("netedit.attrs.frames.selection.networkItem.type"); i++) {
    1473            0 :             buildPressKeyEvent(Category::APP, "tab", false);
    1474              :         }
    1475              :         // set network element
    1476            0 :         for (const char c : "Network elements") {
    1477            0 :             buildPressKeyEvent(Category::APP, {c}, false);
    1478              :         }
    1479              :         // show info
    1480              :         std::cout << "Network elements" << std::endl;
    1481              :         // got to type
    1482            0 :         for (int i = 0; i < myTestSystem->getAttributesEnum().at("netedit.attrs.frames.selection.networkItem.subType"); i++) {
    1483            0 :             buildPressKeyEvent(Category::APP, "tab", false);
    1484              :         }
    1485              :         // set network element
    1486            0 :         for (const char c : element) {
    1487            0 :             buildPressKeyEvent(Category::APP, {c}, false);
    1488              :         }
    1489              :         // show info
    1490              :         std::cout << element << std::endl;
    1491              :         // got to attribute
    1492            0 :         for (int i = 0; i < myTestSystem->getAttributesEnum().at("netedit.attrs.frames.selection.networkItem.attribute"); i++) {
    1493            0 :             buildPressKeyEvent(Category::APP, "tab", false);
    1494              :         }
    1495              :         // set attribute
    1496            0 :         for (const char c : attribute) {
    1497            0 :             buildPressKeyEvent(Category::APP, {c}, false);
    1498              :         }
    1499              :         // show info
    1500              :         std::cout << attribute << std::endl;
    1501              :         // got to value
    1502            0 :         for (int i = 0; i < myTestSystem->getAttributesEnum().at("netedit.attrs.frames.selection.networkItem.value"); i++) {
    1503            0 :             buildPressKeyEvent(Category::APP, "tab", false);
    1504              :         }
    1505              :         // set value
    1506            0 :         for (const char c : value) {
    1507            0 :             buildPressKeyEvent(Category::APP, {c}, false);
    1508              :         }
    1509              :         // show info
    1510              :         std::cout << value << std::endl;
    1511              :         // press enter to confirm changes (updating view)
    1512            0 :         buildPressKeyEvent(Category::APP, "enter", true);
    1513              :     }
    1514            0 : }
    1515              : 
    1516              : 
    1517              : void
    1518            0 : InternalTestStep::lockSelection() const {
    1519            0 :     if (myArguments.size() != 1 || !checkIntArgument(myArguments[0])) {
    1520            0 :         writeError("lockSelection", 0, "<element/int, \"attribute\", \"value\">");
    1521              :     } else {
    1522              :         // get argument
    1523            0 :         const auto lockType = getIntArgument(myArguments[0]);
    1524              :         // continue depending of lock type
    1525            0 :         if (lockType == myTestSystem->getAttributesEnum().at("netedit.attrs.selection.lockSelectionNetwork.junctions")) {
    1526            0 :             new InternalTestStep(myTestSystem, SEL_COMMAND, MID_GNE_LOCK_JUNCTION, Category::APP, "lock junctions");
    1527            0 :         } else if (lockType == myTestSystem->getAttributesEnum().at("netedit.attrs.selection.lockSelectionNetwork.edges")) {
    1528            0 :             new InternalTestStep(myTestSystem, SEL_COMMAND, MID_GNE_LOCK_EDGE, Category::APP, "lock edges");
    1529            0 :         } else if (lockType == myTestSystem->getAttributesEnum().at("netedit.attrs.selection.lockSelectionNetwork.lanes")) {
    1530            0 :             new InternalTestStep(myTestSystem, SEL_COMMAND, MID_GNE_LOCK_LANE, Category::APP, "lock lanes");
    1531            0 :         } else if (lockType == myTestSystem->getAttributesEnum().at("netedit.attrs.selection.lockSelectionNetwork.connections")) {
    1532            0 :             new InternalTestStep(myTestSystem, SEL_COMMAND, MID_GNE_LOCK_CONNECTION, Category::APP, "lock connections");
    1533            0 :         } else if (lockType == myTestSystem->getAttributesEnum().at("netedit.attrs.selection.lockSelectionNetwork.crossings")) {
    1534            0 :             new InternalTestStep(myTestSystem, SEL_COMMAND, MID_GNE_LOCK_CROSSING, Category::APP, "lock crossings");
    1535            0 :         } else if (lockType == myTestSystem->getAttributesEnum().at("netedit.attrs.selection.lockSelectionNetwork.walkingAreas")) {
    1536            0 :             new InternalTestStep(myTestSystem, SEL_COMMAND, MID_GNE_LOCK_WALKINGAREA, Category::APP, "lock walking areas");
    1537            0 :         } else if (lockType == myTestSystem->getAttributesEnum().at("netedit.attrs.selection.lockSelectionNetwork.additionals")) {
    1538            0 :             new InternalTestStep(myTestSystem, SEL_COMMAND, MID_GNE_LOCK_ADDITIONALELEMENT, Category::APP, "lock additionals");
    1539            0 :         } else if (lockType == myTestSystem->getAttributesEnum().at("netedit.attrs.selection.lockSelectionNetwork.tazs")) {
    1540            0 :             new InternalTestStep(myTestSystem, SEL_COMMAND, MID_GNE_LOCK_TAZ, Category::APP, "lock TAZs");
    1541            0 :         } else if (lockType == myTestSystem->getAttributesEnum().at("netedit.attrs.selection.lockSelectionNetwork.wires")) {
    1542            0 :             new InternalTestStep(myTestSystem, SEL_COMMAND, MID_GNE_LOCK_WIRE, Category::APP, "lock wires");
    1543            0 :         } else if (lockType == myTestSystem->getAttributesEnum().at("netedit.attrs.selection.lockSelectionNetwork.polygons")) {
    1544            0 :             new InternalTestStep(myTestSystem, SEL_COMMAND, MID_GNE_LOCK_POLYGON, Category::APP, "lock polygons");
    1545            0 :         } else if (lockType == myTestSystem->getAttributesEnum().at("netedit.attrs.selection.lockSelectionNetwork.pois")) {
    1546            0 :             new InternalTestStep(myTestSystem, SEL_COMMAND, MID_GNE_LOCK_POI, Category::APP, "lock POIs");
    1547            0 :         } else if (lockType == myTestSystem->getAttributesEnum().at("netedit.attrs.selection.lockSelectionNetwork.walkableAreas")) {
    1548            0 :             new InternalTestStep(myTestSystem, SEL_COMMAND, MID_GNE_LOCK_JPS_WALKABLEAREA, Category::APP, "lock walkableAreas");
    1549            0 :         } else if (lockType == myTestSystem->getAttributesEnum().at("netedit.attrs.selection.lockSelectionNetwork.obstacles")) {
    1550            0 :             new InternalTestStep(myTestSystem, SEL_COMMAND, MID_GNE_LOCK_JPS_OBSTACLE, Category::APP, "lock obstacles");
    1551            0 :         } else if (lockType == myTestSystem->getAttributesEnum().at("netedit.attrs.selection.lockSelectionNetwork.selected")) {
    1552            0 :             new InternalTestStep(myTestSystem, SEL_COMMAND, MID_GNE_LOCK_SELECTEDELEMENTS, Category::APP, "lock selected elements");
    1553            0 :         } else if (lockType == myTestSystem->getAttributesEnum().at("netedit.attrs.selection.lockSelectionNetwork.lockAll")) {
    1554            0 :             new InternalTestStep(myTestSystem, SEL_COMMAND, MID_GNE_LOCK_ALLELEMENTS, Category::APP, "lock all elements");
    1555            0 :         } else if (lockType == myTestSystem->getAttributesEnum().at("netedit.attrs.selection.lockSelectionNetwork.unlockAll")) {
    1556            0 :             new InternalTestStep(myTestSystem, SEL_COMMAND, MID_GNE_UNLOCK_ALLELEMENTS, Category::APP, "unlock all elements");
    1557              :         }
    1558              :     }
    1559            0 : }
    1560              : 
    1561              : 
    1562              : void
    1563            0 : InternalTestStep::selectionRectangle() const {
    1564            0 :     if (myArguments.size() != 3 || (myTestSystem->getViewPositions().count(myArguments[1]) == 0) ||
    1565            0 :             (myTestSystem->getViewPositions().count(myArguments[2]) == 0)) {
    1566            0 :         writeError("selectionRectangle", 0, "<viewPosition, viewPosition>");
    1567              :     } else {
    1568              :         // get position
    1569            0 :         const auto& from = myTestSystem->getViewPositions().at(myArguments[1]);
    1570            0 :         const auto& to = myTestSystem->getViewPositions().at(myArguments[2]);
    1571              :         // go to selection mode
    1572            0 :         new InternalTestStep(myTestSystem, SEL_COMMAND, MID_HOTKEY_S_MODE_STOPSIMULATION_SELECT, Category::APP, "selection mode");
    1573              :         // drag and drop
    1574            0 :         buildMouseDragDrop(from, 0, 0, to, 0, 0, "shift");
    1575              :     }
    1576            0 : }
    1577              : 
    1578              : 
    1579              : void
    1580            0 : InternalTestStep::createDataSet() const {
    1581            0 :     if ((myArguments.size() != 1) || !checkStringArgument(myArguments[0])) {
    1582            0 :         writeError("createDataSet", 0, "<dataSetId>");
    1583              :     } else {
    1584              :         // get dataSetId
    1585            0 :         const auto& dataSetId = getStringArgument(myArguments[0]);
    1586              :         // show info
    1587              :         std::cout << dataSetId << std::endl;
    1588              :         // focus frame
    1589            0 :         new InternalTestStep(myTestSystem, SEL_COMMAND, MID_HOTKEY_SHIFT_F12_FOCUSUPPERELEMENT, Category::APP, "focus data frame");
    1590              :         // jump to select additional argument
    1591            0 :         for (int i = 0; i < 2; i++) {
    1592            0 :             buildPressKeyEvent(Category::APP, "tab", false);
    1593              :         }
    1594              :         // create new dataSet
    1595            0 :         buildPressKeyEvent(Category::APP, "space", true);
    1596              :         // write additional character by character
    1597            0 :         for (const char c : dataSetId) {
    1598            0 :             buildPressKeyEvent(Category::APP, {c}, false);
    1599              :         }
    1600              :         // go to create new dataSet
    1601            0 :         buildPressKeyEvent(Category::APP, "tab", false);
    1602              :         // press enter to confirm changes (updating view)
    1603            0 :         buildPressKeyEvent(Category::APP, "space", true);
    1604              :     }
    1605            0 : }
    1606              : 
    1607              : 
    1608              : void
    1609            0 : InternalTestStep::createDataInterval() const {
    1610            0 :     if ((myArguments.size() != 2) || !checkStringArgument(myArguments[0]) || !checkStringArgument(myArguments[1])) {
    1611            0 :         writeError("createDataInterval", 0, "<begin, end>");
    1612              :     } else {
    1613              :         // get begin and end
    1614            0 :         const auto& begin = getStringArgument(myArguments[0]);
    1615            0 :         const auto& end = getStringArgument(myArguments[1]);
    1616              :         // show info
    1617              :         std::cout << begin << std::endl;
    1618              :         std::cout << end << std::endl;
    1619              :         // focus frame
    1620            0 :         new InternalTestStep(myTestSystem, SEL_COMMAND, MID_HOTKEY_SHIFT_F12_FOCUSUPPERELEMENT, Category::APP, "focus data frame");
    1621              :         // jump to create interval
    1622            0 :         for (int i = 0; i < 6; i++) {
    1623            0 :             buildPressKeyEvent(Category::APP, "tab", false);
    1624              :         }
    1625              :         // create new interval
    1626            0 :         buildPressKeyEvent(Category::APP, "space", true);
    1627              :         // go to begin
    1628            0 :         buildPressKeyEvent(Category::APP, "tab", false);
    1629              :         // write begin character by character
    1630            0 :         for (const char c : begin) {
    1631            0 :             buildPressKeyEvent(Category::APP, {c}, false);
    1632              :         }
    1633              :         // go to begin
    1634            0 :         buildPressKeyEvent(Category::APP, "tab", false);
    1635              :         // write end character by character
    1636            0 :         for (const char c : end) {
    1637            0 :             buildPressKeyEvent(Category::APP, {c}, false);
    1638              :         }
    1639              :         // go to create button
    1640            0 :         buildPressKeyEvent(Category::APP, "tab", false);
    1641              :         // press button
    1642            0 :         buildPressKeyEvent(Category::APP, "space", true);
    1643              :     }
    1644            0 : }
    1645              : 
    1646              : 
    1647              : void
    1648            0 : InternalTestStep::openAboutDialog() {
    1649            0 :     if (myArguments.size() != 0) {
    1650            0 :         writeError("openAboutDialog", 0, "<>");
    1651              :     } else {
    1652            0 :         myCategory = Category::APP;
    1653            0 :         myMessageID = MID_HOTKEY_F12_ABOUT;
    1654              :         // close dialog
    1655            0 :         new InternalTestStep(myTestSystem, new DialogArgument(DialogType::ABOUT, DialogArgument::Action::ACCEPT), "close about dialog");
    1656              :     }
    1657            0 : }
    1658              : 
    1659              : 
    1660              : void
    1661            0 : InternalTestStep::loadFile() {
    1662            0 :     if ((myArguments.size() != 5) || !checkIntArgument(myArguments[4])) {
    1663            0 :         writeError("loadFile", 0, "<referencePosition, type, file, extension, extensionIndex>");
    1664              :     } else {
    1665            0 :         myCategory = Category::APP;
    1666              :         // get type and file
    1667            0 :         const auto type = getStringArgument(myArguments[1]);
    1668            0 :         const auto file = getStringArgument(myArguments[2]);
    1669            0 :         const auto extension = getStringArgument(myArguments[3]);
    1670            0 :         const auto extensionIndex = getIntArgument(myArguments[4]);
    1671              :         // get working directory
    1672            0 :         std::string workingDirectory = FXSystem::getCurrentDirectory().text();
    1673            0 :         const auto sandboxDirectory = std::getenv("TEXTTEST_SANDBOX");
    1674            0 :         if (sandboxDirectory) {
    1675              :             workingDirectory = sandboxDirectory;
    1676              :         }
    1677              :         // continue depending of type
    1678            0 :         if (type == "neteditConfig") {
    1679            0 :             myMessageID = MID_HOTKEY_CTRL_E_EDITSELECTION_LOADNETEDITCONFIG;
    1680            0 :         } else if (type == "sumoConfig") {
    1681            0 :             myMessageID = MID_HOTKEY_CTRL_M_OPENSUMOCONFIG;
    1682            0 :         } else if (type == "netconvertConfig") {
    1683            0 :             myMessageID = MID_HOTKEY_CTRL_SHIFT_O_OPENNETCONVERTFILE;
    1684            0 :         } else if (type == "network") {
    1685            0 :             myMessageID = MID_HOTKEY_CTRL_O_OPENSIMULATION_OPENNETWORK;
    1686            0 :         } else if (type == "trafficLights") {
    1687            0 :             myMessageID = MID_HOTKEY_CTRL_K_OPENTLSPROGRAMS;
    1688            0 :         } else if (type == "edgeTypes") {
    1689            0 :             myMessageID = MID_HOTKEY_CTRL_H_APPSETTINGS_OPENEDGETYPES;
    1690            0 :         } else if (type == "additional") {
    1691            0 :             myMessageID = MID_HOTKEY_CTRL_A_STARTSIMULATION_OPENADDITIONALELEMENTS;
    1692            0 :         } else if (type == "demand") {
    1693            0 :             myMessageID = MID_HOTKEY_CTRL_D_SINGLESIMULATIONSTEP_OPENDEMANDELEMENTS;
    1694            0 :         } else if (type == "data") {
    1695            0 :             myMessageID = MID_HOTKEY_CTRL_B_EDITBREAKPOINT_OPENDATAELEMENTS;
    1696            0 :         } else if (type == "meanData") {
    1697            0 :             myMessageID = MID_GNE_TOOLBARFILE_OPENMEANDATAELEMENTS;
    1698              :         } else {
    1699            0 :             WRITE_ERRORF("Invalid type '%' used in function loadFile", type);
    1700              :         }
    1701              :         // write info
    1702              :         std::cout << file << "." << extension << std::endl;
    1703              :         // set filename dialog
    1704            0 :         new InternalTestStep(myTestSystem, new DialogArgument(DialogType::FILE, workingDirectory + "/" + file + "." + extension, extensionIndex), "filepath");
    1705            0 :         new InternalTestStep(myTestSystem, new DialogArgument(DialogType::FILE, DialogArgument::Action::ACCEPT), "go to directory");
    1706              :     }
    1707            0 : }
    1708              : 
    1709              : 
    1710              : void
    1711            0 : InternalTestStep::saveNewFile() {
    1712            0 :     if ((myArguments.size() != 4) || !checkIntArgument(myArguments[3])) {
    1713            0 :         writeError("saveNewFile", 0, "<referencePosition, type, extension, extensionIndex>");
    1714              :     } else {
    1715            0 :         myCategory = Category::APP;
    1716              :         // get type and file
    1717            0 :         const auto type = getStringArgument(myArguments[1]);
    1718            0 :         const auto extension = getStringArgument(myArguments[2]);
    1719            0 :         const auto extensionIndex = getIntArgument(myArguments[3]);
    1720              :         std::string file;
    1721              :         // get working directory
    1722            0 :         std::string workingDirectory = FXSystem::getCurrentDirectory().text();
    1723            0 :         const auto sandboxDirectory = std::getenv("TEXTTEST_SANDBOX");
    1724            0 :         if (sandboxDirectory) {
    1725              :             workingDirectory = sandboxDirectory;
    1726              :         }
    1727              :         // continue depending of type
    1728            0 :         if (type == "neteditConfig") {
    1729            0 :             myMessageID = MID_HOTKEY_CTRL_SHIFT_E_SAVENETEDITCONFIG;
    1730            0 :             file = "netedit_B." + extension;
    1731            0 :         } else if (type == "sumoConfig") {
    1732            0 :             myMessageID = MID_HOTKEY_CTRL_SHIFT_S_SAVESUMOCONFIG;
    1733            0 :             file = "sumo_B." + extension;
    1734            0 :         } else if (type == "netconvertConfig") {
    1735            0 :             myMessageID = MID_HOTKEY_CTRL_L_SAVEASPLAINXML;
    1736            0 :             file = "netconvert_B." + extension;
    1737            0 :         } else if (type == "network") {
    1738            0 :             myMessageID = MID_HOTKEY_CTRL_S_STOPSIMULATION_SAVENETWORK;
    1739            0 :             file = "input_net_B." + extension;
    1740            0 :         } else if (type == "trafficLights") {
    1741            0 :             myMessageID = MID_HOTKEY_CTRL_SHIFT_K_SAVETLS;
    1742            0 :             file = "trafficlights_B." + extension;
    1743            0 :         } else if (type == "edgeTypes") {
    1744            0 :             myMessageID = MID_HOTKEY_CTRL_SHIFT_H_SAVEEDGETYPES;
    1745            0 :             file = "input_edgetypes_B." + extension;
    1746              :         } else {
    1747            0 :             WRITE_ERRORF("Invalid type '%' used in function loadFile", type);
    1748              :         }
    1749              :         // write info
    1750              :         std::cout << file << std::endl;
    1751              :         // set filename dialog
    1752            0 :         new InternalTestStep(myTestSystem, new DialogArgument(DialogType::FILE, workingDirectory + "/" + file, extensionIndex), "filepath");
    1753            0 :         new InternalTestStep(myTestSystem, new DialogArgument(DialogType::FILE, DialogArgument::Action::ACCEPT), "go to directory");
    1754              :     }
    1755            0 : }
    1756              : 
    1757              : 
    1758              : void
    1759            0 : InternalTestStep::saveFileAs() {
    1760            0 :     if ((myArguments.size() != 4) || !checkIntArgument(myArguments[3])) {
    1761            0 :         writeError("saveFileAs", 0, "<referencePosition, type, extension, extensionIndex>");
    1762              :     } else {
    1763            0 :         myCategory = Category::APP;
    1764              :         // get type and file
    1765            0 :         const auto type = getStringArgument(myArguments[1]);
    1766            0 :         const auto extension = getStringArgument(myArguments[2]);
    1767            0 :         const auto extensionIndex = getIntArgument(myArguments[3]);
    1768              :         std::string file;
    1769              :         // get working directory
    1770            0 :         std::string workingDirectory = FXSystem::getCurrentDirectory().text();
    1771            0 :         const auto sandboxDirectory = std::getenv("TEXTTEST_SANDBOX");
    1772            0 :         if (sandboxDirectory) {
    1773              :             workingDirectory = sandboxDirectory;
    1774              :         }
    1775              :         // continue depending of type
    1776            0 :         if (type == "neteditConfig") {
    1777            0 :             myMessageID = MID_GNE_TOOLBARFILE_SAVENETEDITCONFIG_AS;
    1778            0 :             file = "netedit_B." + extension;
    1779            0 :         } else if (type == "sumoConfig") {
    1780            0 :             myMessageID = MID_GNE_TOOLBARFILE_SAVESUMOCONFIG_AS;
    1781            0 :             file = "sumo_B." + extension;
    1782            0 :         } else if (type == "network") {
    1783            0 :             myMessageID = MID_GNE_TOOLBARFILE_SAVENETWORK_AS;
    1784            0 :             file = "input_net_B." + extension;
    1785            0 :         } else if (type == "joinedJunctions") {
    1786            0 :             myMessageID = MID_GNE_SAVEJOINEDJUNCTIONS;
    1787            0 :             file = "joinedjunctions_B." + extension;
    1788            0 :         } else if (type == "trafficLights") {
    1789            0 :             myMessageID = MID_GNE_TOOLBARFILE_SAVETLSPROGRAMS_AS;
    1790            0 :             file = "trafficlights_B." + extension;
    1791            0 :         } else if (type == "edgeTypes") {
    1792            0 :             myMessageID = MID_GNE_TOOLBARFILE_SAVEEDGETYPES_AS;
    1793            0 :             file = "edgetypes_B." + extension;
    1794            0 :         } else if (type == "jupedsim") {
    1795            0 :             myMessageID = MID_GNE_TOOLBARFILE_SAVEJUPEDSIMELEMENTS_AS;
    1796            0 :             file = "jupedsims_B." + extension;
    1797            0 :         } else if (type == "additional") {
    1798            0 :             file = "input_additionals_B." + extension;
    1799            0 :             throw ProcessError("not finish");
    1800            0 :         } else if (type == "demand") {
    1801            0 :             file = "input_routes_B." + extension;
    1802            0 :             throw ProcessError("not finish");
    1803            0 :         } else if (type == "data") {
    1804            0 :             file = "input_datas_B." + extension;
    1805            0 :             throw ProcessError("not finish");
    1806            0 :         } else if (type == "meanData") {
    1807            0 :             file = "input_meandatas_B." + extension;
    1808            0 :             throw ProcessError("not finish");
    1809              :         } else {
    1810            0 :             WRITE_ERRORF("Invalid type '%' used in function loadFile", type);
    1811              :         }
    1812              :         // write info
    1813              :         std::cout << file << std::endl;
    1814              :         // set filename dialog
    1815            0 :         new InternalTestStep(myTestSystem, new DialogArgument(DialogType::FILE, workingDirectory + "/" + file, extensionIndex), "filepath");
    1816            0 :         new InternalTestStep(myTestSystem, new DialogArgument(DialogType::FILE, DialogArgument::Action::ACCEPT), "go to directory");
    1817              :     }
    1818            0 : }
    1819              : 
    1820              : 
    1821              : void
    1822            0 : InternalTestStep::saveUnifiedFileAs() {
    1823            0 :     if ((myArguments.size() != 4) || !checkIntArgument(myArguments[3])) {
    1824            0 :         writeError("saveUnifiedFileAs", 0, "<referencePosition, type, extension, extensionIndex>");
    1825              :     } else {
    1826            0 :         myCategory = Category::APP;
    1827              :         // get type and file
    1828            0 :         const auto type = getStringArgument(myArguments[1]);
    1829            0 :         const auto extension = getStringArgument(myArguments[2]);
    1830            0 :         const auto extensionIndex = getIntArgument(myArguments[3]);
    1831              :         std::string file;
    1832              :         // get working directory
    1833            0 :         std::string workingDirectory = FXSystem::getCurrentDirectory().text();
    1834            0 :         const auto sandboxDirectory = std::getenv("TEXTTEST_SANDBOX");
    1835            0 :         if (sandboxDirectory) {
    1836              :             workingDirectory = sandboxDirectory;
    1837              :         }
    1838              :         // continue depending of type
    1839            0 :         if (type == "additional") {
    1840            0 :             myMessageID = MID_GNE_TOOLBARFILE_SAVEADDITIONALELEMENTS_UNIFIED;
    1841            0 :             file = "input_additionals_B." + extension;;
    1842            0 :         } else if (type == "demand") {
    1843            0 :             myMessageID = MID_GNE_TOOLBARFILE_SAVEDEMANDELEMENTS_UNIFIED;
    1844            0 :             file = "input_routes_B." + extension;
    1845            0 :         } else if (type == "data") {
    1846            0 :             myMessageID = MID_GNE_TOOLBARFILE_SAVEDATAELEMENTS_UNIFIED;
    1847            0 :             file = "input_datas_B." + extension;
    1848            0 :         } else if (type == "meanData") {
    1849            0 :             myMessageID = MID_GNE_TOOLBARFILE_SAVEMEANDATAELEMENTS_UNIFIED;
    1850            0 :             file = "input_meandatas_B." + extension;
    1851              :         } else {
    1852            0 :             WRITE_ERRORF("Invalid type '%' used in function loadFile", type);
    1853              :         }
    1854              :         // write info
    1855              :         std::cout << file << std::endl;
    1856              :         // set filename dialog
    1857            0 :         new InternalTestStep(myTestSystem, new DialogArgument(DialogType::FILE, workingDirectory + "/" + file, extensionIndex), "filepath");
    1858            0 :         new InternalTestStep(myTestSystem, new DialogArgument(DialogType::FILE, DialogArgument::Action::ACCEPT), "go to directory");
    1859              :     }
    1860            0 : }
    1861              : 
    1862              : 
    1863              : void
    1864            0 : InternalTestStep::reloadFile() {
    1865            0 :     if (myArguments.size() != 3) {
    1866            0 :         writeError("reloadFile", 0, "<referencePosition, type, bool>");
    1867              :     } else {
    1868            0 :         myCategory = Category::APP;
    1869              :         // get type and file
    1870            0 :         const auto type = getStringArgument(myArguments[1]);
    1871              :         // continue depending of type
    1872            0 :         if (type == "neteditConfig") {
    1873            0 :             myMessageID = MID_GNE_TOOLBARFILE_RELOAD_NETEDITCONFIG;
    1874            0 :         } else if (type == "sumoConfig") {
    1875            0 :             myMessageID = MID_GNE_TOOLBARFILE_RELOAD_SUMOCONFIG;
    1876            0 :         } else if (type == "network") {
    1877            0 :             myMessageID = MID_GNE_TOOLBARFILE_RELOADNETWORK;
    1878            0 :         } else if (type == "edgeTypes") {
    1879            0 :             myMessageID = MID_GNE_TOOLBARFILE_RELOAD_EDGETYPES;
    1880            0 :         } else if (type == "trafficLights") {
    1881            0 :             myMessageID = MID_GNE_TOOLBARFILE_RELOAD_TLSPROGRAMS;
    1882            0 :         } else if (type == "additional") {
    1883            0 :             myMessageID = MID_GNE_TOOLBARFILE_RELOAD_ADDITIONALELEMENTS;
    1884            0 :         } else if (type == "demand") {
    1885            0 :             myMessageID = MID_GNE_TOOLBARFILE_RELOAD_DEMANDELEMENTS;
    1886            0 :         } else if (type == "data") {
    1887            0 :             myMessageID = MID_GNE_TOOLBARFILE_RELOAD_DATAELEMENTS;
    1888            0 :         } else if (type == "meanData") {
    1889            0 :             myMessageID = MID_GNE_TOOLBARFILE_RELOAD_MEANDATAELEMENTS;
    1890              :         } else {
    1891            0 :             WRITE_ERRORF("Invalid type '%' used in function reloadFile", type);
    1892              :         }
    1893              :     }
    1894            0 : }
    1895              : 
    1896              : 
    1897              : void
    1898            0 : InternalTestStep::selectEdgeType() {
    1899            0 :     if (myArguments.size() != 0) {
    1900            0 :         writeError("selectEdgeType", 0, "<>");
    1901              :     } else {
    1902            0 :         new InternalTestStep(myTestSystem, SEL_COMMAND, MID_HOTKEY_SHIFT_F12_FOCUSUPPERELEMENT, Category::APP, "focus edge frame");
    1903              :         // got to type
    1904            0 :         for (int i = 0; i < myTestSystem->getAttributesEnum().at("netedit.attrs.edge.edgeType.select"); i++) {
    1905            0 :             buildPressKeyEvent(Category::APP, "tab", false);
    1906              :         }
    1907              :         // select edge type
    1908            0 :         buildPressKeyEvent(Category::APP, "space", true);
    1909              :     }
    1910            0 : }
    1911              : 
    1912              : 
    1913              : void
    1914            0 : InternalTestStep::createNewEdgeType() {
    1915            0 :     if (myArguments.size() != 1 && checkBoolArgument(myArguments[0])) {
    1916            0 :         writeError("createNewEdgeType", 0, "<bool>");
    1917              :     } else {
    1918            0 :         const auto existent = getBoolArgument(myArguments[0]);
    1919            0 :         new InternalTestStep(myTestSystem, SEL_COMMAND, MID_HOTKEY_SHIFT_F12_FOCUSUPPERELEMENT, Category::APP, "focus edge frame");
    1920            0 :         if (existent) {
    1921            0 :             for (int i = 0; i < myTestSystem->getAttributesEnum().at("netedit.attrs.edge.edgeType.createExistent"); i++) {
    1922            0 :                 buildPressKeyEvent(Category::APP, "tab", false);
    1923              :             }
    1924              :         } else {
    1925            0 :             for (int i = 0; i < myTestSystem->getAttributesEnum().at("netedit.attrs.edge.edgeType.createNew"); i++) {
    1926            0 :                 buildPressKeyEvent(Category::APP, "tab", false);
    1927              :             }
    1928              :         }
    1929              :         // select edge type
    1930            0 :         buildPressKeyEvent(Category::APP, "space", true);
    1931              :     }
    1932            0 : }
    1933              : 
    1934              : 
    1935              : void
    1936            0 : InternalTestStep::overwritingAccept() {
    1937            0 :     myCategory = Category::DIALOG;
    1938            0 :     myDialogArgument = new DialogArgument(DialogType::OVERWRITE, DialogArgument::Action::ACCEPT);
    1939            0 :     myDescription = "accept overwriting";
    1940            0 : }
    1941              : 
    1942              : 
    1943              : void
    1944            0 : InternalTestStep::overwritingCancel() {
    1945            0 :     myCategory = Category::DIALOG;
    1946            0 :     myDialogArgument = new DialogArgument(DialogType::OVERWRITE, DialogArgument::Action::CANCEL);
    1947            0 :     myDescription = "discard overwriting";
    1948            0 : }
    1949              : 
    1950              : 
    1951              : void
    1952            0 : InternalTestStep::overwritingAbort() {
    1953            0 :     myCategory = Category::DIALOG;
    1954            0 :     myDialogArgument = new DialogArgument(DialogType::OVERWRITE, DialogArgument::Action::ABORT);
    1955            0 :     myDescription = "abort overwriting";
    1956            0 : }
    1957              : 
    1958              : 
    1959              : void
    1960            0 : InternalTestStep::overwritingApplyToAll() {
    1961            0 :     myCategory = Category::DIALOG;
    1962            0 :     myDialogArgument = new DialogArgument(DialogType::OVERWRITE, "applyToAll");
    1963            0 :     myDescription = "apply to all";
    1964            0 : }
    1965              : 
    1966              : 
    1967              : void
    1968            0 : InternalTestStep::undo() const {
    1969            0 :     if ((myArguments.size() != 2) || !checkIntArgument(myArguments[1])) {
    1970            0 :         writeError("undo", 0, "<referencePosition, int>");
    1971              :     } else {
    1972              :         // do undo
    1973            0 :         buildUndo(getIntArgument(myArguments[1]));
    1974              :     }
    1975            0 : }
    1976              : 
    1977              : 
    1978              : void
    1979            0 : InternalTestStep::redo() const {
    1980            0 :     if ((myArguments.size() != 2) || !checkIntArgument(myArguments[1])) {
    1981            0 :         writeError("redo", 0, "<referencePosition, int>");
    1982              :     } else {
    1983              :         // do redo
    1984            0 :         buildRedo(getIntArgument(myArguments[1]));
    1985              :     }
    1986            0 : }
    1987              : 
    1988              : 
    1989              : void
    1990            0 : InternalTestStep::changeSupermode() {
    1991            0 :     if ((myArguments.size() != 1) ||
    1992            0 :             !checkStringArgument(myArguments[0])) {
    1993            0 :         writeError("supermode", 0, "<\"string\">");
    1994              :     } else {
    1995            0 :         myCategory = Category::APP;
    1996            0 :         const std::string supermode = getStringArgument(myArguments[0]);
    1997            0 :         if (supermode == "network") {
    1998            0 :             myMessageID = MID_HOTKEY_F2_SUPERMODE_NETWORK;
    1999            0 :         } else if (supermode == "demand") {
    2000            0 :             myMessageID = MID_HOTKEY_F3_SUPERMODE_DEMAND;
    2001            0 :         } else if (supermode == "data") {
    2002            0 :             myMessageID = MID_HOTKEY_F4_SUPERMODE_DATA;
    2003              :         } else {
    2004            0 :             writeError("supermode", 0, "<network/demand/data>");
    2005              :         }
    2006              :     }
    2007            0 : }
    2008              : 
    2009              : 
    2010              : void
    2011            0 : InternalTestStep::changeMode() {
    2012            0 :     if ((myArguments.size() != 1) ||
    2013            0 :             !checkStringArgument(myArguments[0])) {
    2014            0 :         writeError("changeMode", 0, "<\"string\">");
    2015              :     } else {
    2016              :         // set category and enable upate view
    2017            0 :         myCategory = Category::APP;
    2018            0 :         myUpdateView = true;
    2019              :         // get mode
    2020            0 :         const std::string mode = getStringArgument(myArguments[0]);
    2021              :         // set description
    2022            0 :         myDescription = "Change mode to '" + mode + "'";
    2023              :         // continue depending of mode
    2024            0 :         if (mode == "inspect") {
    2025            0 :             myMessageID = MID_HOTKEY_I_MODE_INSPECT;
    2026            0 :         } else if (mode == "delete") {
    2027            0 :             myMessageID = MID_HOTKEY_D_MODE_SINGLESIMULATIONSTEP_DELETE;
    2028            0 :         } else if (mode == "select") {
    2029            0 :             myMessageID = MID_HOTKEY_S_MODE_STOPSIMULATION_SELECT;
    2030            0 :         } else if (mode == "move") {
    2031            0 :             myMessageID = MID_HOTKEY_M_MODE_MOVE_MEANDATA;
    2032            0 :         } else if ((mode == "createEdge") || (mode == "edgeData")) {
    2033            0 :             myMessageID = MID_HOTKEY_E_MODE_EDGE_EDGEDATA;
    2034            0 :         } else if ((mode == "trafficLight") || (mode == "type") || (mode == "TLS")) {
    2035            0 :             myMessageID = MID_HOTKEY_T_MODE_TLS_TYPE;
    2036            0 :         } else if ((mode == "connection") || (mode == "container")) {
    2037            0 :             myMessageID = MID_HOTKEY_C_MODE_CONNECT_CONTAINER;
    2038            0 :         } else if ((mode == "prohibition") || (mode == "containerPlan")) {
    2039            0 :             myMessageID = MID_HOTKEY_H_MODE_PROHIBITION_CONTAINERPLAN;
    2040            0 :         } else if ((mode == "crossing") || (mode == "route") || (mode == "edgeRelData")) {
    2041            0 :             myMessageID = MID_HOTKEY_R_MODE_CROSSING_ROUTE_EDGERELDATA;
    2042            0 :         } else if ((mode == "additional") || (mode == "stop")) {
    2043            0 :             myMessageID = MID_HOTKEY_A_MODE_STARTSIMULATION_ADDITIONALS_STOPS;
    2044            0 :         } else if ((mode == "wire") || (mode == "routeDistribution")) {
    2045            0 :             myMessageID = MID_HOTKEY_W_MODE_WIRE_ROUTEDISTRIBUTION;
    2046            0 :         } else if ((mode == "taz") || (mode == "TAZ") || (mode == "TAZRelData")) {
    2047            0 :             myMessageID = MID_HOTKEY_Z_MODE_TAZ_TAZREL;
    2048            0 :         } else if ((mode == "shape") || (mode == "person")) {
    2049            0 :             myMessageID = MID_HOTKEY_P_MODE_POLYGON_PERSON;
    2050            0 :         } else if ((mode == "decal") || (mode == "typeDistribution")) {
    2051            0 :             myMessageID = MID_HOTKEY_U_MODE_DECAL_TYPEDISTRIBUTION;
    2052            0 :         } else if (mode == "personPlan") {
    2053            0 :             myMessageID = MID_HOTKEY_L_MODE_PERSONPLAN;
    2054            0 :         } else if (mode == "vehicle") {
    2055            0 :             myMessageID = MID_HOTKEY_V_MODE_VEHICLE;
    2056            0 :         } else if (mode == "meanData") {
    2057            0 :             myMessageID = MID_HOTKEY_M_MODE_MOVE_MEANDATA;
    2058              :         } else {
    2059            0 :             writeError("changeMode", 0, "<inspect/delete/select/move...>");
    2060              :         }
    2061              :     }
    2062            0 : }
    2063              : 
    2064              : 
    2065              : void
    2066            0 : InternalTestStep::changeElement() const {
    2067            0 :     if ((myArguments.size() != 2) ||
    2068            0 :             !checkStringArgument(myArguments[0])) {
    2069            0 :         writeError("changeElement", 0, "<\"frame\", \"string\">");
    2070              :     } else {
    2071            0 :         const std::string frame = getStringArgument(myArguments[0]);
    2072            0 :         const std::string element = getStringArgument(myArguments[1]);
    2073              :         int numTabs = -1;
    2074              :         // continue depending of frame
    2075            0 :         if (frame == "additionalFrame") {
    2076            0 :             numTabs = myTestSystem->getAttributesEnum().at("netedit.attrs.frames.changeElement.additional");
    2077            0 :         } else if (frame == "shapeFrame") {
    2078            0 :             numTabs = myTestSystem->getAttributesEnum().at("netedit.attrs.frames.changeElement.shape");
    2079            0 :         } else if (frame == "vehicleFrame") {
    2080            0 :             numTabs = myTestSystem->getAttributesEnum().at("netedit.attrs.frames.changeElement.vehicle");
    2081            0 :         } else if (frame == "routeFrame") {
    2082            0 :             numTabs = myTestSystem->getAttributesEnum().at("netedit.attrs.frames.changeElement.route");
    2083            0 :         } else if (frame == "personFrame") {
    2084            0 :             numTabs = myTestSystem->getAttributesEnum().at("netedit.attrs.frames.changeElement.person");
    2085            0 :         } else if (frame == "containerFrame") {
    2086            0 :             numTabs = myTestSystem->getAttributesEnum().at("netedit.attrs.frames.changeElement.container");
    2087            0 :         } else if (frame == "personPlanFrame") {
    2088            0 :             numTabs = myTestSystem->getAttributesEnum().at("netedit.attrs.frames.changeElement.personPlan");
    2089            0 :         } else if (frame == "containerPlanFrame") {
    2090            0 :             numTabs = myTestSystem->getAttributesEnum().at("netedit.attrs.frames.changeElement.containerPlan");
    2091            0 :         } else if (frame == "stopFrame") {
    2092            0 :             numTabs = myTestSystem->getAttributesEnum().at("netedit.attrs.frames.changeElement.stop");
    2093            0 :         } else if (frame == "meanDataFrame") {
    2094            0 :             numTabs = myTestSystem->getAttributesEnum().at("netedit.attrs.frames.changeElement.meanData");
    2095              :         } else {
    2096            0 :             WRITE_ERRORF("Invalid frame '%' used in function changeElement", frame);
    2097              :         }
    2098            0 :         if (numTabs >= 0) {
    2099              :             // show info
    2100              :             std::cout << element << std::endl;
    2101              :             // focus frame
    2102            0 :             new InternalTestStep(myTestSystem, SEL_COMMAND, MID_HOTKEY_SHIFT_F12_FOCUSUPPERELEMENT, Category::APP, "focus " + frame);
    2103              :             // jump to select additional argument
    2104            0 :             for (int i = 0; i < numTabs; i++) {
    2105            0 :                 buildPressKeyEvent(Category::APP, "tab", false);
    2106              :             }
    2107              :             // write additional character by character
    2108            0 :             for (const char c : element) {
    2109            0 :                 buildPressKeyEvent(Category::APP, {c}, false);
    2110              :             }
    2111              :             // press enter to confirm changes (updating view)
    2112            0 :             buildPressKeyEvent(Category::APP, "enter", true);
    2113              :         }
    2114              :     }
    2115            0 : }
    2116              : 
    2117              : 
    2118              : void
    2119            0 : InternalTestStep::changePlan()  const {
    2120            0 :     if ((myArguments.size() != 3) ||
    2121            0 :             !checkStringArgument(myArguments[0]) ||
    2122            0 :             !checkStringArgument(myArguments[1]) ||
    2123            0 :             !checkBoolArgument(myArguments[2])) {
    2124            0 :         writeError("changePlan", 0, "<\"type\", \"plan\", true/false>");
    2125              :     } else {
    2126              :         // get arguments
    2127            0 :         const std::string type = getStringArgument(myArguments[0]);
    2128            0 :         const std::string plan = getStringArgument(myArguments[1]);
    2129            0 :         const bool flow = getBoolArgument(myArguments[2]);
    2130              :         // check plan
    2131            0 :         if ((type != "person") && (type != "container")) {
    2132            0 :             WRITE_ERRORF("invalid plan type '%' used in changePlan()", type);
    2133              :         } else {
    2134              :             // calculate num tabs
    2135              :             int numTabs = 0;
    2136            0 :             if (flow) {
    2137            0 :                 numTabs = myTestSystem->getAttributesEnum().at("netedit.attrs.frames.changePlan." + type + "Flow");
    2138              :             } else {
    2139            0 :                 numTabs = myTestSystem->getAttributesEnum().at("netedit.attrs.frames.changePlan." + type);
    2140              :             }
    2141              :             // focus frame
    2142            0 :             new InternalTestStep(myTestSystem, SEL_COMMAND, MID_HOTKEY_SHIFT_F12_FOCUSUPPERELEMENT, Category::APP, "focus plan frame");
    2143              :             // jump to select additional argument
    2144            0 :             for (int i = 0; i < numTabs; i++) {
    2145            0 :                 buildPressKeyEvent(Category::APP, "tab", false);
    2146              :             }
    2147              :             // write additional character by character
    2148            0 :             for (const char c : plan) {
    2149            0 :                 buildPressKeyEvent(Category::APP, {c}, false);
    2150              :             }
    2151              :             // print info
    2152              :             std::cout << plan << std::endl;
    2153              :             // press enter to confirm changes (updating view)
    2154            0 :             buildPressKeyEvent(Category::APP, "enter", true);
    2155              :         }
    2156              :     }
    2157            0 : }
    2158              : 
    2159              : 
    2160              : void
    2161            0 : InternalTestStep::computeJunctions() {
    2162            0 :     if (myArguments.size() > 0) {
    2163            0 :         writeError("computeJunctions", 0, "<>");
    2164              :     } else {
    2165            0 :         myCategory = Category::APP;
    2166            0 :         myMessageID = MID_HOTKEY_F5_COMPUTE_NETWORK_DEMAND;
    2167              :     }
    2168            0 : }
    2169              : 
    2170              : 
    2171              : void
    2172            0 : InternalTestStep::computeJunctionsVolatileOptions() {
    2173            0 :     if (myArguments.size() != 1) {
    2174            0 :         writeError("computeJunctionsVolatileOptions", 0, "<yes/no/esc>");
    2175              :     } else {
    2176            0 :         myCategory = Category::APP;
    2177            0 :         myMessageID = MID_HOTKEY_SHIFT_F5_COMPUTEJUNCTIONS_VOLATILE;
    2178              :         // get argument
    2179            0 :         const auto dialogArgument = getStringArgument(myArguments[0]);
    2180              :         // press space to confirm changes (updating view)
    2181            0 :         if (dialogArgument == "yes") {
    2182            0 :             new InternalTestStep(myTestSystem, new DialogArgument(DialogType::QUESTION, DialogArgument::Action::ACCEPT), "close accepting");
    2183            0 :         } else if (dialogArgument == "no") {
    2184            0 :             new InternalTestStep(myTestSystem, new DialogArgument(DialogType::QUESTION, DialogArgument::Action::CANCEL), "close canceling");
    2185              :         } else {
    2186            0 :             new InternalTestStep(myTestSystem, new DialogArgument(DialogType::QUESTION, DialogArgument::Action::ABORT), "close aborting");
    2187              :         }
    2188              :     }
    2189            0 : }
    2190              : 
    2191              : 
    2192              : void
    2193            0 : InternalTestStep::joinJunctions() {
    2194            0 :     if (myArguments.size() > 0) {
    2195            0 :         writeError("joinJunctions", 0, "<>");
    2196              :     } else {
    2197            0 :         myCategory = Category::APP;
    2198            0 :         myMessageID = MID_HOTKEY_F7_JOIN_SELECTEDJUNCTIONS_ROUTES;
    2199              :     }
    2200            0 : }
    2201              : 
    2202              : 
    2203              : void
    2204            0 : InternalTestStep::selectAdditionalChild() {
    2205            0 :     if ((myArguments.size() != 2) ||
    2206            0 :             !checkIntArgument(myArguments[0]) ||
    2207            0 :             !checkIntArgument(myArguments[1])) {
    2208            0 :         writeError("selectAdditionalChild", 0, "<int, int>");
    2209              :     } else {
    2210            0 :         const auto tabs = getIntArgument(myArguments[0]);
    2211            0 :         const auto downs = getIntArgument(myArguments[1]);
    2212              :         // focus frame
    2213            0 :         new InternalTestStep(myTestSystem, SEL_COMMAND, MID_HOTKEY_SHIFT_F12_FOCUSUPPERELEMENT, Category::APP, "select additional child");
    2214              :         // jump to the element
    2215            0 :         for (int i = 0; i < tabs; i++) {
    2216            0 :             buildPressKeyEvent(Category::APP, "tab", false);
    2217              :         }
    2218              :         // jump to the element
    2219            0 :         for (int i = 0; i < downs; i++) {
    2220            0 :             buildPressKeyEvent(Category::APP, "down", false);
    2221              :         }
    2222              :         // select additional child
    2223            0 :         buildPressKeyEvent(Category::APP, "space", true);
    2224              :         // leave
    2225            0 :         buildPressKeyEvent(Category::APP, "tab", true);
    2226              :     }
    2227            0 : }
    2228              : 
    2229              : 
    2230              : void
    2231            0 : InternalTestStep::createRectangledShape() {
    2232              :     if ((myArguments.size() != 5) ||
    2233            0 :             (myTestSystem->getViewPositions().count(myArguments[1]) == 0) ||
    2234            0 :             !checkIntArgument(myArguments[2]) ||
    2235            0 :             !checkIntArgument(myArguments[3]) ||
    2236            0 :             !checkBoolArgument(myArguments[4])) {
    2237            0 :         writeError("createRectangledShape", 0, "<viewPosition, sizeX, sizeY, true/false>");
    2238              :     } else {
    2239              :         // create shape
    2240            0 :         createShape(myTestSystem->getViewPositions().at(myArguments[1]),
    2241              :                     getIntArgument(myArguments[2]),
    2242              :                     getIntArgument(myArguments[3]),
    2243            0 :                     getBoolArgument(myArguments[4]),
    2244              :                     false);
    2245              :     }
    2246            0 : }
    2247              : 
    2248              : 
    2249              : void
    2250            0 : InternalTestStep::createSquaredShape() {
    2251              :     if ((myArguments.size() != 4) ||
    2252            0 :             (myTestSystem->getViewPositions().count(myArguments[1]) == 0) ||
    2253            0 :             !checkIntArgument(myArguments[2]) ||
    2254            0 :             !checkBoolArgument(myArguments[3])) {
    2255            0 :         writeError("createSquaredShape", 0, "<viewPosition, size, true/false>");
    2256              :     } else {
    2257              :         // create shape
    2258            0 :         createShape(myTestSystem->getViewPositions().at(myArguments[1]),
    2259              :                     getIntArgument(myArguments[2]),
    2260              :                     getIntArgument(myArguments[2]),
    2261            0 :                     getBoolArgument(myArguments[3]),
    2262              :                     false);
    2263              :     }
    2264            0 : }
    2265              : 
    2266              : 
    2267              : void
    2268            0 : InternalTestStep::createLineShape() {
    2269              :     if ((myArguments.size() != 5) ||
    2270            0 :             (myTestSystem->getViewPositions().count(myArguments[1]) == 0) ||
    2271            0 :             !checkIntArgument(myArguments[2]) ||
    2272            0 :             !checkIntArgument(myArguments[3]) ||
    2273            0 :             !checkBoolArgument(myArguments[4])) {
    2274            0 :         writeError("createLineShape", 0, "<viewPosition, sizeX, sizeY, true/false>");
    2275              :     } else {
    2276              :         // create shape
    2277            0 :         createShape(myTestSystem->getViewPositions().at(myArguments[1]),
    2278              :                     getIntArgument(myArguments[2]),
    2279              :                     getIntArgument(myArguments[3]),
    2280            0 :                     getBoolArgument(myArguments[4]),
    2281              :                     true);
    2282              :     }
    2283            0 : }
    2284              : 
    2285              : 
    2286              : void
    2287            0 : InternalTestStep::createMeanData() {
    2288            0 :     if (myArguments.size() != 0) {
    2289            0 :         writeError("createMeanData", 0, "<>");
    2290              :     } else {
    2291            0 :         modifyBoolAttribute(Category::APP, 5, 0);
    2292              :     }
    2293            0 : }
    2294              : 
    2295              : 
    2296              : void
    2297            0 : InternalTestStep::deleteMeanData() {
    2298            0 :     if (myArguments.size() != 0) {
    2299            0 :         writeError("deleteMeanData", 0, "<>");
    2300              :     } else {
    2301            0 :         modifyBoolAttribute(Category::APP, 6, 0);
    2302              :     }
    2303            0 : }
    2304              : 
    2305              : 
    2306              : void
    2307            0 : InternalTestStep::copyMeanData() {
    2308            0 :     if (myArguments.size() != 0) {
    2309            0 :         writeError("copyMeanData", 0, "<>");
    2310              :     } else {
    2311            0 :         modifyBoolAttribute(Category::APP, 7, 0);
    2312              :     }
    2313            0 : }
    2314              : 
    2315              : 
    2316              : void
    2317            0 : InternalTestStep::quit() {
    2318            0 :     if (myArguments.size() == 0) {
    2319            0 :         writeError("quit", 0, "<neteditProcess>");
    2320              :     } else {
    2321            0 :         myCategory = Category::APP;
    2322            0 :         myMessageID = MID_HOTKEY_CTRL_Q_CLOSE;
    2323              :         //don't update view if we're closing to avoid problems with drawGL
    2324            0 :         myUpdateView = false;
    2325              :     }
    2326            0 : }
    2327              : 
    2328              : 
    2329              : bool
    2330            0 : InternalTestStep::checkIntArgument(const std::string& argument) const {
    2331            0 :     if (StringUtils::isInt(argument)) {
    2332              :         return true;
    2333            0 :     } else if (myTestSystem->getAttributesEnum().count(argument) > 0) {
    2334            0 :         return true;
    2335              :     } else {
    2336            0 :         return false;
    2337              :     }
    2338              : }
    2339              : 
    2340              : 
    2341              : int
    2342            0 : InternalTestStep::getIntArgument(const std::string& argument) const {
    2343            0 :     if (StringUtils::isInt(argument)) {
    2344            0 :         return StringUtils::toInt(argument);
    2345              :     } else {
    2346            0 :         return myTestSystem->getAttributesEnum().at(argument);
    2347              :     }
    2348              : }
    2349              : 
    2350              : 
    2351              : bool
    2352            0 : InternalTestStep::checkBoolArgument(const std::string& argument) const {
    2353            0 :     if (argument == "True") {
    2354              :         return true;
    2355            0 :     } else if (argument == "False") {
    2356              :         return true;
    2357              :     } else {
    2358            0 :         return false;
    2359              :     }
    2360              : }
    2361              : 
    2362              : 
    2363              : bool
    2364            0 : InternalTestStep::getBoolArgument(const std::string& argument) const {
    2365            0 :     if (argument == "True") {
    2366              :         return true;
    2367              :     } else {
    2368            0 :         return false;
    2369              :     }
    2370              : }
    2371              : 
    2372              : 
    2373              : bool
    2374            0 : InternalTestStep::checkStringArgument(const std::string& argument) const {
    2375            0 :     if (argument.size() < 2) {
    2376              :         return false;
    2377            0 :     } else if ((argument.front() != argument.back()) || ((argument.front() != '\'') && ((argument.front() != '\"')))) {
    2378              :         return false;
    2379              :     } else {
    2380            0 :         return true;
    2381              :     }
    2382              : }
    2383              : 
    2384              : 
    2385              : std::string
    2386            0 : InternalTestStep::getStringArgument(const std::string& argument) const {
    2387              :     std::string argumentParsed;
    2388            0 :     for (int i = 1; i < ((int)argument.size() - 1); i++) {
    2389            0 :         argumentParsed.push_back(argument[i]);
    2390              :     }
    2391            0 :     return argumentParsed;
    2392              : }
    2393              : 
    2394              : 
    2395              : std::string
    2396            0 : InternalTestStep::stripSpaces(const std::string& str) const {
    2397            0 :     auto start = std::find_if_not(str.begin(), str.end(), isspace);
    2398            0 :     auto end = std::find_if_not(str.rbegin(), str.rend(), isspace).base();
    2399            0 :     if (start < end) {
    2400            0 :         return std::string(start, end);
    2401              :     } else {
    2402            0 :         return "";
    2403              :     }
    2404              : }
    2405              : 
    2406              : 
    2407              : void
    2408            0 : InternalTestStep::writeError(const std::string& function, const int overlapping, const std::string& expected) const {
    2409            0 :     if (overlapping > 0) {
    2410            0 :         WRITE_ERRORF("Invalid internal testStep function '%Ovelapped', requires '%' arguments ", function, expected);
    2411              :     } else {
    2412            0 :         WRITE_ERRORF("Invalid internal testStep function '%', requires '%' arguments ", function, expected);
    2413              :     }
    2414              :     // also print arguments
    2415            0 :     if (myArguments.size() > 0) {
    2416            0 :         WRITE_ERROR("Arguments: ");
    2417            0 :         for (const auto& arg : myArguments) {
    2418            0 :             WRITE_ERROR(stripSpaces(arg));
    2419              :         }
    2420              :     }
    2421            0 : }
    2422              : 
    2423              : 
    2424              : void
    2425            0 : InternalTestStep::createShape(const InternalTest::ViewPosition& viewPosition,
    2426              :                               const int sizeX, const int sizeY, const bool close,
    2427              :                               const bool line) const {
    2428              :     // calculate half-sizes
    2429            0 :     const int halfSizeX = int(sizeX * -0.5);
    2430            0 :     const int halfSizeY = int(sizeY * -0.5);
    2431              :     // focus frame
    2432            0 :     new InternalTestStep(myTestSystem, SEL_COMMAND, MID_HOTKEY_SHIFT_F12_FOCUSUPPERELEMENT, Category::APP, "focus frame");
    2433              :     // press enter to start drawing
    2434            0 :     buildPressKeyEvent(Category::APP, "enter", true);
    2435              :     // first edge
    2436            0 :     buildMouseClick(viewPosition, 0, 0, "left", "");
    2437            0 :     writeClickInfo(viewPosition, 0, 0, "");
    2438              :     // second edge
    2439            0 :     if (!line) {
    2440            0 :         buildMouseClick(viewPosition, 0, halfSizeY, "left", "");
    2441            0 :         writeClickInfo(viewPosition, 0, halfSizeY, "");
    2442              :     }
    2443              :     // third edge
    2444            0 :     buildMouseClick(viewPosition, halfSizeX, halfSizeY, "left", "");
    2445            0 :     writeClickInfo(viewPosition, halfSizeX, halfSizeY, "");
    2446              :     // four edge
    2447            0 :     if (!line) {
    2448            0 :         buildMouseClick(viewPosition, halfSizeX, 0, "left", "");
    2449            0 :         writeClickInfo(viewPosition, halfSizeX, 0, "");
    2450              :     }
    2451              :     // check if close polygon
    2452            0 :     if (close) {
    2453            0 :         buildMouseClick(viewPosition, 0, 0, "left", "");
    2454            0 :         writeClickInfo(viewPosition, 0, 0, "");
    2455              :     }
    2456              :     // press enter to end drawing
    2457            0 :     buildPressKeyEvent(Category::APP, "enter", true);
    2458            0 : }
    2459              : 
    2460              : 
    2461              : void
    2462            0 : InternalTestStep::modifyStringAttribute(Category category, const int tabs, const int overlappedTabs, const std::string& value) const {
    2463              :     // print info
    2464              :     std::cout << value << std::endl;
    2465              :     // focus frame
    2466            0 :     new InternalTestStep(myTestSystem, SEL_COMMAND, MID_HOTKEY_SHIFT_F12_FOCUSUPPERELEMENT, category, "focus frame");
    2467              :     // jump to the element
    2468            0 :     for (int i = 0; i < (tabs + overlappedTabs); i++) {
    2469            0 :         buildPressKeyEvent(category, "tab", false);
    2470              :     }
    2471              :     // write attribute character by character
    2472            0 :     if (value.empty()) {
    2473            0 :         buildPressKeyEvent(category, "delete", false);
    2474              :     } else {
    2475            0 :         for (const char c : value) {
    2476            0 :             buildPressKeyEvent(category, {c}, false);
    2477              :         }
    2478              :     }
    2479              :     // press enter to confirm changes (updating view)
    2480            0 :     buildPressKeyEvent(category, "enter", true);
    2481            0 : }
    2482              : 
    2483              : 
    2484              : void
    2485            0 : InternalTestStep::modifyBoolAttribute(Category category, const int tabs, const int overlappedTabs) const {
    2486              :     // focus frame
    2487            0 :     new InternalTestStep(myTestSystem, SEL_COMMAND, MID_HOTKEY_SHIFT_F12_FOCUSUPPERELEMENT, category, "focus frame");
    2488              :     // jump to the element
    2489            0 :     for (int i = 0; i < (tabs + overlappedTabs); i++) {
    2490            0 :         buildPressKeyEvent(category, "tab", false);
    2491              :     }
    2492              :     // toogle attribute
    2493            0 :     buildPressKeyEvent(category, "space", true);
    2494            0 : }
    2495              : 
    2496              : 
    2497              : void
    2498            0 : InternalTestStep::buildUndo(const int number) const {
    2499              :     // get reference position
    2500            0 :     const auto& referencePosition = myTestSystem->getViewPositions().at("netedit.positions.reference");
    2501              :     // focus frame
    2502            0 :     new InternalTestStep(myTestSystem, SEL_COMMAND, MID_HOTKEY_SHIFT_F12_FOCUSUPPERELEMENT, Category::APP, "focus frame");
    2503              :     // go to inspect mode
    2504            0 :     new InternalTestStep(myTestSystem, SEL_COMMAND, MID_HOTKEY_I_MODE_INSPECT, Category::APP, "inspect mode");
    2505              :     // click over reference
    2506              :     std::cout << "TestFunctions: Clicked over position " <<
    2507            0 :               toString(MOUSE_REFERENCE_X) << " - " <<
    2508            0 :               toString(MOUSE_REFERENCE_Y) << std::endl;
    2509              :     // build mouse click
    2510            0 :     buildMouseClick(referencePosition, 0, 0, "left", "");
    2511              :     // undo
    2512            0 :     for (int i = 0; i < number; i++) {
    2513            0 :         new InternalTestStep(myTestSystem, SEL_COMMAND, MID_HOTKEY_CTRL_Z_UNDO, Category::APP, "undo");
    2514              :     }
    2515            0 : }
    2516              : 
    2517              : 
    2518              : void
    2519            0 : InternalTestStep::buildRedo(const int number) const {
    2520              :     // get reference position
    2521            0 :     const auto& referencePosition = myTestSystem->getViewPositions().at("netedit.positions.reference");
    2522              :     // focus frame
    2523            0 :     new InternalTestStep(myTestSystem, SEL_COMMAND, MID_HOTKEY_SHIFT_F12_FOCUSUPPERELEMENT, Category::APP, "focus frame");
    2524              :     // go to inspect mode
    2525            0 :     new InternalTestStep(myTestSystem, SEL_COMMAND, MID_HOTKEY_I_MODE_INSPECT, Category::APP, "inspect mode");
    2526              :     // click over reference
    2527              :     std::cout << "TestFunctions: Clicked over position " <<
    2528            0 :               toString(MOUSE_REFERENCE_X) << " - " <<
    2529            0 :               toString(MOUSE_REFERENCE_Y) << std::endl;
    2530              :     // build mouse click
    2531            0 :     buildMouseClick(referencePosition, 0, 0, "left", "");
    2532              :     // undo
    2533            0 :     for (int i = 0; i < number; i++) {
    2534            0 :         new InternalTestStep(myTestSystem, SEL_COMMAND, MID_HOTKEY_CTRL_Y_REDO, Category::APP, "redo");
    2535              :     }
    2536            0 : }
    2537              : 
    2538              : 
    2539              : std::pair<FXint, FXString>
    2540            0 : InternalTestStep::translateKey(const std::string& key) const {
    2541              :     std::pair<FXint, FXString> solution;
    2542              :     // check if key is a single character
    2543            0 :     if (key.size() == 1) {
    2544            0 :         solution.first = FXint(key.front());
    2545            0 :         solution.second.append(key.front());
    2546              :     } else {
    2547              :         // continue depending of key
    2548            0 :         if (key == "backspace") {
    2549            0 :             solution.first = KEY_BackSpace;
    2550            0 :             solution.second = "\b";
    2551            0 :         } else if (key == "space") {
    2552            0 :             solution.first = KEY_space;
    2553            0 :         } else if (key == "tab") {
    2554            0 :             solution.first = KEY_Tab;
    2555            0 :             solution.second = "\t";
    2556            0 :         } else if (key == "clear") {
    2557            0 :             solution.first = KEY_Clear;
    2558            0 :         } else if (key == "enter" || key == "return") {
    2559            0 :             solution.first = KEY_Return;
    2560            0 :             solution.second = "\n";
    2561            0 :         } else if (key == "pause") {
    2562            0 :             solution.first = KEY_Pause;
    2563            0 :         } else if (key == "sys_req") {
    2564            0 :             solution.first = KEY_Sys_Req;
    2565            0 :         } else if (key == "esc" || key == "escape") {
    2566            0 :             solution.first = KEY_Escape;
    2567            0 :             solution.second = "\x1B";
    2568            0 :         } else if (key == "delete") {
    2569            0 :             solution.first = KEY_Delete;
    2570            0 :             solution.second = "\x7F";
    2571            0 :         } else if (key == "multi_key") {
    2572            0 :             solution.first = KEY_Multi_key;
    2573              :             // function
    2574            0 :         } else if (key == "shift") {
    2575            0 :             solution.first = KEY_Shift_L;
    2576            0 :         } else if (key == "control") {
    2577            0 :             solution.first = KEY_Control_L;
    2578              :             // Cursor
    2579            0 :         } else if (key == "home") {
    2580            0 :             solution.first = KEY_Home;
    2581            0 :         } else if (key == "left") {
    2582            0 :             solution.first = KEY_Left;
    2583            0 :         } else if (key == "up") {
    2584            0 :             solution.first = KEY_Up;
    2585            0 :         } else if (key == "right") {
    2586            0 :             solution.first = KEY_Right;
    2587            0 :         } else if (key == "down") {
    2588            0 :             solution.first = KEY_Down;
    2589            0 :         } else if (key == "prior" || key == "page_up") {
    2590            0 :             solution.first = KEY_Page_Up;
    2591            0 :         } else if (key == "next" || key == "page_down") {
    2592            0 :             solution.first = KEY_Page_Down;
    2593            0 :         } else if (key == "end") {
    2594            0 :             solution.first = KEY_End;
    2595            0 :         } else if (key == "begin") {
    2596            0 :             solution.first = KEY_Begin;
    2597              :             // Function keys
    2598            0 :         } else if (key == "f1") {
    2599            0 :             solution.first = KEY_F1;
    2600            0 :         } else if (key == "f2") {
    2601            0 :             solution.first = KEY_F2;
    2602            0 :         } else if (key == "f3") {
    2603            0 :             solution.first = KEY_F3;
    2604            0 :         } else if (key == "f4") {
    2605            0 :             solution.first = KEY_F4;
    2606            0 :         } else if (key == "f5") {
    2607            0 :             solution.first = KEY_F5;
    2608            0 :         } else if (key == "f6") {
    2609            0 :             solution.first = KEY_F6;
    2610            0 :         } else if (key == "f7") {
    2611            0 :             solution.first = KEY_F7;
    2612            0 :         } else if (key == "f8") {
    2613            0 :             solution.first = KEY_F8;
    2614            0 :         } else if (key == "f9") {
    2615            0 :             solution.first = KEY_F9;
    2616            0 :         } else if (key == "f10") {
    2617            0 :             solution.first = KEY_F10;
    2618            0 :         } else if (key == "f11" || key == "l1") {
    2619            0 :             solution.first = KEY_F11;
    2620            0 :         } else if (key == "f12" || key == "l2") {
    2621            0 :             solution.first = KEY_F12;
    2622              :         } else {
    2623            0 :             writeError("translateKey", 0, "<key>");
    2624            0 :             solution.first = KEY_VoidSymbol;
    2625              :         }
    2626              :     }
    2627            0 :     return solution;
    2628              : }
    2629              : 
    2630              : 
    2631              : FXEvent*
    2632            0 : InternalTestStep::buildKeyPressEvent(const std::string& key) const {
    2633            0 :     const auto keyValues = translateKey(key);
    2634            0 :     FXEvent* keyPressEvent = new FXEvent();
    2635              :     // set event values
    2636            0 :     keyPressEvent->time = myTestSystem->getTime();
    2637            0 :     keyPressEvent->synthetic = true;
    2638            0 :     keyPressEvent->type = SEL_KEYPRESS;
    2639            0 :     keyPressEvent->code = keyValues.first;
    2640            0 :     keyPressEvent->text = keyValues.second;
    2641            0 :     return keyPressEvent;
    2642              : }
    2643              : 
    2644              : 
    2645              : FXEvent*
    2646            0 : InternalTestStep::buildKeyReleaseEvent(const std::string& key) const {
    2647            0 :     const auto keyValues = translateKey(key);
    2648            0 :     FXEvent* keyPressEvent = new FXEvent();
    2649              :     // set event values
    2650            0 :     keyPressEvent->time = myTestSystem->getTime();
    2651            0 :     keyPressEvent->synthetic = true;
    2652            0 :     keyPressEvent->type = SEL_KEYPRESS;
    2653            0 :     keyPressEvent->code = keyValues.first;
    2654            0 :     keyPressEvent->text = keyValues.second;
    2655              :     // special case for shift and control
    2656            0 :     return keyPressEvent;
    2657              : }
    2658              : 
    2659              : 
    2660              : void
    2661            0 : InternalTestStep::buildPressKeyEvent(Category category, const std::string& key, const bool updateView) const {
    2662            0 :     new InternalTestStep(myTestSystem, SEL_KEYPRESS, category, buildKeyPressEvent(key), updateView, "key '" + key + "' pressed");
    2663            0 :     new InternalTestStep(myTestSystem, SEL_KEYRELEASE, category, buildKeyReleaseEvent(key), updateView, "key '" + key + "' released");
    2664            0 : }
    2665              : 
    2666              : 
    2667              : void
    2668            0 : InternalTestStep::buildTwoPressKeyEvent(Category category, const std::string& keyA, const std::string& keyB, const bool updateView) const {
    2669              :     // create both events using keyB
    2670            0 :     auto pressEvent = buildKeyPressEvent(keyB);
    2671            0 :     auto releaseEvent = buildKeyPressEvent(keyB);
    2672              :     // check if set state
    2673            0 :     if (keyA == "shift") {
    2674            0 :         pressEvent->state = SHIFTMASK;
    2675            0 :         releaseEvent->state = SHIFTMASK;
    2676            0 :     } else if (keyA == "control") {
    2677            0 :         pressEvent->state = CONTROLMASK;
    2678            0 :         releaseEvent->state = CONTROLMASK;
    2679            0 :     } else if (keyA == "alt") {
    2680            0 :         pressEvent->state = ALTMASK;
    2681            0 :         releaseEvent->state = ALTMASK;
    2682              :     }
    2683            0 :     new InternalTestStep(myTestSystem, SEL_KEYPRESS, category, pressEvent, updateView, "keys '" + keyA + "' + '" + keyB + "' pressed");
    2684            0 :     new InternalTestStep(myTestSystem, SEL_KEYRELEASE, category, releaseEvent, updateView, "keys '" + keyA + "' + '" + keyB + " pressed");
    2685            0 : }
    2686              : 
    2687              : 
    2688              : void
    2689            0 : InternalTestStep::buildMouseClick(const InternalTest::ViewPosition& viewPosition,
    2690              :                                   const int offsetX, const int offsetY,
    2691              :                                   const std::string& button, const std::string& keyModifier) const {
    2692              :     // move mouse move
    2693            0 :     new InternalTestStep(myTestSystem, SEL_MOTION, Category::VIEW,
    2694              :                          buildMouseMoveEvent(viewPosition, offsetX, offsetY, 0, "", 0),
    2695            0 :                          true, "mouse moved to click position");
    2696              :     // continue depending of mouse
    2697            0 :     if (button == "left") {
    2698            0 :         new InternalTestStep(myTestSystem, SEL_LEFTBUTTONPRESS, Category::VIEW,
    2699              :                              buildMouseClickEvent(SEL_LEFTBUTTONPRESS, viewPosition, offsetX, offsetY, keyModifier, 1),
    2700            0 :                              true, "mouse button " + button + " pressed");
    2701            0 :         new InternalTestStep(myTestSystem, SEL_LEFTBUTTONRELEASE, Category::VIEW,
    2702              :                              buildMouseClickEvent(SEL_LEFTBUTTONRELEASE, viewPosition, offsetX, offsetY, keyModifier, 1),
    2703            0 :                              true, "mouse button " + button + " released");
    2704            0 :     } else if (button == "center") {
    2705            0 :         new InternalTestStep(myTestSystem, SEL_MIDDLEBUTTONPRESS, Category::VIEW,
    2706              :                              buildMouseClickEvent(SEL_MIDDLEBUTTONPRESS, viewPosition, offsetX, offsetY, keyModifier, 1),
    2707            0 :                              true, "mouse button " + button + " pressed");
    2708            0 :         new InternalTestStep(myTestSystem, SEL_MIDDLEBUTTONRELEASE, Category::VIEW,
    2709              :                              buildMouseClickEvent(SEL_MIDDLEBUTTONRELEASE, viewPosition, offsetX, offsetY, keyModifier, 1),
    2710            0 :                              true, "mouse button " + button + " released");
    2711            0 :     } else if (button == "right") {
    2712            0 :         new InternalTestStep(myTestSystem, SEL_RIGHTBUTTONPRESS, Category::VIEW,
    2713              :                              buildMouseClickEvent(SEL_RIGHTBUTTONPRESS, viewPosition, offsetX, offsetY, keyModifier, 1),
    2714            0 :                              true, "mouse button " + button + " pressed");
    2715            0 :         new InternalTestStep(myTestSystem, SEL_RIGHTBUTTONRELEASE, Category::VIEW,
    2716              :                              buildMouseClickEvent(SEL_RIGHTBUTTONRELEASE, viewPosition, offsetX, offsetY, keyModifier, 1),
    2717            0 :                              true, "mouse button " + button + " released");
    2718              :     }
    2719            0 : }
    2720              : 
    2721              : 
    2722              : void
    2723            0 : InternalTestStep::buildMouseDragDrop(const InternalTest::ViewPosition& viewStartPosition,
    2724              :                                      const int offsetStartX, const int offsetStartY,
    2725              :                                      const InternalTest::ViewPosition& viewEndPosition,
    2726              :                                      const int offsetEndX, const int offsetEndY,
    2727              :                                      const std::string& keyModifier) const {
    2728              :     // move mouse interpolating
    2729            0 :     const auto interpolationSteps = myTestSystem->interpolateViewPositions(viewStartPosition, offsetStartX, offsetStartY, viewEndPosition, offsetEndX, offsetEndY);
    2730              :     // move mouse move
    2731            0 :     new InternalTestStep(myTestSystem, SEL_MOTION, Category::VIEW,
    2732              :                          buildMouseMoveEvent(viewStartPosition, offsetStartX, offsetStartY, 0, "", 0),
    2733            0 :                          true, "mouse moved to click position (dragDrop)");
    2734              :     // press button
    2735            0 :     new InternalTestStep(myTestSystem, SEL_LEFTBUTTONPRESS, Category::VIEW,
    2736              :                          buildMouseClickEvent(SEL_LEFTBUTTONPRESS, viewStartPosition, offsetStartX, offsetStartY, keyModifier, 1),
    2737            0 :                          true, "mouse button left pressed (dragDrop)");
    2738              :     // move mouse button
    2739            0 :     for (const auto& position : interpolationSteps) {
    2740            0 :         new InternalTestStep(myTestSystem, SEL_MOTION, Category::VIEW,
    2741              :                              buildMouseMoveEvent(position, 0, 0, LEFTBUTTON, "leftButton", 1),
    2742            0 :                              true, "mouse moved (dragDrop)");
    2743              :     }
    2744              :     // release button
    2745            0 :     new InternalTestStep(myTestSystem, SEL_LEFTBUTTONRELEASE, Category::VIEW,
    2746              :                          buildMouseClickEvent(SEL_LEFTBUTTONRELEASE, viewEndPosition, offsetEndX, offsetEndY, keyModifier, 1),
    2747            0 :                          true, "mouse button left released (dragDrop)");
    2748            0 : }
    2749              : 
    2750              : 
    2751              : FXEvent*
    2752            0 : InternalTestStep::buildMouseMoveEvent(const InternalTest::ViewPosition& viewPosition,
    2753              :                                       const int offsetX, const int offsetY, const int clickedButton,
    2754              :                                       const std::string& keyModifier, const int numberOfClicks) const {
    2755            0 :     FXEvent* moveEvent = new FXEvent();
    2756              :     // set event values
    2757            0 :     moveEvent->time = myTestSystem->getTime();
    2758            0 :     moveEvent->type = SEL_MOTION;
    2759            0 :     moveEvent->synthetic = true;
    2760            0 :     moveEvent->win_x = viewPosition.getX() + MOUSE_OFFSET_X + offsetX;
    2761            0 :     moveEvent->win_y = viewPosition.getY() + MOUSE_OFFSET_Y + offsetY;
    2762            0 :     moveEvent->last_x = myTestSystem->getLastMovedPosition().getX();
    2763            0 :     moveEvent->last_y = myTestSystem->getLastMovedPosition().getY();
    2764            0 :     moveEvent->click_x = 0;
    2765            0 :     moveEvent->click_y = 0;
    2766            0 :     moveEvent->moved = true;
    2767              :     moveEvent->rect = FXRectangle(0, 0, 0, 0);
    2768            0 :     moveEvent->click_button = clickedButton;
    2769            0 :     moveEvent->click_count = numberOfClicks;
    2770            0 :     moveEvent->code = 0;
    2771              :     // set modifier
    2772            0 :     if (keyModifier == "control") {
    2773            0 :         moveEvent->state = CONTROLMASK;
    2774            0 :     } else if (keyModifier == "shift") {
    2775            0 :         moveEvent->state = SHIFTMASK;
    2776            0 :     } else if (keyModifier == "leftButton") {
    2777            0 :         moveEvent->state = LEFTBUTTONMASK;
    2778              :     } else {
    2779            0 :         moveEvent->state = 0;
    2780              :     }
    2781              :     // update last moved position
    2782            0 :     myTestSystem->updateLastMovedPosition(moveEvent->win_x, moveEvent->win_y);
    2783            0 :     return moveEvent;
    2784              : }
    2785              : 
    2786              : 
    2787              : FXEvent*
    2788            0 : InternalTestStep::buildMouseClickEvent(FXSelType type, const InternalTest::ViewPosition& viewPosition,
    2789              :                                        const int offsetX, const int offsetY, const std::string& keyModifier,
    2790              :                                        const int numberOfClicks) const {
    2791            0 :     FXEvent* clickEvent = new FXEvent();
    2792              :     // set event values
    2793            0 :     clickEvent->time = myTestSystem->getTime();
    2794            0 :     clickEvent->type = type;
    2795            0 :     clickEvent->synthetic = true;
    2796            0 :     clickEvent->win_x = viewPosition.getX() + MOUSE_OFFSET_X + offsetX;
    2797            0 :     clickEvent->win_y = viewPosition.getY() + MOUSE_OFFSET_Y + offsetY;
    2798            0 :     clickEvent->click_x = viewPosition.getX() + MOUSE_OFFSET_X + offsetX;
    2799            0 :     clickEvent->click_y = viewPosition.getY() + MOUSE_OFFSET_Y + offsetY;
    2800            0 :     clickEvent->last_x = myTestSystem->getLastMovedPosition().getX();
    2801            0 :     clickEvent->last_y = myTestSystem->getLastMovedPosition().getY();
    2802            0 :     clickEvent->click_count = numberOfClicks;
    2803            0 :     clickEvent->moved = false;
    2804              :     clickEvent->rect = FXRectangle(0, 0, 0, 0);
    2805              :     // set button
    2806            0 :     if ((type == SEL_LEFTBUTTONPRESS) || (type == SEL_LEFTBUTTONRELEASE)) {
    2807            0 :         clickEvent->click_button = LEFTBUTTON;
    2808            0 :         clickEvent->code = LEFTBUTTON;
    2809            0 :     } else if ((type == SEL_MIDDLEBUTTONPRESS) || (type == SEL_MIDDLEBUTTONRELEASE)) {
    2810            0 :         clickEvent->click_button = MIDDLEBUTTON;
    2811            0 :         clickEvent->code = MIDDLEBUTTON;
    2812            0 :     } else if ((type == SEL_RIGHTBUTTONPRESS) || (type == SEL_RIGHTBUTTONRELEASE)) {
    2813            0 :         clickEvent->click_button = RIGHTBUTTON;
    2814            0 :         clickEvent->code = RIGHTBUTTON;
    2815              :     } else {
    2816            0 :         clickEvent->click_button = 0;
    2817            0 :         clickEvent->code = 0;
    2818              :     }
    2819              :     // set modifier
    2820            0 :     if (keyModifier == "control") {
    2821            0 :         clickEvent->state = CONTROLMASK;
    2822            0 :     } else if (keyModifier == "shift") {
    2823            0 :         clickEvent->state = SHIFTMASK;
    2824              :     } else {
    2825            0 :         clickEvent->state = 0;
    2826              :     }
    2827            0 :     return clickEvent;
    2828              : }
    2829              : 
    2830              : 
    2831              : void
    2832            0 : InternalTestStep::writeClickInfo(const InternalTest::ViewPosition& viewPosition,
    2833              :                                  const int offsetX, const int offsetY,
    2834              :                                  const std::string modifier) const {
    2835            0 :     if (modifier == "control") {
    2836              :         std::cout << "TestFunctions: Clicked with Control key pressed over position " <<
    2837            0 :                   toString(viewPosition.getX() + MOUSE_REFERENCE_X + offsetX) << " - " <<
    2838            0 :                   toString(viewPosition.getY() + MOUSE_REFERENCE_Y + offsetY) << std::endl;
    2839            0 :     } else if (modifier == "shift") {
    2840              :         std::cout << "TestFunctions: Clicked with Shift key pressed over position " <<
    2841            0 :                   toString(viewPosition.getX() + MOUSE_REFERENCE_X + offsetX) << " - " <<
    2842            0 :                   toString(viewPosition.getY() + MOUSE_REFERENCE_Y) << std::endl;
    2843              :     } else {
    2844              :         std::cout << "TestFunctions: Clicked over position " <<
    2845            0 :                   toString(viewPosition.getX() + MOUSE_REFERENCE_X + offsetX) << " - " <<
    2846            0 :                   toString(viewPosition.getY() + MOUSE_REFERENCE_Y + offsetY) << std::endl;
    2847              :     }
    2848            0 : }
    2849              : 
    2850              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1