1 /**
2  * UGENE - Integrated Bioinformatics Tools.
3  * Copyright (C) 2008-2018 UniPro <ugene@unipro.ru>
4  * http://ugene.net
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19  * MA 02110-1301, USA.
20  */
21 
22 #include <base_dialogs/GTFileDialog.h>
23 #include <base_dialogs/MessageBoxFiller.h>
24 #include <drivers/GTKeyboardDriver.h>
25 #include <drivers/GTMouseDriver.h>
26 #include <primitives/GTMainWindow.h>
27 #include <primitives/GTMenu.h>
28 #include <primitives/GTToolbar.h>
29 #include <primitives/GTWidget.h>
30 #include <system/GTClipboard.h>
31 #include <system/GTFile.h>
32 
33 #include <QApplication>
34 #include <QDir>
35 #include <QFileInfo>
36 #include <QMdiArea>
37 #include <QTemporaryDir>
38 
39 #include <U2Core/AppContext.h>
40 #include <U2Core/ExternalToolRegistry.h>
41 #include <U2Core/U2SafePoints.h>
42 
43 #include "GTTestsWorkflowDashboard.h"
44 #include "GTUtilsDashboard.h"
45 #include "GTUtilsExternalTools.h"
46 #include "GTUtilsLog.h"
47 #include "GTUtilsMdi.h"
48 #include "GTUtilsTaskTreeView.h"
49 #include "GTUtilsWorkflowDesigner.h"
50 #include "runnables/ugene/corelibs/U2Gui/AppSettingsDialogFiller.h"
51 #include "runnables/ugene/plugins/ngs_classification/GenomicLibraryDialogFiller.h"
52 #include "runnables/ugene/plugins/workflow_designer/DashboardsManagerDialogFiller.h"
53 #include "runnables/ugene/plugins/workflow_designer/StartupDialogFiller.h"
54 
55 namespace U2 {
56 
57 namespace GUITest_common_scenarios_workflow_dashboard {
58 using namespace HI;
59 
60 namespace {
61 
getExternalToolPath(GUITestOpStatus & os,const QString & toolName)62 QString getExternalToolPath(GUITestOpStatus &os, const QString &toolName) {
63     Q_UNUSED(os);
64 
65     ExternalToolRegistry *etRegistry = AppContext::getExternalToolRegistry();
66     CHECK_SET_ERR_RESULT(etRegistry != nullptr, "ExternalToolRegistry is nullptr", QString());
67 
68     ExternalTool *tool = etRegistry->getByName(toolName);
69     CHECK_SET_ERR_RESULT(tool != nullptr, QString("'%1' tool not found in the registry is nullptr").arg(toolName), QString());
70 
71     QString toolPath = tool->getPath();
72     CHECK_SET_ERR_RESULT(!toolPath.isEmpty(), QString("'%1' tool path is empty").arg(toolName), QString());
73     CHECK_SET_ERR_RESULT(tool->isValid(), QString("'%1' tool is invalid").arg(toolName), QString());
74 
75     return toolPath;
76 }
77 
getExternalToolDirPath(GUITestOpStatus & os,const QString & toolName,const QString & dirNamePart)78 QString getExternalToolDirPath(GUITestOpStatus &os, const QString &toolName, const QString &dirNamePart) {
79     const QString toolPath = getExternalToolPath(os, toolName);
80     QDir toolDir = QFileInfo(toolPath).dir();
81     while (!toolDir.dirName().contains(dirNamePart)) {
82         if (!toolDir.cdUp()) {
83             CHECK_SET_ERR_RESULT(false, QString("Can't find tool '%1' dir that should contain '%2'. The tool path: '%3'").arg(toolName).arg(dirNamePart).arg(toolPath), QString());
84         }
85     }
86     return toolDir.path();
87 }
88 
putToolToFolderWithSpaces(GUITestOpStatus & os,const QString & toolName,const QString & toolDirPath,const QString & sandboxDir)89 QString putToolToFolderWithSpaces(GUITestOpStatus &os, const QString &toolName, const QString &toolDirPath, const QString &sandboxDir) {
90     const QString toolPath = getExternalToolPath(os, toolName);
91     CHECK(!toolPath.contains(" "), toolPath);
92 
93     QTemporaryDir dirWithSpaces(QFileInfo(sandboxDir).absolutePath() + "/folder XXXXXX");
94     dirWithSpaces.setAutoRemove(false);
95 
96     const QString newToolDirPath = dirWithSpaces.path() + "/" + QFileInfo(toolDirPath).fileName();
97     QString newToolPath = toolPath;
98     newToolPath.replace(toolDirPath, newToolDirPath);
99     GTFile::copyDir(os, toolDirPath, newToolDirPath);
100 
101     return newToolPath;
102 }
103 
putToolToFolderWithoutSpaces(GUITestOpStatus & os,const QString & toolName,const QString & toolDirPath,const QString & sandboxDir)104 QString putToolToFolderWithoutSpaces(GUITestOpStatus &os, const QString &toolName, const QString &toolDirPath, const QString &sandboxDir) {
105     const QString toolPath = getExternalToolPath(os, toolName);
106     CHECK(toolPath.contains(" "), toolPath);
107 
108     CHECK_SET_ERR_RESULT(!sandboxDir.contains(" "),
109                          QString("Sandbox dir path contains spaces, can't find an acceptable place to copy tool '%1'. Sandbox dir path: '%2'")
110                              .arg(toolName)
111                              .arg(sandboxDir),
112                          QString());
113 
114     QTemporaryDir dirWithoutSpaces(sandboxDir + "/folderXXXXXX");
115     dirWithoutSpaces.setAutoRemove(false);
116 
117     const QString newToolDirPath = dirWithoutSpaces.path() + "/" + QFileInfo(toolDirPath).fileName();
118     QString newToolPath = toolPath;
119     newToolPath.replace(toolDirPath, newToolDirPath);
120     CHECK_SET_ERR_RESULT(!newToolPath.contains(" "),
121                          QString("Can't copy tool '%1' to a folder without spaces in the path: the tool contains spaces in its inner folders. Supposed new tool path: '%2'")
122                              .arg(toolName)
123                              .arg(newToolPath),
124                          QString());
125 
126     GTFile::copyDir(os, toolDirPath, newToolDirPath);
127 
128     return newToolPath;
129 }
130 
getNodesTexts(GUITestOpStatus & os)131 QMap<QString, QList<QPair<QString, QStringList>>> getNodesTexts(GUITestOpStatus &os) {
132     const int firstLevelNodesCount = GTUtilsDashboard::getChildrenNodesCount(os, GTUtilsDashboard::TREE_ROOT_ID);
133     QMap<QString, QList<QPair<QString, QStringList>>> nodesTexts;
134     for (int i = 0; i < firstLevelNodesCount; i++) {
135         const QString firstLevelNodeId = GTUtilsDashboard::getChildNodeId(os, GTUtilsDashboard::TREE_ROOT_ID, i);
136         const QString firstLevelNodeText = GTUtilsDashboard::getNodeText(os, firstLevelNodeId);
137 
138         const int secondLevelNodesCount = GTUtilsDashboard::getChildrenNodesCount(os, firstLevelNodeId);
139         QList<QPair<QString, QStringList>> subtree;
140         for (int j = 0; j < secondLevelNodesCount; j++) {
141             const QString secondLevelNodeId = GTUtilsDashboard::getChildNodeId(os, firstLevelNodeId, j);
142             const QString secondLevelNodeText = GTUtilsDashboard::getNodeText(os, secondLevelNodeId);
143 
144             const int thirdLevelNodesCount = GTUtilsDashboard::getChildrenNodesCount(os, secondLevelNodeId);
145             QStringList thirdLevelNodesTexts;
146             for (int k = 0; k < thirdLevelNodesCount; k++) {
147                 thirdLevelNodesTexts << GTUtilsDashboard::getNodeText(os, GTUtilsDashboard::getChildNodeId(os, secondLevelNodeId, k));
148             }
149             subtree << qMakePair(secondLevelNodeText, thirdLevelNodesTexts);
150         }
151         nodesTexts.insert(firstLevelNodeText, subtree);
152     }
153     return nodesTexts;
154 }
155 
checkTreeStructure(GUITestOpStatus & os,const QMap<QString,QList<QPair<QString,QStringList>>> & expectedNodesTexts)156 void checkTreeStructure(GUITestOpStatus &os, const QMap<QString, QList<QPair<QString, QStringList>>> &expectedNodesTexts) {
157     const QMap<QString, QList<QPair<QString, QStringList>>> nodesTexts = getNodesTexts(os);
158 
159     // Do explicitely comparison to be able to log the incorrect values
160     CHECK_SET_ERR(nodesTexts.size() == expectedNodesTexts.size(),
161                   QString("Unexpected first level nodes count: expected %1, got %2")
162                       .arg(expectedNodesTexts.size())
163                       .arg(nodesTexts.size()));
164 
165     foreach (const QString &expectedFirstLevelNodeText, expectedNodesTexts.keys()) {
166         CHECK_SET_ERR(nodesTexts.contains(expectedFirstLevelNodeText),
167                       QString("An expected first level node with text '%1' is not found in the tree")
168                           .arg(expectedFirstLevelNodeText));
169 
170         const QList<QPair<QString, QStringList>> &expectedSecondLevelNodes = expectedNodesTexts[expectedFirstLevelNodeText];
171         const QList<QPair<QString, QStringList>> &secondLevelNodes = nodesTexts[expectedFirstLevelNodeText];
172 
173         CHECK_SET_ERR(expectedSecondLevelNodes.size() == secondLevelNodes.size(),
174                       QString("Unexpected second level nodes count for the first level node with text '%1': expected %2, got %3")
175                           .arg(expectedFirstLevelNodeText)
176                           .arg(expectedSecondLevelNodes.size())
177                           .arg(secondLevelNodes.size()));
178 
179         for (int i = 0, n = expectedSecondLevelNodes.size(); i < n; i++) {
180             const QPair<QString, QStringList> &expectedSecondLevelNode = expectedSecondLevelNodes[i];
181             const QPair<QString, QStringList> &secondLevelNode = secondLevelNodes[i];
182 
183             const QString expectedSecondLevelNodeText = expectedSecondLevelNode.first;
184             const QString secondLevelNodeText = secondLevelNode.first;
185             CHECK_SET_ERR(expectedSecondLevelNodeText == secondLevelNodeText,
186                           QString("%1 (zero-based) child of the first level node with text '%2' has unexpected text: expected '%3', got '%4'")
187                               .arg(i)
188                               .arg(expectedFirstLevelNodeText)
189                               .arg(expectedSecondLevelNodeText)
190                               .arg(secondLevelNodeText));
191 
192             const QStringList &expectedThirdLevelNodes = expectedSecondLevelNode.second;
193             const QStringList &thirdLevelNodes = secondLevelNode.second;
194 
195             CHECK_SET_ERR(expectedThirdLevelNodes.size() == thirdLevelNodes.size(),
196                           QString("Unexpected third level nodes count for the second level node with text '%1', which is %2 (zero-based) child of the first level node with text '%3': expected %4, got %5")
197                               .arg(expectedSecondLevelNodeText)
198                               .arg(i)
199                               .arg(expectedFirstLevelNodeText)
200                               .arg(expectedThirdLevelNodes.size())
201                               .arg(thirdLevelNodes.size()));
202 
203             for (int j = 0, m = expectedThirdLevelNodes.size(); j < m; j++) {
204                 CHECK_SET_ERR(expectedThirdLevelNodes[j] == thirdLevelNodes[j],
205                               QString("%1 (zero-based) child of the second level node with text '%2', which is %3 (zero-based) child of "
206                                       "the first node with text '%4', has unexpected text: expected '%5', got '%6'")
207                                   .arg(j)
208                                   .arg(expectedSecondLevelNodeText)
209                                   .arg(i)
210                                   .arg(expectedFirstLevelNodeText)
211                                   .arg(expectedThirdLevelNodes[j])
212                                   .arg(thirdLevelNodes[j]));
213             }
214         }
215     }
216 }
217 
218 class SetWorkflowOutputDirScenario : public CustomScenario {
219 public:
SetWorkflowOutputDirScenario(const QString & _path)220     SetWorkflowOutputDirScenario(const QString &_path)
221         : CustomScenario(), path(_path) {
222     }
223 
run(HI::GUITestOpStatus & os)224     void run(HI::GUITestOpStatus &os) {
225         QWidget *dialog = GTWidget::getActiveModalWidget(os);
226         AppSettingsDialogFiller::setWorkflowOutputDirPath(os, path);
227         GTUtilsDialog::clickButtonBox(os, dialog, QDialogButtonBox::Ok);
228     }
229 
230 private:
231     const QString path;
232 };
233 
setWorkflowOutputDir(GUITestOpStatus & os,const QString & path)234 void setWorkflowOutputDir(GUITestOpStatus &os, const QString &path) {
235     GTUtilsDialog::waitForDialog(os, new AppSettingsDialogFiller(os, new SetWorkflowOutputDirScenario(path)));
236     GTMenu::clickMainMenuItem(os, QStringList() << "Settings"
237                                                 << "Preferences...");
238 }
239 
getQuotedString(const QString & string)240 QString getQuotedString(const QString &string) {
241     if (string.contains(QRegularExpression("\\s"))) {
242         return "\"" + string + "\"";
243     }
244     return string;
245 }
246 
247 }  // namespace
248 
GUI_TEST_CLASS_DEFINITION(misc_test_0001)249 GUI_TEST_CLASS_DEFINITION(misc_test_0001) {
250     GTUtilsDialog::waitForDialogWhichMayRunOrNot(os, new StartupDialogFiller(os));
251 
252     //    1. Open "_common_data/workflow/dashboard/external_tools_free_worfklow.uwl".
253     GTFileDialog::openFile(os, testDir + "_common_data/workflow/dashboard/external_tools_free_worfklow.uwl");
254     GTUtilsTaskTreeView::waitTaskFinished(os);
255 
256     //    2. Click "Read File URL(s)" element.
257     GTUtilsWorkflowDesigner::click(os, "Read File URL(s)");
258 
259     //    3. Add "data/samples/FASTA/human_T1.fa" file to "Dataset 1" dataset.
260     GTUtilsWorkflowDesigner::setDatasetInputFile(os, dataDir + "samples/FASTA/human_T1.fa", true);
261 
262     //    4. Launch the workflow.
263     GTUtilsWorkflowDesigner::runWorkflow(os);
264 
265     //    5. Wait the workflow execution finish.
266     GTUtilsTaskTreeView::waitTaskFinished(os);
267 
268     //    Expected result: a dashboard appears, it has no "External Tools" tab.
269     const bool externalToolsTabExists = GTUtilsDashboard::hasTab(os, GTUtilsDashboard::ExternalTools);
270     CHECK_SET_ERR(!externalToolsTabExists, "'External tools' dashboard tab unexpectedly is present on the dashboard");
271 }
272 
GUI_TEST_CLASS_DEFINITION(misc_test_0002)273 GUI_TEST_CLASS_DEFINITION(misc_test_0002) {
274     GTUtilsDialog::waitForDialogWhichMayRunOrNot(os, new StartupDialogFiller(os));
275 
276     //    1. Open "_common_data/workflow/dashboard/clustulo.uwl".
277     GTFileDialog::openFile(os, testDir + "_common_data/workflow/dashboard/clustulo.uwl");
278     GTUtilsDialog::waitAllFinished(os);
279 
280     //    2. Click "Read Alignment" element.
281     GTUtilsWorkflowDesigner::click(os, "Read Alignment");
282 
283     //    3. Add "data/samples/CLUSTALW/COI.aln" file to "Dataset 1" dataset.
284     GTUtilsWorkflowDesigner::setDatasetInputFile(os, dataDir + "samples/CLUSTALW/COI.aln", true);
285 
286     //    4. Launch the workflow.
287     GTUtilsWorkflowDesigner::runWorkflow(os);
288 
289     //    5. Wait the workflow execution finish.
290     GTUtilsTaskTreeView::waitTaskFinished(os);
291 
292     //    Expected result: a dashboard appears, it has "External Tools" tab.
293     bool externalToolsTabExists = GTUtilsDashboard::hasTab(os, GTUtilsDashboard::ExternalTools);
294     CHECK_SET_ERR(externalToolsTabExists, "'External tools' dashboard tab unexpectedly is not present on the dashboard");
295 }
296 
GUI_TEST_CLASS_DEFINITION(misc_test_0003)297 GUI_TEST_CLASS_DEFINITION(misc_test_0003) {
298     GTUtilsDialog::waitForDialogWhichMayRunOrNot(os, new StartupDialogFiller(os));
299 
300     //    1. Open "_common_data/workflow/dashboard/clustulo.uwl".
301     GTFileDialog::openFile(os, testDir + "_common_data/workflow/dashboard/clustulo.uwl");
302     GTUtilsTaskTreeView::waitTaskFinished(os);
303 
304     //    2. Click "Read Alignment" element.
305     GTUtilsWorkflowDesigner::click(os, "Read Alignment");
306 
307     //    3. Add "data/samples/CLUSTALW/COI.aln" file to "Dataset 1" dataset.
308     GTUtilsWorkflowDesigner::setDatasetInputFile(os, dataDir + "samples/CLUSTALW/COI.aln", true);
309 
310     //    4. Launch the workflow.
311     GTUtilsWorkflowDesigner::runWorkflow(os);
312 
313     //    5. Wait the workflow execution finish.
314     GTUtilsTaskTreeView::waitTaskFinished(os);
315 
316     //    6. Switch to an "External Tools" tab.
317     GTUtilsDashboard::openTab(os, GTUtilsDashboard::ExternalTools);
318 
319     //    Expected result:
320     //    The tree looks like:
321     //    Align with ClustalO
322     //    └Align with ClustalO run 1
323     //      └ClustalO run
324 
325     int childrenCount = GTUtilsDashboard::getChildrenNodesCount(os, GTUtilsDashboard::TREE_ROOT_ID);
326     int expectedChildrenCount = 1;
327     CHECK_SET_ERR(expectedChildrenCount == childrenCount, QString("There is an unexpected children count of node with ID '%1': expected %2, got %3").arg(GTUtilsDashboard::TREE_ROOT_ID).arg(expectedChildrenCount).arg(childrenCount));
328 
329     QString nodeId = GTUtilsDashboard::getChildNodeId(os, GTUtilsDashboard::TREE_ROOT_ID, 0);
330     QString nodeText = GTUtilsDashboard::getNodeText(os, nodeId);
331     QString expectedNodeText = "Align with ClustalO";
332     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(nodeId).arg(expectedNodeText).arg(nodeText));
333 
334     childrenCount = GTUtilsDashboard::getChildrenNodesCount(os, nodeId);
335     expectedChildrenCount = 1;
336     CHECK_SET_ERR(expectedChildrenCount == childrenCount, QString("There is an unexpected children count of node with ID '%1': expected %2, got %3").arg(nodeId).arg(expectedChildrenCount).arg(childrenCount));
337 
338     nodeId = GTUtilsDashboard::getChildNodeId(os, nodeId, 0);
339     nodeText = GTUtilsDashboard::getNodeText(os, nodeId);
340     expectedNodeText = "Align with ClustalO run 1";
341     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(nodeId).arg(expectedNodeText).arg(nodeText));
342 
343     childrenCount = GTUtilsDashboard::getChildrenNodesCount(os, nodeId);
344     expectedChildrenCount = 1;
345     CHECK_SET_ERR(expectedChildrenCount == childrenCount, QString("There is an unexpected children count of node with ID '%1': expected %2, got %3").arg(nodeId).arg(expectedChildrenCount).arg(childrenCount));
346 
347     nodeId = GTUtilsDashboard::getChildNodeId(os, nodeId, 0);
348     nodeText = GTUtilsDashboard::getNodeText(os, nodeId);
349     expectedNodeText = "ClustalO run";
350     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(nodeId).arg(expectedNodeText).arg(nodeText));
351 }
352 
GUI_TEST_CLASS_DEFINITION(misc_test_0004)353 GUI_TEST_CLASS_DEFINITION(misc_test_0004) {
354     GTUtilsDialog::waitForDialogWhichMayRunOrNot(os, new StartupDialogFiller(os));
355 
356     //    1. Open "_common_data/workflow/dashboard/samtools_clustulo_clustalw.uwl".
357     GTFileDialog::openFile(os, testDir + "_common_data/workflow/dashboard/samtools_clustulo_clustalw.uwl");
358     GTUtilsTaskTreeView::waitTaskFinished(os);
359 
360     //    2. Click "Read File URL(s)" element.
361     GTUtilsWorkflowDesigner::click(os, "Read File URL(s)");
362 
363     //    3. Add "data/samples/Assembly/chrM.sam.bam" file to "Dataset 1" dataset.
364     GTUtilsWorkflowDesigner::setDatasetInputFile(os, dataDir + "samples/Assembly/chrM.sorted.bam", true);
365 
366     //    4. Create a new dataset with name "Dataset 2".
367     GTUtilsWorkflowDesigner::createDataset(os, "Dataset 2");
368 
369     //    5. Add "data/samples/Assembly/chrM.sam.bam" file to "Dataset 2" dataset.
370     GTUtilsWorkflowDesigner::setDatasetInputFile(os, dataDir + "samples/Assembly/chrM.sam", true);
371 
372     //    6. Click "Call Variants with SAMtools" element.
373     GTUtilsWorkflowDesigner::click(os, "Call Variants with SAMtools");
374 
375     //    7. Set "Reference" attribute value to "data/samples/Assembly/chrM.fa".
376     GTUtilsWorkflowDesigner::setParameter(os, "Reference", dataDir + "samples/Assembly/chrM.fa", GTUtilsWorkflowDesigner::textValue);
377 
378     //    8. Set "Output variants file" attribute value to "misc_test_0004.vcf".
379     GTUtilsWorkflowDesigner::setParameter(os, "Output variants file", QFileInfo(sandBoxDir + "misc_test_0004.vcf").absoluteFilePath(), GTUtilsWorkflowDesigner::textValue);
380 
381     //    9. Click "Read Alignment" element.
382     GTUtilsWorkflowDesigner::click(os, "Read Alignment");
383 
384     //    10. Add "data/samples/CLUSTALW/COI.aln" file to "Dataset 1" dataset.
385     GTUtilsWorkflowDesigner::setDatasetInputFile(os, dataDir + "samples/CLUSTALW/COI.aln", true);
386 
387     //    11. Add "data/samples/CLUSTALW/COI.aln" file to "Dataset 1" dataset.
388     GTUtilsWorkflowDesigner::setDatasetInputFile(os, dataDir + "samples/CLUSTALW/COI.aln", true);
389 
390     //    12. Launch the workflow.
391     GTUtilsWorkflowDesigner::runWorkflow(os);
392 
393     //    13. Wait the workflow execution finish.
394     GTUtilsTaskTreeView::waitTaskFinished(os);
395 
396     //    14. Switch to an "External Tools" tab.
397     GTUtilsDashboard::openTab(os, GTUtilsDashboard::ExternalTools);
398 
399     //    Expected result:
400     //    The tree looks like:
401     //    Call Variants with SAMtools
402     //    ├Call Variants with SAMtools run 1
403     //    |├SAMtools run
404     //    |├BCFtools run
405     //    |└vcfutils run
406     //    └Call Variants with SAMtools run 2
407     //     ├SAMtools run
408     //     ├BCFtools run
409     //     └vcfutils run
410     //    Align with ClustalO
411     //    ├Align with ClustalO run 1
412     //    |└ClustalO run
413     //    └Align with ClustalO run 2
414     //     └ClustalO run
415     //    Align with ClustalW
416     //    ├Align with ClustalW run 1
417     //    |└ClustalW run
418     //    └Align with ClustalW run 2
419     //     └ClustalW run
420 
421     // root
422     int childrenCount = GTUtilsDashboard::getChildrenNodesCount(os, GTUtilsDashboard::TREE_ROOT_ID);
423     int expectedChildrenCount = 3;
424     CHECK_SET_ERR(expectedChildrenCount == childrenCount, QString("There is an unexpected children count of node with ID '%1': expected %2, got %3").arg(GTUtilsDashboard::TREE_ROOT_ID).arg(expectedChildrenCount).arg(childrenCount));
425 
426     // root / Call Variants with SAMtools
427     QString nodeLevel1Id = GTUtilsDashboard::getChildNodeId(os, GTUtilsDashboard::TREE_ROOT_ID, 0);
428     QString nodeText = GTUtilsDashboard::getNodeText(os, nodeLevel1Id);
429     QString expectedNodeText = "Call Variants with SAMtools";
430     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(nodeLevel1Id).arg(expectedNodeText).arg(nodeText));
431 
432     childrenCount = GTUtilsDashboard::getChildrenNodesCount(os, nodeLevel1Id);
433     expectedChildrenCount = 2;
434     CHECK_SET_ERR(expectedChildrenCount == childrenCount, QString("There is an unexpected children count of node with ID '%1': expected %2, got %3").arg(nodeLevel1Id).arg(expectedChildrenCount).arg(childrenCount));
435 
436     // root / Call Variants with SAMtools / Call Variants with SAMtools run 1
437     QString nodeLevel2Id = GTUtilsDashboard::getChildNodeId(os, nodeLevel1Id, 0);
438     nodeText = GTUtilsDashboard::getNodeText(os, nodeLevel2Id);
439     expectedNodeText = "Call Variants with SAMtools run 1";
440     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(nodeLevel2Id).arg(expectedNodeText).arg(nodeText));
441 
442     childrenCount = GTUtilsDashboard::getChildrenNodesCount(os, nodeLevel2Id);
443     expectedChildrenCount = 3;
444     CHECK_SET_ERR(expectedChildrenCount == childrenCount, QString("There is an unexpected children count of node with ID '%1': expected %2, got %3").arg(nodeLevel2Id).arg(expectedChildrenCount).arg(childrenCount));
445 
446     // root / Call Variants with SAMtools / Call Variants with SAMtools run 1 / SAMtools run
447     QString nodeLevel3Id = GTUtilsDashboard::getChildNodeId(os, nodeLevel2Id, 0);
448     nodeText = GTUtilsDashboard::getNodeText(os, nodeLevel3Id);
449     expectedNodeText = "SAMtools run";
450     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(nodeLevel3Id).arg(expectedNodeText).arg(nodeText));
451 
452     // root / Call Variants with SAMtools / Call Variants with SAMtools run 1 / BCFtools run
453     nodeLevel3Id = GTUtilsDashboard::getChildNodeId(os, nodeLevel2Id, 1);
454     nodeText = GTUtilsDashboard::getNodeText(os, nodeLevel3Id);
455     expectedNodeText = "BCFtools run";
456     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(nodeLevel3Id).arg(expectedNodeText).arg(nodeText));
457 
458     // root / Call Variants with SAMtools / Call Variants with SAMtools run 1 / vcfutils run
459     nodeLevel3Id = GTUtilsDashboard::getChildNodeId(os, nodeLevel2Id, 2);
460     nodeText = GTUtilsDashboard::getNodeText(os, nodeLevel3Id);
461     expectedNodeText = "vcfutils run";
462     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(nodeLevel3Id).arg(expectedNodeText).arg(nodeText));
463 
464     // root / Call Variants with SAMtools / Call Variants with SAMtools run 2
465     nodeLevel2Id = GTUtilsDashboard::getChildNodeId(os, nodeLevel1Id, 1);
466     nodeText = GTUtilsDashboard::getNodeText(os, nodeLevel2Id);
467     expectedNodeText = "Call Variants with SAMtools run 2";
468     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(nodeLevel2Id).arg(expectedNodeText).arg(nodeText));
469 
470     childrenCount = GTUtilsDashboard::getChildrenNodesCount(os, nodeLevel2Id);
471     expectedChildrenCount = 3;
472     CHECK_SET_ERR(expectedChildrenCount == childrenCount, QString("There is an unexpected children count of node with ID '%1': expected %2, got %3").arg(nodeLevel2Id).arg(expectedChildrenCount).arg(childrenCount));
473 
474     // root / Call Variants with SAMtools / Call Variants with SAMtools run 2 / SAMtools run
475     nodeLevel3Id = GTUtilsDashboard::getChildNodeId(os, nodeLevel2Id, 0);
476     nodeText = GTUtilsDashboard::getNodeText(os, nodeLevel3Id);
477     expectedNodeText = "SAMtools run";
478     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(nodeLevel3Id).arg(expectedNodeText).arg(nodeText));
479 
480     // root / Call Variants with SAMtools / Call Variants with SAMtools run 2 / BCFtools run
481     nodeLevel3Id = GTUtilsDashboard::getChildNodeId(os, nodeLevel2Id, 1);
482     nodeText = GTUtilsDashboard::getNodeText(os, nodeLevel3Id);
483     expectedNodeText = "BCFtools run";
484     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(nodeLevel3Id).arg(expectedNodeText).arg(nodeText));
485 
486     // root / Call Variants with SAMtools / Call Variants with SAMtools run 2 / vcfutils run
487     nodeLevel3Id = GTUtilsDashboard::getChildNodeId(os, nodeLevel2Id, 2);
488     nodeText = GTUtilsDashboard::getNodeText(os, nodeLevel3Id);
489     expectedNodeText = "vcfutils run";
490     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(nodeLevel3Id).arg(expectedNodeText).arg(nodeText));
491 
492     // root / Align with ClustalO
493     nodeLevel1Id = GTUtilsDashboard::getChildNodeId(os, GTUtilsDashboard::TREE_ROOT_ID, 1);
494     nodeText = GTUtilsDashboard::getNodeText(os, nodeLevel1Id);
495     expectedNodeText = "Align with ClustalO";
496     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(nodeLevel1Id).arg(expectedNodeText).arg(nodeText));
497 
498     childrenCount = GTUtilsDashboard::getChildrenNodesCount(os, nodeLevel1Id);
499     expectedChildrenCount = 2;
500     CHECK_SET_ERR(expectedChildrenCount == childrenCount, QString("There is an unexpected children count of node with ID '%1': expected %2, got %3").arg(nodeLevel1Id).arg(expectedChildrenCount).arg(childrenCount));
501 
502     // root / Align with ClustalO / Align with ClustalO run 1
503     nodeLevel2Id = GTUtilsDashboard::getChildNodeId(os, nodeLevel1Id, 0);
504     nodeText = GTUtilsDashboard::getNodeText(os, nodeLevel2Id);
505     expectedNodeText = "Align with ClustalO run 1";
506     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(nodeLevel2Id).arg(expectedNodeText).arg(nodeText));
507 
508     childrenCount = GTUtilsDashboard::getChildrenNodesCount(os, nodeLevel2Id);
509     expectedChildrenCount = 1;
510     CHECK_SET_ERR(expectedChildrenCount == childrenCount, QString("There is an unexpected children count of node with ID '%1': expected %2, got %3").arg(nodeLevel2Id).arg(expectedChildrenCount).arg(childrenCount));
511 
512     // root / Align with ClustalO / Align with ClustalO run 1 / ClustalO run
513     nodeLevel3Id = GTUtilsDashboard::getChildNodeId(os, nodeLevel2Id, 0);
514     nodeText = GTUtilsDashboard::getNodeText(os, nodeLevel3Id);
515     expectedNodeText = "ClustalO run";
516     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(nodeLevel3Id).arg(expectedNodeText).arg(nodeText));
517 
518     // root / Align with ClustalO / Align with ClustalO run 2
519     nodeLevel2Id = GTUtilsDashboard::getChildNodeId(os, nodeLevel1Id, 1);
520     nodeText = GTUtilsDashboard::getNodeText(os, nodeLevel2Id);
521     expectedNodeText = "Align with ClustalO run 2";
522     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(nodeLevel2Id).arg(expectedNodeText).arg(nodeText));
523 
524     childrenCount = GTUtilsDashboard::getChildrenNodesCount(os, nodeLevel2Id);
525     expectedChildrenCount = 1;
526     CHECK_SET_ERR(expectedChildrenCount == childrenCount, QString("There is an unexpected children count of node with ID '%1': expected %2, got %3").arg(nodeLevel2Id).arg(expectedChildrenCount).arg(childrenCount));
527 
528     // root / Align with ClustalO / Align with ClustalO run 2 / ClustalO run
529     nodeLevel3Id = GTUtilsDashboard::getChildNodeId(os, nodeLevel2Id, 0);
530     nodeText = GTUtilsDashboard::getNodeText(os, nodeLevel3Id);
531     expectedNodeText = "ClustalO run";
532     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(nodeLevel3Id).arg(expectedNodeText).arg(nodeText));
533 
534     // root / Align with ClustalW
535     nodeLevel1Id = GTUtilsDashboard::getChildNodeId(os, GTUtilsDashboard::TREE_ROOT_ID, 2);
536     nodeText = GTUtilsDashboard::getNodeText(os, nodeLevel1Id);
537     expectedNodeText = "Align with ClustalW";
538     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(nodeLevel1Id).arg(expectedNodeText).arg(nodeText));
539 
540     childrenCount = GTUtilsDashboard::getChildrenNodesCount(os, nodeLevel1Id);
541     expectedChildrenCount = 2;
542     CHECK_SET_ERR(expectedChildrenCount == childrenCount, QString("There is an unexpected children count of node with ID '%1': expected %2, got %3").arg(nodeLevel1Id).arg(expectedChildrenCount).arg(childrenCount));
543 
544     // root / Align with ClustalW / Align with ClustalW run 1
545     nodeLevel2Id = GTUtilsDashboard::getChildNodeId(os, nodeLevel1Id, 0);
546     nodeText = GTUtilsDashboard::getNodeText(os, nodeLevel2Id);
547     expectedNodeText = "Align with ClustalW run 1";
548     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(nodeLevel2Id).arg(expectedNodeText).arg(nodeText));
549 
550     childrenCount = GTUtilsDashboard::getChildrenNodesCount(os, nodeLevel2Id);
551     expectedChildrenCount = 1;
552     CHECK_SET_ERR(expectedChildrenCount == childrenCount, QString("There is an unexpected children count of node with ID '%1': expected %2, got %3").arg(nodeLevel2Id).arg(expectedChildrenCount).arg(childrenCount));
553 
554     // root / Align with ClustalW / Align with ClustalW run 1 / ClustalW run
555     nodeLevel3Id = GTUtilsDashboard::getChildNodeId(os, nodeLevel2Id, 0);
556     nodeText = GTUtilsDashboard::getNodeText(os, nodeLevel3Id);
557     expectedNodeText = "ClustalW run";
558     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(nodeLevel3Id).arg(expectedNodeText).arg(nodeText));
559 
560     // root / Align with ClustalO / Align with ClustalW run 2
561     nodeLevel2Id = GTUtilsDashboard::getChildNodeId(os, nodeLevel1Id, 1);
562     nodeText = GTUtilsDashboard::getNodeText(os, nodeLevel2Id);
563     expectedNodeText = "Align with ClustalW run 2";
564     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(nodeLevel2Id).arg(expectedNodeText).arg(nodeText));
565 
566     childrenCount = GTUtilsDashboard::getChildrenNodesCount(os, nodeLevel2Id);
567     expectedChildrenCount = 1;
568     CHECK_SET_ERR(expectedChildrenCount == childrenCount, QString("There is an unexpected children count of node with ID '%1': expected %2, got %3").arg(nodeLevel2Id).arg(expectedChildrenCount).arg(childrenCount));
569 
570     // root / Align with ClustalO / Align with ClustalW run 2 / ClustalW run
571     nodeLevel3Id = GTUtilsDashboard::getChildNodeId(os, nodeLevel2Id, 0);
572     nodeText = GTUtilsDashboard::getNodeText(os, nodeLevel3Id);
573     expectedNodeText = "ClustalW run";
574     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(nodeLevel3Id).arg(expectedNodeText).arg(nodeText));
575 }
576 
GUI_TEST_CLASS_DEFINITION(tree_nodes_creation_test_0001)577 GUI_TEST_CLASS_DEFINITION(tree_nodes_creation_test_0001) {
578     GTUtilsDialog::waitForDialogWhichMayRunOrNot(os, new StartupDialogFiller(os));
579 
580     //    1. Ensure that taxonomy data is set. It should be full enough to pass the kraken-build validator.
581     // Currently, it is impossible to set taxonomy data after UGENE launch: UGENE-5979
582     // Test should be updated.
583 
584     //    2. Set the "_common_data/workflow/dashboard/fake_tools/fake_kraken-build" as "kraken-build" external tool in the "Application Settings".
585     const QString krakenBuildToolName = "kraken-build";
586     const QString krakenBuildToolPath = QDir::toNativeSeparators(QFileInfo(testDir + "_common_data/workflow/dashboard/fake_tools/fake_kraken-build").absoluteFilePath());
587     GTUtilsExternalTools::setToolUrl(os, krakenBuildToolName, krakenBuildToolPath);
588     GTUtilsTaskTreeView::waitTaskFinished(os);
589 
590     //    3. Open "_common_data/workflow/dashboard/2_kraken-builds.uwl".
591     GTFileDialog::openFile(os, testDir + "_common_data/workflow/dashboard/2_kraken-builds.uwl");
592     GTUtilsTaskTreeView::waitTaskFinished(os);
593 
594     //    4. Click "Build Kraken Database" element.
595     GTUtilsWorkflowDesigner::click(os, "Build Kraken Database");
596 
597     //    5. Set "Database" attribute value to tree_nodes_creation_test_0001_db1".
598     const QString db1Url = QFileInfo(sandBoxDir + "tree_nodes_creation_test_0001_db1").absoluteFilePath();
599     QDir().mkpath(db1Url);
600     GTUtilsWorkflowDesigner::setParameter(os, "Database", db1Url, GTUtilsWorkflowDesigner::textValue);
601 
602     //    6. Click the "..." button in the "Genomic library" attribute value field.
603     //    Expected result: "Select Genomes for Kraken Database" dialog appeared.
604     //    7. Add "data/samples/FASTA/human_T1.fa", "_common_data/fasta/COI2.fa", "_common_data/fasta/DNA.fa" files to the dataset in the dialog.
605     //    8. Click the "Select" button in the dialog.
606     QStringList urls = {QFileInfo(dataDir + "samples/FASTA/human_T1.fa").absoluteFilePath(),
607                         QFileInfo(testDir + "_common_data/fasta/COI2.fa").absoluteFilePath(),
608                         QFileInfo(testDir + "_common_data/fasta/DNA.fa").absoluteFilePath()};
609     GTUtilsDialog::waitForDialog(os, new GenomicLibraryDialogFiller(os, urls));
610     GTUtilsWorkflowDesigner::setParameter(os, "Genomic library", QVariant(), GTUtilsWorkflowDesigner::customDialogSelector);
611 
612     //    9. Click "Build Kraken Database 1" element.
613     GTUtilsWorkflowDesigner::click(os, "Build Kraken Database 1");
614 
615     //    10. Set "Database" attribute value to tree_nodes_creation_test_0001_db2".
616     const QString db2Url = QFileInfo(sandBoxDir + "tree_nodes_creation_test_0001_db2").absoluteFilePath();
617     QDir().mkpath(db2Url);
618     GTUtilsWorkflowDesigner::setParameter(os, "Database", db2Url, GTUtilsWorkflowDesigner::textValue);
619 
620     //    11. Click the "..." button in the "Genomic library" attribute value field.
621     //    Expected result: "Select Genomes for Kraken Database" dialog appeared.
622     //    12. Add "data/samples/FASTA/human_T1.fa", "_common_data/fasta/COI2.fa" files to the dataset in the dialog.
623     //    13. Click the "Select" button in the dialog.
624     urls.removeLast();
625     GTUtilsDialog::waitForDialog(os, new GenomicLibraryDialogFiller(os, urls));
626     GTUtilsWorkflowDesigner::setParameter(os, "Genomic library", QVariant(), GTUtilsWorkflowDesigner::customDialogSelector);
627 
628     //    14. Launch the workflow.
629     GTUtilsWorkflowDesigner::runWorkflow(os);
630 
631     //    15. Wait the workflow execution finish.
632     GTUtilsTaskTreeView::waitTaskFinished(os);
633 
634     //    16. Switch to an "External Tools" tab.
635     GTUtilsDashboard::openTab(os, GTUtilsDashboard::ExternalTools);
636 
637     //    Expected result:
638     //    The tree looks like:
639     //     -----------
640     //    Build Kraken Database
641     //    └Build Kraken Database run 1
642     //      ├kraken-build run 1
643     //      ├kraken-build run 2
644     //      ├kraken-build run 3
645     //      └Messages limit on the dashboard exceeded. See log files, if required.
646     //    Build Kraken Database 1
647     //    └Build Kraken Database 1 run 1
648     //      ├kraken-build run 1
649     //      ├kraken-build run 2
650     //      └kraken-build run 3
651     //     -----------
652     //    "log files" in a message is a link to a dir with tools execution logs.
653 
654     QMap<QString, QList<QPair<QString, QStringList>>> expectedNodesTexts;
655     expectedNodesTexts.insert("Build Kraken Database", {qMakePair(QString("Build Kraken Database run 1"), QStringList({"kraken-build run 1 ", "kraken-build run 2 ", "kraken-build run 3 "}))});
656     expectedNodesTexts.insert("Build Kraken Database 1", {qMakePair(QString("Build Kraken Database 1 run 1"), QStringList({"kraken-build run 1 ", "kraken-build run 2 ", "kraken-build run 3 "}))});
657     checkTreeStructure(os, expectedNodesTexts);
658 
659     const QString elementNodeId = GTUtilsDashboard::getChildWithTextId(os, GTUtilsDashboard::TREE_ROOT_ID, "Build Kraken Database");
660     const QString elementTickNodeId = GTUtilsDashboard::getChildNodeId(os, elementNodeId, 0);
661     const bool limitationMessageNodeExists = GTUtilsDashboard::hasLimitationMessage(os, elementTickNodeId);
662     CHECK_SET_ERR(limitationMessageNodeExists, QString("Message node unexpectedly not found, parent node ID: '%1'").arg(elementTickNodeId));
663 
664     const QString messageNodeText = GTUtilsDashboard::getLimitationMessage(os, elementTickNodeId);
665     const QString expectedMessageNodeText = "Messages limit on the dashboard exceeded.";
666     CHECK_SET_ERR(messageNodeText.startsWith(expectedMessageNodeText),
667                   QString("Unexpected message node text: expected '%1', got '%2'; parent node ID: '%3'")
668                       .arg(expectedMessageNodeText)
669                       .arg(messageNodeText)
670                       .arg(elementTickNodeId));
671 
672     const QString logUrl = GTUtilsDashboard::getLogUrlFromNodeLimitationMessage(os, elementTickNodeId);
673 
674     const QFileInfo fileInfo(logUrl);
675     CHECK_SET_ERR(fileInfo.exists(), QString("Dir with URL '%1' doesn't exist").arg(logUrl));
676     CHECK_SET_ERR(fileInfo.isDir(), QString("Entry with URL '%1' is not a dir").arg(logUrl));
677     CHECK_SET_ERR(!QDir(logUrl).entryList(QDir::Files).isEmpty(), QString("Dir with URL '%1' doesn't contain log files").arg(logUrl));
678 }
679 
GUI_TEST_CLASS_DEFINITION(tree_nodes_creation_test_0002)680 GUI_TEST_CLASS_DEFINITION(tree_nodes_creation_test_0002) {
681     GTUtilsDialog::waitForDialogWhichMayRunOrNot(os, new StartupDialogFiller(os));
682 
683     //    1. Set the "_common_data/workflow/dashboard/fake_tools/fake_cutadapt.py" as "cutadapt" external tool in the "Application Settings".
684     const QString cutadaptToolName = "cutadapt";
685     const QString cutadaptToolPath = QDir::toNativeSeparators(QFileInfo(testDir + "_common_data/workflow/dashboard/fake_tools/fake_cutadapt.py").absoluteFilePath());
686     GTUtilsExternalTools::setToolUrl(os, cutadaptToolName, cutadaptToolPath);
687     GTUtilsTaskTreeView::waitTaskFinished(os);
688 
689     //    2. Open "_common_data/workflow/dashboard/cutadapt.uwl".
690     GTFileDialog::openFile(os, testDir + "_common_data/workflow/dashboard/cutadapt.uwl");
691     GTUtilsTaskTreeView::waitTaskFinished(os);
692 
693     //    3. Click "Read File URL(s)" element.
694     GTUtilsWorkflowDesigner::click(os, "Read File URL(s)");
695 
696     //    4. Add "data/samples/FASTQ/eas.fastq" file 100 times to "Dataset 1" dataset.
697     const QString inputDir = QFileInfo(sandBoxDir + "tree_nodes_creation_test_0002_input").absoluteFilePath();
698     QDir().mkpath(inputDir);
699     for (int i = 0; i < 100; i++) {
700         GTFile::copy(os, dataDir + "samples/FASTQ/eas.fastq", inputDir + "/" + QString("eas_%2.fastq").arg(i));
701     }
702     GTUtilsWorkflowDesigner::setDatasetInputFolder(os, inputDir);
703 
704     //    5. Launch the workflow.
705     GTUtilsWorkflowDesigner::runWorkflow(os);
706 
707     //    6. Wait the workflow execution finish.
708     GTUtilsTaskTreeView::waitTaskFinished(os);
709 
710     //    7. Switch to an "External Tools" tab.
711     GTUtilsDashboard::openTab(os, GTUtilsDashboard::ExternalTools);
712 
713     //    Expected result:
714     //    The tree looks like:
715     //     -----------
716     //    Cut Adapter
717     //    ├Cut Adapter run 1
718     //     |└cutadapt run
719     //    ├Cut Adapter run 2
720     //     |└cutadapt run
721     //    ...
722     //    └Cut Adapter run 100
723     //      └cutadapt run
724     QMap<QString, QList<QPair<QString, QStringList>>> expectedNodesTexts;
725     QList<QPair<QString, QStringList>> secondLevelNodes;
726     for (int i = 1; i < 101; i++) {
727         secondLevelNodes << qMakePair(QString("Cut Adapter run %1").arg(i), QStringList({"cutadapt run"}));
728     }
729     expectedNodesTexts.insert("Cut Adapter", secondLevelNodes);
730     checkTreeStructure(os, expectedNodesTexts);
731 }
732 
GUI_TEST_CLASS_DEFINITION(tree_nodes_creation_test_0003)733 GUI_TEST_CLASS_DEFINITION(tree_nodes_creation_test_0003) {
734     GTUtilsDialog::waitForDialogWhichMayRunOrNot(os, new StartupDialogFiller(os));
735 
736     //    1. Set the "_common_data/workflow/dashboard/fake_tools/fake_cutadapt.py" as "cutadapt" external tool in the "Application Settings".
737     const QString cutadaptToolName = "cutadapt";
738     const QString cutadaptToolPath = QDir::toNativeSeparators(QFileInfo(testDir + "_common_data/workflow/dashboard/fake_tools/fake_cutadapt.py").absoluteFilePath());
739     GTUtilsExternalTools::setToolUrl(os, cutadaptToolName, cutadaptToolPath);
740     GTUtilsTaskTreeView::waitTaskFinished(os);
741 
742     //    2. Open "_common_data/workflow/dashboard/50_cutadapts.uwl".
743     GTFileDialog::openFile(os, testDir + "_common_data/workflow/dashboard/50_cutadapts.uwl");
744     GTUtilsTaskTreeView::waitTaskFinished(os);
745 
746     //    3. Click "Read File URL(s)" element.
747     GTUtilsWorkflowDesigner::click(os, "Read File URL(s)");
748 
749     //    4. Add "_common_data/fastq/eas.fastq" and "_common_data/fastq/eas_broken.fastq" files to "Dataset 1" dataset.
750     GTUtilsWorkflowDesigner::setDatasetInputFiles(os, {testDir + "_common_data/fastq/eas.fastq", testDir + "_common_data/fastq/eas_broken.fastq"});
751 
752     //    5. Launch the workflow.
753     GTUtilsWorkflowDesigner::runWorkflow(os);
754 
755     //    6. Wait the workflow execution finish.
756     GTUtilsTaskTreeView::waitTaskFinished(os);
757 
758     //    7. Switch to an "External Tools" tab.
759     GTUtilsDashboard::openTab(os, GTUtilsDashboard::ExternalTools);
760 
761     //    Expected result:
762     //    The tree looks like (note, that the elements order is not fixed):
763     //     -----------
764     //    Cut Adapter 1
765     //    ├Cut Adapter 1 run 1
766     //     |└cutadapt run
767     //    └Cut Adapter 1 run 2
768     //      └cutadapt run
769     //    Cut Adapter 2
770     //    ├Cut Adapter 2 run 1
771     //     |└cutadapt run
772     //    └Cut Adapter 2 run 2
773     //      └cutadapt run
774     //    ...
775     //    Cut Adapter 50
776     //    ├Cut Adapter 50 run 1
777     //     |└cutadapt run
778     //    └Cut Adapter 50 run 2
779     //      └cutadapt run
780     QMap<QString, QList<QPair<QString, QStringList>>> expectedNodesTexts;
781     QList<QPair<QString, QStringList>> secondLevelNodes;
782     for (int i = 1; i < 51; i++) {
783         expectedNodesTexts.insert(QString("Cut Adapter %1").arg(i), {qMakePair(QString("Cut Adapter %1 run 1").arg(i), QStringList({"cutadapt run"})), qMakePair(QString("Cut Adapter %1 run 2").arg(i), QStringList({"cutadapt run"}))});
784     }
785     checkTreeStructure(os, expectedNodesTexts);
786 }
787 
GUI_TEST_CLASS_DEFINITION(tree_nodes_creation_test_0004)788 GUI_TEST_CLASS_DEFINITION(tree_nodes_creation_test_0004) {
789     GTUtilsDialog::waitForDialogWhichMayRunOrNot(os, new StartupDialogFiller(os));
790 
791     //    1. Set the "_common_data/workflow/dashboard/fake_tools/fake_cutadapt.py" as "cutadapt" external tool in the "Application Settings".
792     const QString cutadaptToolName = "cutadapt";
793     const QString cutadaptToolPath = QDir::toNativeSeparators(QFileInfo(testDir + "_common_data/workflow/dashboard/fake_tools/fake_cutadapt.py").absoluteFilePath());
794     GTUtilsExternalTools::setToolUrl(os, cutadaptToolName, cutadaptToolPath);
795     GTUtilsTaskTreeView::waitTaskFinished(os);
796 
797     //    2. Open "_common_data/workflow/dashboard/101_cutadapts.uwl".
798     GTFileDialog::openFile(os, testDir + "_common_data/workflow/dashboard/101_cutadapts.uwl");
799     GTUtilsTaskTreeView::waitTaskFinished(os);
800 
801     //    3. Click "Read File URL(s)" element.
802     GTUtilsWorkflowDesigner::click(os, "Read File URL(s)");
803 
804     //    4. Add "data/samples/FASTQ/eas.fastq" file to "Dataset 1" dataset.
805     GTUtilsWorkflowDesigner::setDatasetInputFile(os, dataDir + "samples/FASTQ/eas.fastq", true);
806 
807     //    5. Launch the workflow.
808     GTUtilsWorkflowDesigner::runWorkflow(os);
809 
810     //    6. Wait the workflow execution finish.
811     GTUtilsTaskTreeView::waitTaskFinished(os);
812 
813     //    7. Switch to an "External Tools" tab.
814     GTUtilsDashboard::openTab(os, GTUtilsDashboard::ExternalTools);
815 
816     //    Expected result:
817     //    The tree looks like (note, that the elements order is not fixed):
818     //     -----------
819     //    Cut Adapter 1
820     //    └Cut Adapter 1 run 1
821     //      └cutadapt run
822     //    Cut Adapter 2
823     //    └Cut Adapter 2 run 1
824     //      └cutadapt run
825     //    ...
826     //    Cut Adapter 101
827     //    └Cut Adapter 101 run 1
828     //      └cutadapt run
829     //    Messages limit on the dashboard exceeded. See log files, if required.
830     //     -----------
831     //    "log files" in a message is a link to a dir with tools execution logs.
832     QMap<QString, QList<QPair<QString, QStringList>>> expectedNodesTexts;
833     QList<QPair<QString, QStringList>> secondLevelNodes;
834     for (int i = 1; i <= 100; i++) {
835         expectedNodesTexts.insert(QString("Cut Adapter %1").arg(i), {qMakePair(QString("Cut Adapter %1 run 1").arg(i), QStringList({"cutadapt run"}))});
836     }
837     checkTreeStructure(os, expectedNodesTexts);
838 
839     bool limitationMessageNodeExists = GTUtilsDashboard::hasLimitationMessage(os, GTUtilsDashboard::TREE_ROOT_ID);
840     CHECK_SET_ERR(limitationMessageNodeExists, QString("Message node unexpectedly not found, parent node ID: '%1'").arg(GTUtilsDashboard::TREE_ROOT_ID));
841 
842     QString messageNodeText = GTUtilsDashboard::getLimitationMessage(os, GTUtilsDashboard::TREE_ROOT_ID);
843     QString expectedMessageNodeText = "Messages limit on the dashboard exceeded.";
844     CHECK_SET_ERR(messageNodeText.startsWith(expectedMessageNodeText),
845                   QString("Unexpected message node text: expected '%1', got '%2'; parent node ID: '%3'")
846                       .arg(expectedMessageNodeText)
847                       .arg(messageNodeText)
848                       .arg(GTUtilsDashboard::TREE_ROOT_ID));
849 
850     QString logUrl = GTUtilsDashboard::getLogUrlFromNodeLimitationMessage(os, GTUtilsDashboard::TREE_ROOT_ID);
851 
852     QFileInfo fileInfo(logUrl);
853     CHECK_SET_ERR(fileInfo.exists(), QString("Dir with URL '%1' doesn't exist").arg(logUrl));
854     CHECK_SET_ERR(fileInfo.isDir(), QString("Entry with URL '%1' is not a dir").arg(logUrl));
855     CHECK_SET_ERR(!QDir(logUrl).entryList(QDir::Files).isEmpty(), QString("Dir with URL '%1' doesn't contain log files").arg(logUrl));
856 }
857 
GUI_TEST_CLASS_DEFINITION(tool_launch_nodes_test_0001)858 GUI_TEST_CLASS_DEFINITION(tool_launch_nodes_test_0001) {
859     GTUtilsDialog::waitForDialogWhichMayRunOrNot(os, new StartupDialogFiller(os));
860 
861     //    1. Open "_common_data/workflow/dashboard/clustulo_clustalw.uwl".
862     GTFileDialog::openFile(os, testDir + "_common_data/workflow/dashboard/clustulo_clustalw.uwl");
863     GTUtilsTaskTreeView::waitTaskFinished(os);
864 
865     //    2. Click "Read Alignment" element.
866     GTUtilsWorkflowDesigner::click(os, "Read Alignment");
867 
868     //    3. Add "data/samples/CLUSTALW/COI.aln" file to "Dataset 1" dataset.
869     GTUtilsWorkflowDesigner::setDatasetInputFile(os, dataDir + "samples/CLUSTALW/COI.aln", true);
870 
871     //    4. Launch the workflow.
872     GTLogTracer logTracer;
873     GTUtilsWorkflowDesigner::runWorkflow(os);
874 
875     //    5. Wait the workflow execution finish.
876     GTUtilsTaskTreeView::waitTaskFinished(os);
877 
878     //    6. Switch to an "External Tools" tab.
879     GTUtilsDashboard::openTab(os, GTUtilsDashboard::ExternalTools);
880 
881     //    Expected result:
882     //        the third-level node "ClustalO run" has a button to copy the command. The icon size is greater than 10x10 pixels.
883     //        the third-level node "ClustalW run" has a button to copy the command. The icon size is greater than 10x10 pixels.
884     const QString clustaloRunNodeId = GTUtilsDashboard::getDescendantNodeId(os, GTUtilsDashboard::TREE_ROOT_ID, {0, 0, 0});
885     QSize copyButtonSize = GTUtilsDashboard::getCopyButtonSize(os, clustaloRunNodeId);
886     QSize minimumCopyButtonSize(10, 10);
887 
888     CHECK_SET_ERR(minimumCopyButtonSize.width() <= copyButtonSize.width(),
889                   QString("Copy button width of node with ID '%1' is less than %2 pixels: it's width is %3 pixels")
890                       .arg(clustaloRunNodeId)
891                       .arg(minimumCopyButtonSize.width())
892                       .arg(copyButtonSize.width()));
893     CHECK_SET_ERR(minimumCopyButtonSize.height() <= copyButtonSize.height(),
894                   QString("Copy button height of node with ID '%1' is less than %2 pixels: it's height is %3 pixels")
895                       .arg(clustaloRunNodeId)
896                       .arg(minimumCopyButtonSize.height())
897                       .arg(copyButtonSize.height()));
898 
899     const QString clustalwRunNodeId = GTUtilsDashboard::getDescendantNodeId(os, GTUtilsDashboard::TREE_ROOT_ID, {1, 0, 0});
900     copyButtonSize = GTUtilsDashboard::getCopyButtonSize(os, clustalwRunNodeId);
901 
902     CHECK_SET_ERR(minimumCopyButtonSize.width() <= copyButtonSize.width(),
903                   QString("Copy button width of node with ID '%1' is less than %2 pixels: it's width is %3 pixels")
904                       .arg(clustalwRunNodeId)
905                       .arg(minimumCopyButtonSize.width())
906                       .arg(copyButtonSize.width()));
907     CHECK_SET_ERR(minimumCopyButtonSize.height() <= copyButtonSize.height(),
908                   QString("Copy button height of node with ID '%1' is less than %2 pixels: it's height is %3 pixels")
909                       .arg(clustalwRunNodeId)
910                       .arg(minimumCopyButtonSize.height())
911                       .arg(copyButtonSize.height()));
912 
913     //    7. Expand the third-level node "ClustalO run".
914     GTUtilsDashboard::expandNode(os, clustaloRunNodeId);
915 
916     //    Expected result:
917     //        the third-level node "ClustalO run" has a child node "Command".
918     //        the "Command" node has a child node with the command that was used to launch the "ClustalO" external tool.
919     //        log contains the command that is on the dashboard.
920     QString clustaloRunCommandNodeId = GTUtilsDashboard::getChildNodeId(os, clustaloRunNodeId, 0);
921     CHECK_SET_ERR(GTUtilsDashboard::isNodeVisible(os, clustaloRunCommandNodeId),
922                   QString("Node with ID '%1' is invisible after parent node expanding")
923                       .arg(clustaloRunCommandNodeId));
924 
925     QString nodeText = GTUtilsDashboard::getNodeText(os, clustaloRunCommandNodeId);
926     QString expectedNodeText = "Command";
927     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(clustaloRunCommandNodeId).arg(expectedNodeText).arg(nodeText));
928 
929     const QString clustaloRunCommandContentNodeId = GTUtilsDashboard::getChildNodeId(os, clustaloRunCommandNodeId, 0);
930     nodeText = GTUtilsDashboard::getNodeText(os, clustaloRunCommandContentNodeId);
931     QString expectedNodeTextPart = "clustalo";
932     CHECK_SET_ERR(nodeText.contains(expectedNodeTextPart),
933                   QString("Tool run command doesn't contain the following expected part: '%1'. Full command: '%2'")
934                       .arg(expectedNodeText)
935                       .arg(nodeText));
936     CHECK_SET_ERR(logTracer.checkMessage(nodeText), QString("Log doesn't contain the following expected message: '%1'").arg(nodeText));
937 
938     //    8. Click to the "Copy command" button that is in the third-level node "ClustalO run".
939     GTUtilsDashboard::clickCopyButton(os, clustaloRunNodeId);
940 
941     //    Expected result: the clipboard contains the same command as the child of "Command" node that belongs to "ClustalO run" does.
942     QString clipboardData = GTClipboard::text(os);
943     CHECK_SET_ERR(clipboardData == nodeText,
944                   QString("Clipboard data is not the same as 'Command' node text: clipboard data is '%1', node text is '%2'")
945                       .arg(clipboardData)
946                       .arg(nodeText));
947 
948     //    9. Expand the third-level node "ClustalW run".
949     GTUtilsDashboard::collapseNode(os, clustaloRunNodeId);
950     GTUtilsDashboard::expandNode(os, clustalwRunNodeId);
951 
952     //    Expected result:
953     //        the third-level node "ClustalW run" has a child node "Command".
954     //        the "Command" node has a child node with the command that was used to launch the "ClustalW" external tool.
955     //        log contains the command that is on the dashboard.
956     const QString clustalwRunCommandNodeId = GTUtilsDashboard::getChildNodeId(os, clustalwRunNodeId, 0);
957 
958     CHECK_SET_ERR(GTUtilsDashboard::isNodeVisible(os, clustalwRunCommandNodeId),
959                   QString("Node with ID '%1' is invisible after parent node expanding")
960                       .arg(clustalwRunCommandNodeId));
961 
962     nodeText = GTUtilsDashboard::getNodeText(os, clustalwRunCommandNodeId);
963     expectedNodeText = "Command";
964     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(clustalwRunCommandNodeId).arg(expectedNodeText).arg(nodeText));
965 
966     const QString clustalwRunCommandContentNodeId = GTUtilsDashboard::getChildNodeId(os, clustalwRunCommandNodeId, 0);
967     nodeText = GTUtilsDashboard::getNodeText(os, clustalwRunCommandContentNodeId);
968     expectedNodeTextPart = "clustalw";
969     CHECK_SET_ERR(nodeText.contains(expectedNodeTextPart),
970                   QString("Tool run command doesn't contain the following expected part: '%1'. Full command: '%2'")
971                       .arg(expectedNodeText)
972                       .arg(nodeText));
973     CHECK_SET_ERR(logTracer.checkMessage(nodeText), QString("Log doesn't contain the following expected message: '%1'").arg(nodeText));
974 
975     //    10. Click to the "Copy command" button that is in the third-level node "ClustalW run".
976     GTUtilsDashboard::clickCopyButton(os, clustalwRunNodeId);
977 
978     //    Expected result: the clipboard contains the same command as the child of "Command" node that belongs to "ClustalW run" does.
979     clipboardData = GTClipboard::text(os);
980     CHECK_SET_ERR(clipboardData == nodeText,
981                   QString("Clipboard data is not the same as 'Command' node text: clipboard data is '%1', node text is '%2'")
982                       .arg(clipboardData)
983                       .arg(nodeText));
984 }
985 
GUI_TEST_CLASS_DEFINITION(tool_launch_nodes_test_0002)986 GUI_TEST_CLASS_DEFINITION(tool_launch_nodes_test_0002) {
987     GTUtilsDialog::waitForDialogWhichMayRunOrNot(os, new StartupDialogFiller(os));
988 
989     //    1. Ensure that "ClustalO" tool doesn't contain spaces in its paths.
990     const QString toolName = "ClustalO";
991     QString toolPath = getExternalToolPath(os, toolName);
992     if (toolPath.contains(" ")) {
993         const QString newToolPath = putToolToFolderWithoutSpaces(os, toolName, getExternalToolDirPath(os, toolName, "clustalo"), sandBoxDir);
994         GTUtilsExternalTools::setToolUrl(os, toolName, QDir::toNativeSeparators(newToolPath));
995 
996         GTUtilsTaskTreeView::waitTaskFinished(os);
997         toolPath = getExternalToolPath(os, toolName);
998         CHECK_SET_ERR(QDir::toNativeSeparators(toolPath) == QDir::toNativeSeparators(newToolPath),
999                       QString("'%1' tool path wasn't set properly: expected '%2', got '%3'")
1000                           .arg(toolName)
1001                           .arg(newToolPath)
1002                           .arg(toolPath));
1003     }
1004 
1005     //    2. Open "_common_data/workflow/dashboard/clustulo.uwl".
1006     GTFileDialog::openFile(os, testDir + "_common_data/workflow/dashboard/clustulo.uwl");
1007     GTUtilsTaskTreeView::waitTaskFinished(os);
1008 
1009     //    3. Click "Read Alignment" element.
1010     GTUtilsWorkflowDesigner::click(os, "Read Alignment");
1011 
1012     //    4. Add "data/samples/CLUSTALW/COI.aln" file to "Dataset 1" dataset.
1013     GTUtilsWorkflowDesigner::setDatasetInputFile(os, dataDir + "samples/CLUSTALW/COI.aln", true);
1014 
1015     //    5. Launch the workflow.
1016     GTUtilsWorkflowDesigner::runWorkflow(os);
1017 
1018     //    6. Wait the workflow execution finish.
1019     GTUtilsTaskTreeView::waitTaskFinished(os);
1020 
1021     //    7. Switch to an "External Tools" tab.
1022     GTUtilsDashboard::openTab(os, GTUtilsDashboard::ExternalTools);
1023 
1024     //    8. Expand the third-level node "ClustalO run".
1025     const QString clustaloRunNodeId = GTUtilsDashboard::getDescendantNodeId(os, GTUtilsDashboard::TREE_ROOT_ID, {0, 0, 0});
1026     GTUtilsDashboard::expandNode(os, clustaloRunNodeId);
1027 
1028     //    Expected result: the third-level node "ClustalO run" has a child node "Command", which has a child node with the command. The first argument in the command is the path to the "ClustalO" that was set at the beginning, the path is not wrapped with double quotes.
1029     const QString clustaloRunCommandNodeId = GTUtilsDashboard::getChildNodeId(os, clustaloRunNodeId, 0);
1030     CHECK_SET_ERR(GTUtilsDashboard::isNodeVisible(os, clustaloRunCommandNodeId),
1031                   QString("Node with ID '%1' is invisible after parent node expanding").arg(clustaloRunCommandNodeId));
1032 
1033     QString nodeText = GTUtilsDashboard::getNodeText(os, clustaloRunCommandNodeId);
1034     QString expectedNodeText = "Command";
1035     CHECK_SET_ERR(expectedNodeText == nodeText,
1036                   QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(clustaloRunCommandNodeId).arg(expectedNodeText).arg(nodeText));
1037 
1038     const QString clustaloRunCommandContentNodeId = GTUtilsDashboard::getChildNodeId(os, clustaloRunCommandNodeId, 0);
1039     nodeText = GTUtilsDashboard::getNodeText(os, clustaloRunCommandContentNodeId);
1040     const QString expectedNodeTextPart = QString("%1 ").arg(toolPath);
1041     CHECK_SET_ERR(nodeText.startsWith(expectedNodeTextPart),
1042                   QString("Tool run command doesn't start with the following expected part: '%1'. Full command: '%2'")
1043                       .arg(expectedNodeTextPart)
1044                       .arg(nodeText));
1045 }
1046 
GUI_TEST_CLASS_DEFINITION(tool_launch_nodes_test_0003)1047 GUI_TEST_CLASS_DEFINITION(tool_launch_nodes_test_0003) {
1048     GTUtilsDialog::waitForDialogWhichMayRunOrNot(os, new StartupDialogFiller(os));
1049 
1050     //    1. Copy external tool "ClustalO" to a folder with spaces in its path.
1051     //    2. Set the copied "ClustalO" in the "Application Settings".
1052     const QString toolName = "ClustalO";
1053     QString toolPath = getExternalToolPath(os, toolName);
1054     if (!toolPath.contains(" ")) {
1055         const QString newToolPath = putToolToFolderWithSpaces(os, toolName, getExternalToolDirPath(os, toolName, "clustalo"), sandBoxDir);
1056         GTUtilsExternalTools::setToolUrl(os, toolName, QDir::toNativeSeparators(newToolPath));
1057 
1058         GTUtilsTaskTreeView::waitTaskFinished(os);
1059         toolPath = getExternalToolPath(os, toolName);
1060         CHECK_SET_ERR(QDir::toNativeSeparators(toolPath) == QDir::toNativeSeparators(newToolPath),
1061                       QString("'%1' tool path wasn't set properly: expected '%2', got '%3'")
1062                           .arg(toolName)
1063                           .arg(newToolPath)
1064                           .arg(toolPath));
1065     }
1066 
1067     //    3. Open "_common_data/workflow/dashboard/clustulo.uwl".
1068     GTFileDialog::openFile(os, testDir + "_common_data/workflow/dashboard/clustulo.uwl");
1069     GTUtilsTaskTreeView::waitTaskFinished(os);
1070 
1071     //    4. Click "Read Alignment" element.
1072     GTUtilsWorkflowDesigner::click(os, "Read Alignment");
1073 
1074     //    5. Add "data/samples/CLUSTALW/COI.aln" file to "Dataset 1" dataset.
1075     GTUtilsWorkflowDesigner::setDatasetInputFile(os, dataDir + "samples/CLUSTALW/COI.aln", true);
1076 
1077     //    6. Launch the workflow.
1078     GTUtilsWorkflowDesigner::runWorkflow(os);
1079 
1080     //    7. Wait the workflow execution finish.
1081     GTUtilsTaskTreeView::waitTaskFinished(os);
1082 
1083     //    8. Switch to an "External Tools" tab.
1084     GTUtilsDashboard::openTab(os, GTUtilsDashboard::ExternalTools);
1085 
1086     //    9. Expand the third-level node "ClustalO run".
1087     const QString clustaloRunNodeId = GTUtilsDashboard::getDescendantNodeId(os, GTUtilsDashboard::TREE_ROOT_ID, {0, 0, 0});
1088     GTUtilsDashboard::expandNode(os, clustaloRunNodeId);
1089 
1090     //    Expected result: the third-level node "ClustalO run" has a child node "Command", which has a child node with the command. The first argument in the command is the path to the "ClustalO" that was set at the beginning, the path is wrapped with double quotes.
1091     const QString clustaloRunCommandNodeId = GTUtilsDashboard::getChildNodeId(os, clustaloRunNodeId, 0);
1092     CHECK_SET_ERR(GTUtilsDashboard::isNodeVisible(os, clustaloRunCommandNodeId),
1093                   QString("Node with ID '%1' is invisible after parent node expanding")
1094                       .arg(clustaloRunCommandNodeId));
1095 
1096     QString nodeText = GTUtilsDashboard::getNodeText(os, clustaloRunCommandNodeId);
1097     QString expectedNodeText = "Command";
1098     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(clustaloRunCommandNodeId).arg(expectedNodeText).arg(nodeText));
1099 
1100     const QString clustaloRunCommandContentNodeId = GTUtilsDashboard::getChildNodeId(os, clustaloRunCommandNodeId, 0);
1101     nodeText = GTUtilsDashboard::getNodeText(os, clustaloRunCommandContentNodeId);
1102 
1103     const QString expectedNodeTextPart = getQuotedString(toolPath) + " ";
1104     CHECK_SET_ERR(nodeText.startsWith(expectedNodeTextPart),
1105                   QString("Tool run command doesn't start with the following expected part: '%1'. Full command: '%2'")
1106                       .arg(expectedNodeTextPart)
1107                       .arg(nodeText));
1108 }
1109 
GUI_TEST_CLASS_DEFINITION(tool_launch_nodes_test_0004)1110 GUI_TEST_CLASS_DEFINITION(tool_launch_nodes_test_0004) {
1111     GTUtilsDialog::waitForDialogWhichMayRunOrNot(os, new StartupDialogFiller(os));
1112 
1113     //    1. Ensure that neither "python" nor "cutadapt" contain spaces in their paths.
1114     const QString pythonToolName = "python";
1115     QString pythonToolPath = getExternalToolPath(os, pythonToolName);
1116     if (pythonToolPath.contains(" ")) {
1117         const QString newToolPath = putToolToFolderWithSpaces(os, pythonToolName, getExternalToolDirPath(os, pythonToolName, "python"), sandBoxDir);
1118         GTUtilsExternalTools::setToolUrl(os, pythonToolName, QDir::toNativeSeparators(newToolPath));
1119 
1120         GTUtilsTaskTreeView::waitTaskFinished(os);
1121         pythonToolPath = getExternalToolPath(os, pythonToolName);
1122         CHECK_SET_ERR(QDir::toNativeSeparators(pythonToolPath) == QDir::toNativeSeparators(newToolPath),
1123                       QString("'%1' tool path wasn't set properly: expected '%2', got '%3'")
1124                           .arg(pythonToolName)
1125                           .arg(newToolPath)
1126                           .arg(pythonToolPath));
1127     }
1128 
1129     const QString cutadaptToolName = "cutadapt";
1130     QString cutadaptToolPath = getExternalToolPath(os, cutadaptToolName);
1131     if (cutadaptToolPath.contains(" ")) {
1132         const QString newToolPath = putToolToFolderWithSpaces(os, cutadaptToolName, getExternalToolDirPath(os, cutadaptToolName, "cutadapt"), sandBoxDir);
1133         GTUtilsExternalTools::setToolUrl(os, cutadaptToolName, QDir::toNativeSeparators(newToolPath));
1134 
1135         GTUtilsTaskTreeView::waitTaskFinished(os);
1136         cutadaptToolPath = getExternalToolPath(os, cutadaptToolName);
1137         CHECK_SET_ERR(QDir::toNativeSeparators(cutadaptToolPath) == QDir::toNativeSeparators(newToolPath),
1138                       QString("'%1' tool path wasn't set properly: expected '%2', got '%3'")
1139                           .arg(cutadaptToolName)
1140                           .arg(newToolPath)
1141                           .arg(cutadaptToolPath));
1142     }
1143 
1144     //    1. Open "_common_data/workflow/dashboard/cutadapt.uwl".
1145     GTFileDialog::openFile(os, testDir + "_common_data/workflow/dashboard/cutadapt.uwl");
1146     GTUtilsTaskTreeView::waitTaskFinished(os);
1147 
1148     //    2. Click "Read File URL(s)" element.
1149     GTUtilsWorkflowDesigner::click(os, "Read File URL(s)");
1150 
1151     //    3. Add "data/samples/FASTQ/eas.fastq" file to "Dataset 1" dataset.
1152     GTUtilsWorkflowDesigner::setDatasetInputFile(os, dataDir + "samples/FASTQ/eas.fastq", true);
1153 
1154     //    4. Launch the workflow.
1155     GTUtilsWorkflowDesigner::runWorkflow(os);
1156 
1157     //    5. Wait the workflow execution finish.
1158     GTUtilsTaskTreeView::waitTaskFinished(os);
1159 
1160     //    6. Switch to an "External Tools" tab.
1161     GTUtilsDashboard::openTab(os, GTUtilsDashboard::ExternalTools);
1162 
1163     //    7. Expand the third-level node "cutadapt run".
1164     const QString cutadaptRunNodeId = GTUtilsDashboard::getDescendantNodeId(os, GTUtilsDashboard::TREE_ROOT_ID, {0, 0, 0});
1165     GTUtilsDashboard::expandNode(os, cutadaptRunNodeId);
1166 
1167     //    Expected result: the third-level node "cutadapt run" has a child node "Command", which has a child node with the command. The first argument in the command is the path to the "python", the second argument in the command is the path to "cutadapt". Neither the first nor the second argument is wrapped with double quotes.
1168     const QString cutadaptRunCommandNodeId = GTUtilsDashboard::getChildNodeId(os, cutadaptRunNodeId, 0);
1169     CHECK_SET_ERR(GTUtilsDashboard::isNodeVisible(os, cutadaptRunCommandNodeId),
1170                   QString("Node with ID '%1' is invisible after parent node expanding")
1171                       .arg(cutadaptRunCommandNodeId));
1172 
1173     QString nodeText = GTUtilsDashboard::getNodeText(os, cutadaptRunCommandNodeId);
1174     QString expectedNodeText = "Command";
1175     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(cutadaptRunCommandNodeId).arg(expectedNodeText).arg(nodeText));
1176 
1177     const QString cutadaptRunCommandContentNodeId = GTUtilsDashboard::getChildNodeId(os, cutadaptRunCommandNodeId, 0);
1178     nodeText = GTUtilsDashboard::getNodeText(os, cutadaptRunCommandContentNodeId);
1179     const QString expectedNodeTextPart = QString("%1 %2 ").arg(pythonToolPath).arg(cutadaptToolPath);
1180     CHECK_SET_ERR(nodeText.startsWith(expectedNodeTextPart),
1181                   QString("Tool run command doesn't start with the following expected part: '%1'. Full command: '%2'")
1182                       .arg(expectedNodeTextPart)
1183                       .arg(nodeText));
1184 }
1185 
GUI_TEST_CLASS_DEFINITION(tool_launch_nodes_test_0005)1186 GUI_TEST_CLASS_DEFINITION(tool_launch_nodes_test_0005) {
1187     GTUtilsDialog::waitForDialogWhichMayRunOrNot(os, new StartupDialogFiller(os));
1188 
1189     //    1. Copy external tool "python" to a folder with spaces in its path.
1190     //    2. Set the copied "python" in the "Application Settings".
1191     const QString pythonToolName = "python";
1192     QString pythonToolPath = getExternalToolPath(os, pythonToolName);
1193     if (!pythonToolPath.contains(" ")) {
1194         const QString newToolPath = putToolToFolderWithSpaces(os, pythonToolName, getExternalToolDirPath(os, pythonToolName, "python"), sandBoxDir);
1195         GTUtilsExternalTools::setToolUrl(os, pythonToolName, QDir::toNativeSeparators(newToolPath));
1196 
1197         GTUtilsTaskTreeView::waitTaskFinished(os);
1198         pythonToolPath = getExternalToolPath(os, pythonToolName);
1199         CHECK_SET_ERR(QDir::toNativeSeparators(pythonToolPath) == QDir::toNativeSeparators(newToolPath),
1200                       QString("'%1' tool path wasn't set properly: expected '%2', got '%3'")
1201                           .arg(pythonToolName)
1202                           .arg(newToolPath)
1203                           .arg(pythonToolPath));
1204     }
1205 
1206     //    3. Open "_common_data/workflow/dashboard/cutadapt.uwl".
1207     GTFileDialog::openFile(os, testDir + "_common_data/workflow/dashboard/cutadapt.uwl");
1208     GTUtilsTaskTreeView::waitTaskFinished(os);
1209 
1210     //    4. Click "Read File URL(s)" element.
1211     GTUtilsWorkflowDesigner::click(os, "Read File URL(s)");
1212 
1213     //    5. Add "data/samples/FASTQ/eas.fastq" file to "Dataset 1" dataset.
1214     GTUtilsWorkflowDesigner::setDatasetInputFile(os, dataDir + "samples/FASTQ/eas.fastq", true);
1215 
1216     //    6. Launch the workflow.
1217     GTUtilsWorkflowDesigner::runWorkflow(os);
1218 
1219     //    7. Wait the workflow execution finish.
1220     GTUtilsTaskTreeView::waitTaskFinished(os);
1221 
1222     //    8. Switch to an "External Tools" tab.
1223     GTUtilsDashboard::openTab(os, GTUtilsDashboard::ExternalTools);
1224 
1225     //    9. Expand the third-level node "cutadapt run".
1226     const QString cutadaptRunNodeId = GTUtilsDashboard::getDescendantNodeId(os, GTUtilsDashboard::TREE_ROOT_ID, {0, 0, 0});
1227     GTUtilsDashboard::expandNode(os, cutadaptRunNodeId);
1228 
1229     //    Expected result: the third-level node "cutadapt run" has a child node "Command", which has a child node with the command. The first argument in the command is the path to the "python" that was set at the beginning, the path is wrapped with double quotes.
1230     const QString cutadaptRunCommandNodeId = GTUtilsDashboard::getChildNodeId(os, cutadaptRunNodeId, 0);
1231     CHECK_SET_ERR(GTUtilsDashboard::isNodeVisible(os, cutadaptRunCommandNodeId),
1232                   QString("Node with ID '%1' is invisible after parent node expanding")
1233                       .arg(cutadaptRunCommandNodeId));
1234 
1235     QString nodeText = GTUtilsDashboard::getNodeText(os, cutadaptRunCommandNodeId);
1236     QString expectedNodeText = "Command";
1237     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(cutadaptRunCommandNodeId).arg(expectedNodeText).arg(nodeText));
1238 
1239     const QString cutadaptRunCommandContentNodeId = GTUtilsDashboard::getChildNodeId(os, cutadaptRunCommandNodeId, 0);
1240     nodeText = GTUtilsDashboard::getNodeText(os, cutadaptRunCommandContentNodeId);
1241     const QString expectedNodeTextPart = getQuotedString(pythonToolPath) + " ";
1242     CHECK_SET_ERR(nodeText.startsWith(expectedNodeTextPart),
1243                   QString("Tool run command doesn't start with the following expected part: '%1'. Full command: '%2'")
1244                       .arg(expectedNodeTextPart)
1245                       .arg(nodeText));
1246 }
1247 
GUI_TEST_CLASS_DEFINITION(tool_launch_nodes_test_0006)1248 GUI_TEST_CLASS_DEFINITION(tool_launch_nodes_test_0006) {
1249     GTUtilsDialog::waitForDialogWhichMayRunOrNot(os, new StartupDialogFiller(os));
1250 
1251     //    1. Copy external tool "cutadapt" to a folder with spaces in its path.
1252     //    2. Set the copied "cutadapt" in the "Application Settings".
1253     const QString cutadaptToolName = "cutadapt";
1254     QString cutadaptToolPath = getExternalToolPath(os, cutadaptToolName);
1255     if (!cutadaptToolPath.contains(" ")) {
1256         const QString newToolPath = putToolToFolderWithSpaces(os, cutadaptToolName, getExternalToolDirPath(os, cutadaptToolName, "cutadapt"), sandBoxDir);
1257         GTUtilsExternalTools::setToolUrl(os, cutadaptToolName, QDir::toNativeSeparators(newToolPath));
1258 
1259         GTUtilsTaskTreeView::waitTaskFinished(os);
1260         cutadaptToolPath = getExternalToolPath(os, cutadaptToolName);
1261         CHECK_SET_ERR(QDir::toNativeSeparators(cutadaptToolPath) == QDir::toNativeSeparators(newToolPath),
1262                       QString("'%1' tool path wasn't set properly: expected '%2', got '%3'")
1263                           .arg(cutadaptToolName)
1264                           .arg(newToolPath)
1265                           .arg(cutadaptToolPath));
1266     }
1267 
1268     //    3. Open "_common_data/workflow/dashboard/cutadapt.uwl".
1269     GTFileDialog::openFile(os, testDir + "_common_data/workflow/dashboard/cutadapt.uwl");
1270     GTUtilsTaskTreeView::waitTaskFinished(os);
1271 
1272     //    4. Click "Read File URL(s)" element.
1273     GTUtilsWorkflowDesigner::click(os, "Read File URL(s)");
1274 
1275     //    5. Add "data/samples/FASTQ/eas.fastq" file to "Dataset 1" dataset.
1276     GTUtilsWorkflowDesigner::setDatasetInputFile(os, dataDir + "samples/FASTQ/eas.fastq", true);
1277 
1278     //    6. Launch the workflow.
1279     GTUtilsWorkflowDesigner::runWorkflow(os);
1280 
1281     //    7. Wait the workflow execution finish.
1282     GTUtilsTaskTreeView::waitTaskFinished(os);
1283 
1284     //    8. Switch to an "External Tools" tab.
1285     GTUtilsDashboard::openTab(os, GTUtilsDashboard::ExternalTools);
1286 
1287     //    9. Expand the third-level node "cutadapt run".
1288     const QString cutadaptRunNodeId = GTUtilsDashboard::getDescendantNodeId(os, GTUtilsDashboard::TREE_ROOT_ID, {0, 0, 0});
1289     GTUtilsDashboard::expandNode(os, cutadaptRunNodeId);
1290 
1291     //    Expected result: the third-level node "cutadapt run" has a child node "Command", which has a child node with the command. The second argument in the command is the path to the "cutadapt" that was set at the beginning, the path is wrapped with double quotesos.setError("Not implemented");
1292     const QString cutadaptRunCommandNodeId = GTUtilsDashboard::getChildNodeId(os, cutadaptRunNodeId, 0);
1293     CHECK_SET_ERR(GTUtilsDashboard::isNodeVisible(os, cutadaptRunCommandNodeId),
1294                   QString("Node with ID '%1' is invisible after parent node expanding")
1295                       .arg(cutadaptRunCommandNodeId));
1296 
1297     QString nodeText = GTUtilsDashboard::getNodeText(os, cutadaptRunCommandNodeId);
1298     QString expectedNodeText = "Command";
1299     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(cutadaptRunCommandNodeId).arg(expectedNodeText).arg(nodeText));
1300 
1301     const QString cutadaptRunCommandContentNodeId = GTUtilsDashboard::getChildNodeId(os, cutadaptRunCommandNodeId, 0);
1302     nodeText = GTUtilsDashboard::getNodeText(os, cutadaptRunCommandContentNodeId);
1303     const QString expectedNodeTextPart = getQuotedString(cutadaptToolPath) + " ";
1304     CHECK_SET_ERR(nodeText.contains(expectedNodeTextPart),
1305                   QString("Tool run command doesn't contain the following expected part: '%1'. Full command: '%2'")
1306                       .arg(expectedNodeTextPart)
1307                       .arg(nodeText));
1308 }
1309 
GUI_TEST_CLASS_DEFINITION(tool_launch_nodes_test_0007)1310 GUI_TEST_CLASS_DEFINITION(tool_launch_nodes_test_0007) {
1311     GTUtilsDialog::waitForDialogWhichMayRunOrNot(os, new StartupDialogFiller(os));
1312 
1313     //    1. Copy external tool "python" to a folder with spaces in its path.
1314     //    2. Copy external tool "cutadapt" to a folder with spaces in its path.
1315     //    3. Set the copied "python" in the "Application Settings".
1316     //    4. Set the copied "cutadapt" in the "Application Settings".
1317     const QString pythonToolName = "python";
1318     QString pythonToolPath = getExternalToolPath(os, pythonToolName);
1319     if (!pythonToolPath.contains(" ")) {
1320         const QString newToolPath = putToolToFolderWithSpaces(os, pythonToolName, getExternalToolDirPath(os, pythonToolName, "python"), sandBoxDir);
1321         GTUtilsExternalTools::setToolUrl(os, pythonToolName, QDir::toNativeSeparators(newToolPath));
1322 
1323         GTUtilsTaskTreeView::waitTaskFinished(os);
1324         pythonToolPath = getExternalToolPath(os, pythonToolName);
1325         CHECK_SET_ERR(QDir::toNativeSeparators(pythonToolPath) == QDir::toNativeSeparators(newToolPath),
1326                       QString("'%1' tool path wasn't set properly: expected '%2', got '%3'")
1327                           .arg(pythonToolName)
1328                           .arg(newToolPath)
1329                           .arg(pythonToolPath));
1330     }
1331 
1332     const QString cutadaptToolName = "cutadapt";
1333     QString cutadaptToolPath = getExternalToolPath(os, cutadaptToolName);
1334     if (!cutadaptToolPath.contains(" ")) {
1335         const QString newToolPath = putToolToFolderWithSpaces(os, cutadaptToolName, getExternalToolDirPath(os, cutadaptToolName, "cutadapt"), sandBoxDir);
1336         GTUtilsExternalTools::setToolUrl(os, cutadaptToolName, QDir::toNativeSeparators(newToolPath));
1337 
1338         GTUtilsTaskTreeView::waitTaskFinished(os);
1339         cutadaptToolPath = getExternalToolPath(os, cutadaptToolName);
1340         CHECK_SET_ERR(QDir::toNativeSeparators(cutadaptToolPath) == QDir::toNativeSeparators(newToolPath),
1341                       QString("'%1' tool path wasn't set properly: expected '%2', got '%3'")
1342                           .arg(cutadaptToolName)
1343                           .arg(newToolPath)
1344                           .arg(cutadaptToolPath));
1345     }
1346 
1347     //    5. Open "_common_data/workflow/dashboard/cutadapt.uwl".
1348     GTFileDialog::openFile(os, testDir + "_common_data/workflow/dashboard/cutadapt.uwl");
1349     GTUtilsTaskTreeView::waitTaskFinished(os);
1350 
1351     //    6. Click "Read File URL(s)" element.
1352     GTUtilsWorkflowDesigner::click(os, "Read File URL(s)");
1353 
1354     //    7. Add "data/samples/FASTQ/eas.fastq" file to "Dataset 1" dataset.
1355     GTUtilsWorkflowDesigner::setDatasetInputFile(os, dataDir + "samples/FASTQ/eas.fastq", true);
1356 
1357     //    8. Launch the workflow.
1358     GTUtilsWorkflowDesigner::runWorkflow(os);
1359 
1360     //    9. Wait the workflow execution finish.
1361     GTUtilsTaskTreeView::waitTaskFinished(os);
1362 
1363     //    10. Switch to an "External Tools" tab.
1364     GTUtilsDashboard::openTab(os, GTUtilsDashboard::ExternalTools);
1365 
1366     //    11. Expand the third-level node "cutadapt run".
1367     const QString cutadaptRunNodeId = GTUtilsDashboard::getDescendantNodeId(os, GTUtilsDashboard::TREE_ROOT_ID, {0, 0, 0});
1368     GTUtilsDashboard::expandNode(os, cutadaptRunNodeId);
1369 
1370     //    Expected result: the third-level node "cutadapt run" has a child node "Command", which has a child node with the command. The first argument in the command is the path to the "python", the second argument in the command is the path to the "cutadapt". Both of them are wrapped with double quotes.
1371     const QString cutadaptRunCommandNodeId = GTUtilsDashboard::getChildNodeId(os, cutadaptRunNodeId, 0);
1372     CHECK_SET_ERR(GTUtilsDashboard::isNodeVisible(os, cutadaptRunCommandNodeId),
1373                   QString("Node with ID '%1' is invisible after parent node expanding")
1374                       .arg(cutadaptRunCommandNodeId));
1375 
1376     QString nodeText = GTUtilsDashboard::getNodeText(os, cutadaptRunCommandNodeId);
1377     QString expectedNodeText = "Command";
1378     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(cutadaptRunCommandNodeId).arg(expectedNodeText).arg(nodeText));
1379 
1380     const QString cutadaptRunCommandContentNodeId = GTUtilsDashboard::getChildNodeId(os, cutadaptRunCommandNodeId, 0);
1381     nodeText = GTUtilsDashboard::getNodeText(os, cutadaptRunCommandContentNodeId);
1382     const QString expectedNodeTextPart = getQuotedString(pythonToolPath) + " " + getQuotedString(cutadaptToolPath) + " ";
1383     CHECK_SET_ERR(nodeText.startsWith(expectedNodeTextPart),
1384                   QString("Tool run command doesn't start with the following expected part: '%1'. Full command: '%2'")
1385                       .arg(expectedNodeTextPart)
1386                       .arg(nodeText));
1387 }
1388 
GUI_TEST_CLASS_DEFINITION(tool_launch_nodes_test_0008)1389 GUI_TEST_CLASS_DEFINITION(tool_launch_nodes_test_0008) {
1390     GTUtilsDialog::waitForDialogWhichMayRunOrNot(os, new StartupDialogFiller(os));
1391 
1392     //    1. Ensure that file "data/samples/FASTQ/eas.fastq' is in the folder without spaces in the path.
1393     QString inputFileUrl = QFileInfo(dataDir + "samples/FASTQ/eas.fastq").absoluteFilePath();
1394     if (inputFileUrl.contains(" ")) {
1395         QString newInputFileUrl = QFileInfo(sandBoxDir + "eas.fastq").absoluteFilePath();
1396         CHECK_SET_ERR(!newInputFileUrl.contains(" "),
1397                       QString("Can't copy input file to a folder without spaces in the path, sandbox dir path contains spaces: %1").arg(sandBoxDir));
1398         GTFile::copy(os, inputFileUrl, newInputFileUrl);
1399         inputFileUrl = newInputFileUrl;
1400     }
1401 
1402     //    2. Open "_common_data/workflow/dashboard/cutadapt.uwl".
1403     GTFileDialog::openFile(os, testDir + "_common_data/workflow/dashboard/cutadapt.uwl");
1404     GTUtilsTaskTreeView::waitTaskFinished(os);
1405 
1406     //    3. Click "Read File URL(s)" element.
1407     GTUtilsWorkflowDesigner::click(os, "Read File URL(s)");
1408 
1409     //    4. Add "eas.fastq" from the step 1 file to "Dataset 1" dataset.
1410     GTUtilsWorkflowDesigner::setDatasetInputFile(os, inputFileUrl, true);
1411 
1412     //    5. Launch the workflow.
1413     GTUtilsWorkflowDesigner::runWorkflow(os);
1414 
1415     //    6. Wait the workflow execution finish.
1416     GTUtilsTaskTreeView::waitTaskFinished(os);
1417 
1418     //    7. Switch to an "External Tools" tab.
1419     GTUtilsDashboard::openTab(os, GTUtilsDashboard::ExternalTools);
1420 
1421     //    8. Expand the third-level node "cutadapt run".
1422     const QString cutadaptRunNodeId = GTUtilsDashboard::getDescendantNodeId(os, GTUtilsDashboard::TREE_ROOT_ID, {0, 0, 0});
1423     GTUtilsDashboard::expandNode(os, cutadaptRunNodeId);
1424 
1425     //    Expected result: the third-level node "cutadapt run" has a child node "Command", which has a child node with the command. The last argument in the command is the path to the input file. It is not wrapped with double quotes.
1426     const QString cutadaptRunCommandNodeId = GTUtilsDashboard::getChildNodeId(os, cutadaptRunNodeId, 0);
1427     CHECK_SET_ERR(GTUtilsDashboard::isNodeVisible(os, cutadaptRunCommandNodeId),
1428                   QString("Node with ID '%1' is invisible after parent node expanding")
1429                       .arg(cutadaptRunCommandNodeId));
1430 
1431     QString nodeText = GTUtilsDashboard::getNodeText(os, cutadaptRunCommandNodeId);
1432     QString expectedNodeText = "Command";
1433     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(cutadaptRunCommandNodeId).arg(expectedNodeText).arg(nodeText));
1434 
1435     const QString cutadaptRunCommandContentNodeId = GTUtilsDashboard::getChildNodeId(os, cutadaptRunCommandNodeId, 0);
1436     nodeText = GTUtilsDashboard::getNodeText(os, cutadaptRunCommandContentNodeId);
1437     const QString expectedNodeTextPart = QString(" %1").arg(inputFileUrl);
1438     CHECK_SET_ERR(nodeText.endsWith(expectedNodeTextPart),
1439                   QString("Tool run command doesn't end with the following expected part: '%1'. Full command: '%2'")
1440                       .arg(expectedNodeTextPart)
1441                       .arg(nodeText));
1442 }
1443 
GUI_TEST_CLASS_DEFINITION(tool_launch_nodes_test_0009)1444 GUI_TEST_CLASS_DEFINITION(tool_launch_nodes_test_0009) {
1445     GTUtilsDialog::waitForDialogWhichMayRunOrNot(os, new StartupDialogFiller(os));
1446 
1447     //    1. Copy "data/samples/FASTQ/eas.fastq" to a folder with spaces in its path.
1448     QString inputFileUrl = QFileInfo(dataDir + "samples/FASTQ/eas.fastq").absoluteFilePath();
1449     if (!inputFileUrl.contains(" ")) {
1450         QString newInputFileUrl = QFileInfo(sandBoxDir + "tool launch nodes test 0009").absoluteFilePath();
1451         QDir().mkpath(newInputFileUrl);
1452         newInputFileUrl += "/" + QFileInfo(inputFileUrl).fileName();
1453         GTFile::copy(os, inputFileUrl, newInputFileUrl);
1454         inputFileUrl = newInputFileUrl;
1455     }
1456 
1457     //    2. Open "_common_data/workflow/dashboard/cutadapt.uwl".
1458     GTFileDialog::openFile(os, testDir + "_common_data/workflow/dashboard/cutadapt.uwl");
1459     GTUtilsTaskTreeView::waitTaskFinished(os);
1460 
1461     //    3. Click "Read File URL(s)" element.
1462     GTUtilsWorkflowDesigner::click(os, "Read File URL(s)");
1463 
1464     //    4. Add the copied file to "Dataset 1" dataset.
1465     GTUtilsWorkflowDesigner::setDatasetInputFile(os, inputFileUrl, true);
1466 
1467     //    5. Launch the workflow.
1468     GTUtilsWorkflowDesigner::runWorkflow(os);
1469 
1470     //    6. Wait the workflow execution finish.
1471     GTUtilsTaskTreeView::waitTaskFinished(os);
1472 
1473     //    7. Switch to an "External Tools" tab.
1474     GTUtilsDashboard::openTab(os, GTUtilsDashboard::ExternalTools);
1475 
1476     //    8. Expand the third-level node "cutadapt run".
1477     const QString cutadaptRunNodeId = GTUtilsDashboard::getDescendantNodeId(os, GTUtilsDashboard::TREE_ROOT_ID, {0, 0, 0});
1478     GTUtilsDashboard::expandNode(os, cutadaptRunNodeId);
1479 
1480     //    Expected result: the third-level node "cutadapt run" has a child node "Command", which has a child node with the command. The last argument in the command is the path to the input file. It is wrapped with double quotes.
1481     const QString cutadaptRunCommandNodeId = GTUtilsDashboard::getChildNodeId(os, cutadaptRunNodeId, 0);
1482     CHECK_SET_ERR(GTUtilsDashboard::isNodeVisible(os, cutadaptRunCommandNodeId),
1483                   QString("Node with ID '%1' is invisible after parent node expanding")
1484                       .arg(cutadaptRunCommandNodeId));
1485 
1486     QString nodeText = GTUtilsDashboard::getNodeText(os, cutadaptRunCommandNodeId);
1487     QString expectedNodeText = "Command";
1488     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(cutadaptRunCommandNodeId).arg(expectedNodeText).arg(nodeText));
1489 
1490     const QString cutadaptRunCommandContentNodeId = GTUtilsDashboard::getChildNodeId(os, cutadaptRunCommandNodeId, 0);
1491     nodeText = GTUtilsDashboard::getNodeText(os, cutadaptRunCommandContentNodeId);
1492     const QString expectedNodeTextPart = QString(" \"%1\"").arg(inputFileUrl);
1493     CHECK_SET_ERR(nodeText.endsWith(expectedNodeTextPart),
1494                   QString("Tool run command doesn't end with the following expected part: '%1'. Full command: '%2'")
1495                       .arg(expectedNodeTextPart)
1496                       .arg(nodeText));
1497 }
1498 
GUI_TEST_CLASS_DEFINITION(tool_launch_nodes_test_0010)1499 GUI_TEST_CLASS_DEFINITION(tool_launch_nodes_test_0010) {
1500     GTUtilsDialog::waitForDialogWhichMayRunOrNot(os, new StartupDialogFiller(os));
1501 
1502     //    1. Set the "_common_data/workflow/dashboard/fake_tools/fake_spades_no_output.py" as "SPAdes" external tool in the "Application Settings".
1503     const QString spadesToolName = "SPAdes";
1504     const QString spadesToolPath = QDir::toNativeSeparators(QFileInfo(testDir + "_common_data/workflow/dashboard/fake_tools/fake_spades_no_output.py").absoluteFilePath());
1505     GTUtilsExternalTools::setToolUrl(os, spadesToolName, spadesToolPath);
1506     GTUtilsTaskTreeView::waitTaskFinished(os);
1507 
1508     //    2. Open "_common_data/workflow/dashboard/spades.uwl".
1509     GTFileDialog::openFile(os, testDir + "_common_data/workflow/dashboard/spades.uwl");
1510     GTUtilsTaskTreeView::waitTaskFinished(os);
1511 
1512     //    3. Click "Read File URL(s)" element.
1513     GTUtilsWorkflowDesigner::click(os, "Read File URL(s)");
1514 
1515     //    4. Add "data/samples/FASTQ/eas.fastq" file to "Dataset 1" dataset.
1516     GTUtilsWorkflowDesigner::setDatasetInputFile(os, dataDir + "samples/FASTQ/eas.fastq", true);
1517 
1518     //    5. Launch the workflow.
1519     GTUtilsWorkflowDesigner::runWorkflow(os);
1520 
1521     //    6. Wait the workflow execution finish.
1522     GTUtilsTaskTreeView::waitTaskFinished(os);
1523 
1524     //    7. Switch to an "External Tools" tab.
1525     GTUtilsDashboard::openTab(os, GTUtilsDashboard::ExternalTools);
1526 
1527     //    8. Expand the third-level node "SPAdes run".
1528     const QString spadesRunNodeId = GTUtilsDashboard::getDescendantNodeId(os, GTUtilsDashboard::TREE_ROOT_ID, {0, 0, 0});
1529     GTUtilsDashboard::expandNode(os, spadesRunNodeId);
1530 
1531     //    Expected result: the third-level node "SPAdes run" doesn't have child nodes "Output log (stdout)" and "Output log (stderr)".
1532     const int spadesRunNodeChildrenCount = GTUtilsDashboard::getChildrenNodesCount(os, spadesRunNodeId);
1533     const int expectedChildrenCount = 1;
1534     CHECK_SET_ERR(expectedChildrenCount == spadesRunNodeChildrenCount,
1535                   QString("Node with ID '%1' has unexpected children count: expected %2, got %3")
1536                       .arg(spadesRunNodeId)
1537                       .arg(expectedChildrenCount)
1538                       .arg(spadesRunNodeChildrenCount));
1539 
1540     const QString spadesRunCommandNodeId = GTUtilsDashboard::getChildNodeId(os, spadesRunNodeId, 0);
1541     CHECK_SET_ERR(GTUtilsDashboard::isNodeVisible(os, spadesRunCommandNodeId),
1542                   QString("Node with ID '%1' is invisible after parent node expanding")
1543                       .arg(spadesRunCommandNodeId));
1544 
1545     QString nodeText = GTUtilsDashboard::getNodeText(os, spadesRunCommandNodeId);
1546     QString expectedNodeText = "Command";
1547     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(spadesRunCommandNodeId).arg(expectedNodeText).arg(nodeText));
1548 }
1549 
GUI_TEST_CLASS_DEFINITION(tool_launch_nodes_test_0011)1550 GUI_TEST_CLASS_DEFINITION(tool_launch_nodes_test_0011) {
1551     GTUtilsDialog::waitForDialogWhichMayRunOrNot(os, new StartupDialogFiller(os));
1552 
1553     //    1. Set the "_common_data/workflow/dashboard/fake_tools/fake_spades_stdout_only.py" as "SPAdes" external tool in the "Application Settings".
1554     const QString spadesToolName = "SPAdes";
1555     const QString spadesToolPath = QDir::toNativeSeparators(QFileInfo(testDir + "_common_data/workflow/dashboard/fake_tools/fake_spades_stdout_only.py").absoluteFilePath());
1556     GTUtilsExternalTools::setToolUrl(os, spadesToolName, spadesToolPath);
1557     GTUtilsTaskTreeView::waitTaskFinished(os);
1558 
1559     //    2. Open "_common_data/workflow/dashboard/spades.uwl".
1560     GTFileDialog::openFile(os, testDir + "_common_data/workflow/dashboard/spades.uwl");
1561     GTUtilsTaskTreeView::waitTaskFinished(os);
1562 
1563     //    3. Click "Read File URL(s)" element.
1564     GTUtilsWorkflowDesigner::click(os, "Read File URL(s)");
1565 
1566     //    4. Add "data/samples/FASTQ/eas.fastq" file to "Dataset 1" dataset.
1567     GTUtilsWorkflowDesigner::setDatasetInputFile(os, dataDir + "samples/FASTQ/eas.fastq", true);
1568 
1569     //    5. Launch the workflow.
1570     GTUtilsWorkflowDesigner::runWorkflow(os);
1571 
1572     //    6. Wait the workflow execution finish.
1573     GTUtilsTaskTreeView::waitTaskFinished(os);
1574 
1575     //    7. Switch to an "External Tools" tab.
1576     GTUtilsDashboard::openTab(os, GTUtilsDashboard::ExternalTools);
1577 
1578     //    8. Expand the third-level node "SPAdes run".
1579     const QString spadesRunNodeId = GTUtilsDashboard::getDescendantNodeId(os, GTUtilsDashboard::TREE_ROOT_ID, {0, 0, 0});
1580     GTUtilsDashboard::expandNode(os, spadesRunNodeId);
1581 
1582     //    Expected result: the third-level node "SPAdes run" have a child node "Output log (stdout)" and doesn't have a child node "Output log (stderr)".
1583     const int spadesRunNodeChildrenCount = GTUtilsDashboard::getChildrenNodesCount(os, spadesRunNodeId);
1584     const int expectedChildrenCount = 2;
1585     CHECK_SET_ERR(expectedChildrenCount == spadesRunNodeChildrenCount,
1586                   QString("Node with ID '%1' has unexpected children count: expected %2, got %3")
1587                       .arg(spadesRunNodeId)
1588                       .arg(expectedChildrenCount)
1589                       .arg(spadesRunNodeChildrenCount));
1590 
1591     const QString spadesRunCommandNodeId = GTUtilsDashboard::getChildNodeId(os, spadesRunNodeId, 0);
1592     CHECK_SET_ERR(GTUtilsDashboard::isNodeVisible(os, spadesRunCommandNodeId),
1593                   QString("Node with ID '%1' is invisible after parent node expanding")
1594                       .arg(spadesRunCommandNodeId));
1595 
1596     QString nodeText = GTUtilsDashboard::getNodeText(os, spadesRunCommandNodeId);
1597     QString expectedNodeText = "Command";
1598     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(spadesRunCommandNodeId).arg(expectedNodeText).arg(nodeText));
1599 
1600     const QString spadesRunStdoutNodeId = GTUtilsDashboard::getChildNodeId(os, spadesRunNodeId, 1);
1601     CHECK_SET_ERR(GTUtilsDashboard::isNodeVisible(os, spadesRunStdoutNodeId),
1602                   QString("Node with ID '%1' is invisible after parent node expanding")
1603                       .arg(spadesRunStdoutNodeId));
1604 
1605     nodeText = GTUtilsDashboard::getNodeText(os, spadesRunStdoutNodeId);
1606     expectedNodeText = "Output log (stdout)";
1607     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(spadesRunStdoutNodeId).arg(expectedNodeText).arg(nodeText));
1608 }
1609 
GUI_TEST_CLASS_DEFINITION(tool_launch_nodes_test_0012)1610 GUI_TEST_CLASS_DEFINITION(tool_launch_nodes_test_0012) {
1611     GTUtilsDialog::waitForDialogWhichMayRunOrNot(os, new StartupDialogFiller(os));
1612 
1613     //    1. Set the "_common_data/workflow/dashboard/fake_tools/fake_spades_stderr_only.py" as "SPAdes" external tool in the "Application Settings".
1614     const QString spadesToolName = "SPAdes";
1615     const QString spadesToolPath = QDir::toNativeSeparators(QFileInfo(testDir + "_common_data/workflow/dashboard/fake_tools/fake_spades_stderr_only.py").absoluteFilePath());
1616     GTUtilsExternalTools::setToolUrl(os, spadesToolName, spadesToolPath);
1617     GTUtilsTaskTreeView::waitTaskFinished(os);
1618 
1619     //    2. Open "_common_data/workflow/dashboard/spades.uwl".
1620     GTFileDialog::openFile(os, testDir + "_common_data/workflow/dashboard/spades.uwl");
1621     GTUtilsTaskTreeView::waitTaskFinished(os);
1622 
1623     //    3. Click "Read File URL(s)" element.
1624     GTUtilsWorkflowDesigner::click(os, "Read File URL(s)");
1625 
1626     //    4. Add "data/samples/FASTQ/eas.fastq" file to "Dataset 1" dataset.
1627     GTUtilsWorkflowDesigner::setDatasetInputFile(os, dataDir + "samples/FASTQ/eas.fastq", true);
1628 
1629     //    5. Launch the workflow.
1630     GTUtilsWorkflowDesigner::runWorkflow(os);
1631 
1632     //    6. Wait the workflow execution finish.
1633     GTUtilsTaskTreeView::waitTaskFinished(os);
1634 
1635     //    7. Switch to an "External Tools" tab.
1636     GTUtilsDashboard::openTab(os, GTUtilsDashboard::ExternalTools);
1637 
1638     //    8. Expand the third-level node "SPAdes run".
1639     const QString spadesRunNodeId = GTUtilsDashboard::getDescendantNodeId(os, GTUtilsDashboard::TREE_ROOT_ID, {0, 0, 0});
1640     GTUtilsDashboard::expandNode(os, spadesRunNodeId);
1641 
1642     //    Expected result: the third-level node "SPAdes run" has a child node "Output log (stderr)" and doesn't have a child node "Output log (stdout)".
1643     const int spadesRunNodeChildrenCount = GTUtilsDashboard::getChildrenNodesCount(os, spadesRunNodeId);
1644     const int expectedChildrenCount = 2;
1645     CHECK_SET_ERR(expectedChildrenCount == spadesRunNodeChildrenCount,
1646                   QString("Node with ID '%1' has unexpected children count: expected %2, got %3")
1647                       .arg(spadesRunNodeId)
1648                       .arg(expectedChildrenCount)
1649                       .arg(spadesRunNodeChildrenCount));
1650 
1651     const QString spadesRunCommandNodeId = GTUtilsDashboard::getChildNodeId(os, spadesRunNodeId, 0);
1652     CHECK_SET_ERR(GTUtilsDashboard::isNodeVisible(os, spadesRunCommandNodeId),
1653                   QString("Node with ID '%1' is invisible after parent node expanding")
1654                       .arg(spadesRunCommandNodeId));
1655 
1656     QString nodeText = GTUtilsDashboard::getNodeText(os, spadesRunCommandNodeId);
1657     QString expectedNodeText = "Command";
1658     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(spadesRunCommandNodeId).arg(expectedNodeText).arg(nodeText));
1659 
1660     const QString spadesRunStderrNodeId = GTUtilsDashboard::getChildNodeId(os, spadesRunNodeId, 1);
1661     CHECK_SET_ERR(GTUtilsDashboard::isNodeVisible(os, spadesRunStderrNodeId),
1662                   QString("Node with ID '%1' is invisible after parent node expanding")
1663                       .arg(spadesRunStderrNodeId));
1664 
1665     nodeText = GTUtilsDashboard::getNodeText(os, spadesRunStderrNodeId);
1666     expectedNodeText = "Output log (stderr)";
1667     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(spadesRunStderrNodeId).arg(expectedNodeText).arg(nodeText));
1668 }
1669 
GUI_TEST_CLASS_DEFINITION(tool_launch_nodes_test_0013)1670 GUI_TEST_CLASS_DEFINITION(tool_launch_nodes_test_0013) {
1671     GTUtilsDialog::waitForDialogWhichMayRunOrNot(os, new StartupDialogFiller(os));
1672 
1673     //    1. Set the "_common_data/workflow/dashboard/fake_tools/fake_spades_stdout_and_stderr.py" as "SPAdes" external tool in the "Application Settings".
1674     const QString spadesToolName = "SPAdes";
1675     const QString spadesToolPath = QDir::toNativeSeparators(QFileInfo(testDir + "_common_data/workflow/dashboard/fake_tools/fake_spades_stdout_and_stderr.py").absoluteFilePath());
1676     GTUtilsExternalTools::setToolUrl(os, spadesToolName, spadesToolPath);
1677     GTUtilsTaskTreeView::waitTaskFinished(os);
1678 
1679     //    2. Open "_common_data/workflow/dashboard/spades.uwl".
1680     GTFileDialog::openFile(os, testDir + "_common_data/workflow/dashboard/spades.uwl");
1681     GTUtilsTaskTreeView::waitTaskFinished(os);
1682 
1683     //    3. Click "Read File URL(s)" element.
1684     GTUtilsWorkflowDesigner::click(os, "Read File URL(s)");
1685 
1686     //    4. Add "data/samples/FASTQ/eas.fastq" file to "Dataset 1" dataset.
1687     GTUtilsWorkflowDesigner::setDatasetInputFile(os, dataDir + "samples/FASTQ/eas.fastq", true);
1688 
1689     //    5. Launch the workflow.
1690     GTUtilsWorkflowDesigner::runWorkflow(os);
1691 
1692     //    6. Wait the workflow execution finish.
1693     GTUtilsTaskTreeView::waitTaskFinished(os);
1694 
1695     //    7. Switch to an "External Tools" tab.
1696     GTUtilsDashboard::openTab(os, GTUtilsDashboard::ExternalTools);
1697 
1698     //    8. Expand the third-level node "SPAdes run".
1699     const QString spadesRunNodeId = GTUtilsDashboard::getDescendantNodeId(os, GTUtilsDashboard::TREE_ROOT_ID, {0, 0, 0});
1700     GTUtilsDashboard::expandNode(os, spadesRunNodeId);
1701 
1702     //    Expected result: the third-level node "SPAdes run" has child nodes "Output log (stdout)" and "Output log (stderr)".
1703     const int spadesRunNodeChildrenCount = GTUtilsDashboard::getChildrenNodesCount(os, spadesRunNodeId);
1704     const int expectedChildrenCount = 3;
1705     CHECK_SET_ERR(expectedChildrenCount == spadesRunNodeChildrenCount,
1706                   QString("Node with ID '%1' has unexpected children count: expected %2, got %3")
1707                       .arg(spadesRunNodeId)
1708                       .arg(expectedChildrenCount)
1709                       .arg(spadesRunNodeChildrenCount));
1710 
1711     const QString spadesRunCommandNodeId = GTUtilsDashboard::getChildNodeId(os, spadesRunNodeId, 0);
1712     CHECK_SET_ERR(GTUtilsDashboard::isNodeVisible(os, spadesRunCommandNodeId),
1713                   QString("Node with ID '%1' is invisible after parent node expanding")
1714                       .arg(spadesRunCommandNodeId));
1715 
1716     QString nodeText = GTUtilsDashboard::getNodeText(os, spadesRunCommandNodeId);
1717     QString expectedNodeText = "Command";
1718     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(spadesRunCommandNodeId).arg(expectedNodeText).arg(nodeText));
1719 
1720     const QString oneOutNodeId = GTUtilsDashboard::getChildNodeId(os, spadesRunNodeId, 1);
1721     const QString anotherOutNodeId = GTUtilsDashboard::getChildNodeId(os, spadesRunNodeId, 2);
1722 
1723     QString spadesRunStdoutNodeId;
1724     QString spadesRunStderrNodeId;
1725     if (oneOutNodeId.contains("stderr")) {
1726         spadesRunStdoutNodeId = anotherOutNodeId;
1727         spadesRunStderrNodeId = oneOutNodeId;
1728     } else {
1729         spadesRunStdoutNodeId = oneOutNodeId;
1730         spadesRunStderrNodeId = anotherOutNodeId;
1731     }
1732 
1733     CHECK_SET_ERR(GTUtilsDashboard::isNodeVisible(os, spadesRunStdoutNodeId),
1734                   QString("Node with ID '%1' is invisible after parent node expanding")
1735                       .arg(spadesRunStdoutNodeId));
1736 
1737     nodeText = GTUtilsDashboard::getNodeText(os, spadesRunStdoutNodeId);
1738     expectedNodeText = "Output log (stdout)";
1739     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(spadesRunStdoutNodeId).arg(expectedNodeText).arg(nodeText));
1740 
1741     CHECK_SET_ERR(GTUtilsDashboard::isNodeVisible(os, spadesRunStderrNodeId),
1742                   QString("Node with ID '%1' is invisible after parent node expanding")
1743                       .arg(spadesRunStderrNodeId));
1744 
1745     nodeText = GTUtilsDashboard::getNodeText(os, spadesRunStderrNodeId);
1746     expectedNodeText = "Output log (stderr)";
1747     CHECK_SET_ERR(expectedNodeText == nodeText, QString("There is unexpected text of node with ID '%1': expected '%2', got '%3'").arg(spadesRunStderrNodeId).arg(expectedNodeText).arg(nodeText));
1748 }
1749 
GUI_TEST_CLASS_DEFINITION(tool_launch_nodes_test_0014)1750 GUI_TEST_CLASS_DEFINITION(tool_launch_nodes_test_0014) {
1751     GTUtilsDialog::waitForDialogWhichMayRunOrNot(os, new StartupDialogFiller(os));
1752 
1753     //    1. Ensure that taxonomy data is set. It should be full enough to pass the "kraken-build" validator.
1754     // Currently, it is impossible to set taxonomy data after UGENE launch: UGENE-5979
1755     // Test should be updated.
1756 
1757     //    2. Set the "_common_data/workflow/dashboard/fake_tools/fake_kraken-build" as "kraken-build" external tool in the "Application Settings".
1758     const QString krakenBuildToolName = "kraken-build";
1759     const QString spadesToolPath = QDir::toNativeSeparators(QFileInfo(testDir + "_common_data/workflow/dashboard/fake_tools/fake_kraken-build").absoluteFilePath());
1760     GTUtilsExternalTools::setToolUrl(os, krakenBuildToolName, spadesToolPath);
1761     GTUtilsTaskTreeView::waitTaskFinished(os);
1762 
1763     //    3. Open "_common_data/workflow/dashboard/kraken-build.uwl".
1764     GTFileDialog::openFile(os, testDir + "_common_data/workflow/dashboard/kraken-build.uwl");
1765     GTUtilsTaskTreeView::waitTaskFinished(os);
1766 
1767     //    4. Click "Build Kraken Database" element.
1768     GTUtilsWorkflowDesigner::click(os, "Build Kraken Database");
1769 
1770     //    5. Set "Database" attribute value to "tool_launch_nodes_test_0013".
1771     GTUtilsWorkflowDesigner::setParameter(os, "Database", "tool_launch_nodes_test_0013", GTUtilsWorkflowDesigner::textValue);
1772 
1773     //    6. Click the "..." button in the "Genomic library" attribute value field.
1774     //    Expected result: "Select Genomes for Kraken Database" dialog appeared.
1775     //    7. Add "data/samples/FASTA/human_T1.fa" file to the dataset in the dialog.
1776     //    8. Click the "Select" button in the dialog.
1777     GTUtilsDialog::waitForDialog(os, new GenomicLibraryDialogFiller(os, {dataDir + "samples/FASTA/human_T1.fa"}));
1778     GTUtilsWorkflowDesigner::setParameter(os, "Genomic library", QVariant(), GTUtilsWorkflowDesigner::customDialogSelector);
1779 
1780     //    9. Set "Clean" attribute value to "False".
1781     GTUtilsWorkflowDesigner::setParameter(os, "Clean", "False", GTUtilsWorkflowDesigner::comboValue);
1782 
1783     //    10. Launch the workflow.
1784     GTUtilsWorkflowDesigner::runWorkflow(os);
1785 
1786     //    11. Wait the workflow execution finish.
1787     GTUtilsTaskTreeView::waitTaskFinished(os);
1788 
1789     //    12. Switch to an "External Tools" tab.
1790     GTUtilsDashboard::openTab(os, GTUtilsDashboard::ExternalTools);
1791 
1792     //    Expected result: there is one second-level node "Build Kraken Database run 1", it has two child nodes: "kraken-build run 1" and "kraken-build run 2"
1793     const QString firstLevelNodeId = GTUtilsDashboard::getChildNodeId(os, GTUtilsDashboard::TREE_ROOT_ID, 0);
1794     int childrenCount = GTUtilsDashboard::getChildrenNodesCount(os, firstLevelNodeId);
1795     int expectedChildrenCount = 1;
1796     CHECK_SET_ERR(expectedChildrenCount == childrenCount,
1797                   QString("Node with ID '%1' has unexpected children count: expected %2, got %3")
1798                       .arg(firstLevelNodeId)
1799                       .arg(expectedChildrenCount)
1800                       .arg(childrenCount));
1801 
1802     const QString secondLevelNodeId = GTUtilsDashboard::getChildNodeId(os, firstLevelNodeId, 0);
1803     childrenCount = GTUtilsDashboard::getChildrenNodesCount(os, secondLevelNodeId);
1804     expectedChildrenCount = 2;
1805     CHECK_SET_ERR(expectedChildrenCount == childrenCount,
1806                   QString("Node with ID '%1' has unexpected children count: expected %2, got %3")
1807                       .arg(secondLevelNodeId)
1808                       .arg(expectedChildrenCount)
1809                       .arg(childrenCount));
1810 
1811     QString nodeText = GTUtilsDashboard::getNodeText(os, secondLevelNodeId);
1812     QString expectedNodeText = "Build Kraken Database run 1";
1813     CHECK_SET_ERR(expectedNodeText == nodeText,
1814                   QString("Node with ID '%1' has unexpected text: expected '%2', got '%3'")
1815                       .arg(secondLevelNodeId)
1816                       .arg(expectedNodeText)
1817                       .arg(nodeText));
1818 
1819     const QString thirdLevelNodeId1 = GTUtilsDashboard::getChildNodeId(os, secondLevelNodeId, 0);
1820     nodeText = GTUtilsDashboard::getNodeText(os, thirdLevelNodeId1);
1821     expectedNodeText = "kraken-build run 1 ";
1822     CHECK_SET_ERR(expectedNodeText == nodeText,
1823                   QString("Node with ID '%1' has unexpected text: expected '%2', got '%3'")
1824                       .arg(thirdLevelNodeId1)
1825                       .arg(expectedNodeText)
1826                       .arg(nodeText));
1827 
1828     const QString thirdLevelNodeId2 = GTUtilsDashboard::getChildNodeId(os, secondLevelNodeId, 1);
1829     nodeText = GTUtilsDashboard::getNodeText(os, thirdLevelNodeId2);
1830     expectedNodeText = "kraken-build run 2 ";
1831     CHECK_SET_ERR(expectedNodeText == nodeText,
1832                   QString("Node with ID '%1' has unexpected text: expected '%2', got '%3'")
1833                       .arg(thirdLevelNodeId2)
1834                       .arg(expectedNodeText)
1835                       .arg(nodeText));
1836 
1837     //    13. Expand the third-level node "kraken-build run 1".
1838     GTUtilsDashboard::expandNode(os, thirdLevelNodeId1);
1839 
1840     //    Expected result: the third-level node "kraken-build run 1" has child nodes "Command", "Output log (stdout)" and "Output log (stderr)". These nodes contain text "--add-to-library".
1841     childrenCount = GTUtilsDashboard::getChildrenNodesCount(os, thirdLevelNodeId1);
1842     expectedChildrenCount = 3;
1843     CHECK_SET_ERR(expectedChildrenCount == childrenCount,
1844                   QString("Node with ID '%1' has unexpected children count: expected %2, got %3")
1845                       .arg(thirdLevelNodeId1)
1846                       .arg(expectedChildrenCount)
1847                       .arg(childrenCount));
1848 
1849     // Command node
1850     QString commandTitleNodeId = GTUtilsDashboard::getChildNodeId(os, thirdLevelNodeId1, 0);
1851 
1852     CHECK_SET_ERR(GTUtilsDashboard::isNodeVisible(os, commandTitleNodeId),
1853                   QString("Node with ID '%1' is unexpectedly invisible")
1854                       .arg(commandTitleNodeId));
1855 
1856     nodeText = GTUtilsDashboard::getNodeText(os, commandTitleNodeId);
1857     expectedNodeText = "Command";
1858     CHECK_SET_ERR(expectedNodeText == nodeText,
1859                   QString("Node with ID '%1' has unexpected text: expected '%2', got '%3'")
1860                       .arg(commandTitleNodeId)
1861                       .arg(expectedNodeText)
1862                       .arg(nodeText));
1863 
1864     childrenCount = GTUtilsDashboard::getChildrenNodesCount(os, commandTitleNodeId);
1865     expectedChildrenCount = 1;
1866     CHECK_SET_ERR(expectedChildrenCount == childrenCount,
1867                   QString("Node with ID '%1' has unexpected children count: expected %2, got %3")
1868                       .arg(commandTitleNodeId)
1869                       .arg(expectedChildrenCount)
1870                       .arg(childrenCount));
1871 
1872     QString commandDataNodeId = GTUtilsDashboard::getChildNodeId(os, commandTitleNodeId, 0);
1873 
1874     CHECK_SET_ERR(GTUtilsDashboard::isNodeVisible(os, commandDataNodeId),
1875                   QString("Node with ID '%1' is unexpectedly invisible")
1876                       .arg(commandDataNodeId));
1877 
1878     nodeText = GTUtilsDashboard::getNodeText(os, commandDataNodeId);
1879     QString expectedNodeTextPart = "--add-to-library";
1880     CHECK_SET_ERR(nodeText.contains(expectedNodeTextPart),
1881                   QString("Node with ID '%1' text doesn't contain expected text: expected part is '%2', full node text is '%3'")
1882                       .arg(commandDataNodeId)
1883                       .arg(expectedNodeTextPart)
1884                       .arg(nodeText));
1885 
1886     // Output nodes
1887     QString oneOutNodeId = GTUtilsDashboard::getChildNodeId(os, thirdLevelNodeId1, 1);
1888     QString anotherOutNodeId = GTUtilsDashboard::getChildNodeId(os, thirdLevelNodeId1, 2);
1889 
1890     QString stdoutTitleNodeId;
1891     QString stderrTitleNodeId;
1892     if (oneOutNodeId.contains("stderr")) {
1893         stdoutTitleNodeId = anotherOutNodeId;
1894         stderrTitleNodeId = oneOutNodeId;
1895     } else {
1896         stdoutTitleNodeId = oneOutNodeId;
1897         stderrTitleNodeId = anotherOutNodeId;
1898     }
1899 
1900     // Output log (stdout) node
1901     CHECK_SET_ERR(GTUtilsDashboard::isNodeVisible(os, stdoutTitleNodeId),
1902                   QString("Node with ID '%1' is unexpectedly invisible")
1903                       .arg(stdoutTitleNodeId));
1904 
1905     nodeText = GTUtilsDashboard::getNodeText(os, stdoutTitleNodeId);
1906     expectedNodeText = "Output log (stdout)";
1907     CHECK_SET_ERR(expectedNodeText == nodeText,
1908                   QString("Node with ID '%1' has unexpected text: expected '%2', got '%3'")
1909                       .arg(stdoutTitleNodeId)
1910                       .arg(expectedNodeText)
1911                       .arg(nodeText));
1912 
1913     childrenCount = GTUtilsDashboard::getChildrenNodesCount(os, stdoutTitleNodeId);
1914     expectedChildrenCount = 1;
1915     CHECK_SET_ERR(expectedChildrenCount == childrenCount,
1916                   QString("Node with ID '%1' has unexpected children count: expected %2, got %3")
1917                       .arg(stdoutTitleNodeId)
1918                       .arg(expectedChildrenCount)
1919                       .arg(childrenCount));
1920 
1921     QString stdoutDataNodeId = GTUtilsDashboard::getChildNodeId(os, stdoutTitleNodeId, 0);
1922 
1923     CHECK_SET_ERR(GTUtilsDashboard::isNodeVisible(os, stdoutDataNodeId),
1924                   QString("Node with ID '%1' is unexpectedly invisible")
1925                       .arg(stdoutDataNodeId));
1926 
1927     nodeText = GTUtilsDashboard::getNodeText(os, stdoutDataNodeId);
1928     expectedNodeTextPart = "--add-to-library";
1929     CHECK_SET_ERR(nodeText.contains(expectedNodeTextPart),
1930                   QString("Node with ID '%1' text doesn't contain expected text: expected part is '%2', full node text is '%3'")
1931                       .arg(stdoutDataNodeId)
1932                       .arg(expectedNodeTextPart)
1933                       .arg(nodeText));
1934 
1935     // Output log (stderr) node
1936     CHECK_SET_ERR(GTUtilsDashboard::isNodeVisible(os, stderrTitleNodeId),
1937                   QString("Node with ID '%1' is unexpectedly invisible")
1938                       .arg(stderrTitleNodeId));
1939 
1940     nodeText = GTUtilsDashboard::getNodeText(os, stderrTitleNodeId);
1941     expectedNodeText = "Output log (stderr)";
1942     CHECK_SET_ERR(expectedNodeText == nodeText,
1943                   QString("Node with ID '%1' has unexpected text: expected '%2', got '%3'")
1944                       .arg(stderrTitleNodeId)
1945                       .arg(expectedNodeText)
1946                       .arg(nodeText));
1947 
1948     childrenCount = GTUtilsDashboard::getChildrenNodesCount(os, stderrTitleNodeId);
1949     expectedChildrenCount = 1;
1950     CHECK_SET_ERR(expectedChildrenCount == childrenCount,
1951                   QString("Node with ID '%1' has unexpected children count: expected %2, got %3")
1952                       .arg(stderrTitleNodeId)
1953                       .arg(expectedChildrenCount)
1954                       .arg(childrenCount));
1955 
1956     QString stderrDataNodeId = GTUtilsDashboard::getChildNodeId(os, stderrTitleNodeId, 0);
1957 
1958     CHECK_SET_ERR(GTUtilsDashboard::isNodeVisible(os, stderrDataNodeId),
1959                   QString("Node with ID '%1' is unexpectedly invisible")
1960                       .arg(stderrDataNodeId));
1961 
1962     nodeText = GTUtilsDashboard::getNodeText(os, stderrDataNodeId);
1963     expectedNodeTextPart = "--add-to-library";
1964     CHECK_SET_ERR(nodeText.contains(expectedNodeTextPart),
1965                   QString("Node with ID '%1' text doesn't contain expected text: expected part is '%2', full node text is '%3'")
1966                       .arg(stderrDataNodeId)
1967                       .arg(expectedNodeTextPart)
1968                       .arg(nodeText));
1969 
1970     //    14. Expand the third-level node "kraken-build run 2".
1971     GTUtilsDashboard::collapseNode(os, thirdLevelNodeId1);
1972     GTUtilsDashboard::expandNode(os, thirdLevelNodeId2);
1973 
1974     //    Expected result: the third-level node "kraken-build run 2" has child nodes "Command", "Output log (stdout)" and "Output log (stderr)". These nodes contain text "--build".
1975     childrenCount = GTUtilsDashboard::getChildrenNodesCount(os, thirdLevelNodeId1);
1976     expectedChildrenCount = 3;
1977     CHECK_SET_ERR(expectedChildrenCount == childrenCount,
1978                   QString("Node with ID '%1' has unexpected children count: expected %2, got %3")
1979                       .arg(thirdLevelNodeId2)
1980                       .arg(expectedChildrenCount)
1981                       .arg(childrenCount));
1982 
1983     // Command node
1984     commandTitleNodeId = GTUtilsDashboard::getChildNodeId(os, thirdLevelNodeId2, 0);
1985 
1986     CHECK_SET_ERR(GTUtilsDashboard::isNodeVisible(os, commandTitleNodeId),
1987                   QString("Node with ID '%1' is unexpectedly invisible")
1988                       .arg(commandTitleNodeId));
1989 
1990     nodeText = GTUtilsDashboard::getNodeText(os, commandTitleNodeId);
1991     expectedNodeText = "Command";
1992     CHECK_SET_ERR(expectedNodeText == nodeText,
1993                   QString("Node with ID '%1' has unexpected text: expected '%2', got '%3'")
1994                       .arg(commandTitleNodeId)
1995                       .arg(expectedNodeText)
1996                       .arg(nodeText));
1997 
1998     childrenCount = GTUtilsDashboard::getChildrenNodesCount(os, commandTitleNodeId);
1999     expectedChildrenCount = 1;
2000     CHECK_SET_ERR(expectedChildrenCount == childrenCount,
2001                   QString("Node with ID '%1' has unexpected children count: expected %2, got %3")
2002                       .arg(commandTitleNodeId)
2003                       .arg(expectedChildrenCount)
2004                       .arg(childrenCount));
2005 
2006     commandDataNodeId = GTUtilsDashboard::getChildNodeId(os, commandTitleNodeId, 0);
2007 
2008     CHECK_SET_ERR(GTUtilsDashboard::isNodeVisible(os, commandDataNodeId),
2009                   QString("Node with ID '%1' is unexpectedly invisible")
2010                       .arg(commandDataNodeId));
2011 
2012     nodeText = GTUtilsDashboard::getNodeText(os, commandDataNodeId);
2013     expectedNodeTextPart = "--build";
2014     CHECK_SET_ERR(nodeText.contains(expectedNodeTextPart),
2015                   QString("Node with ID '%1' text doesn't contain expected text: expected part is '%2', full node text is '%3'")
2016                       .arg(commandDataNodeId)
2017                       .arg(expectedNodeTextPart)
2018                       .arg(nodeText));
2019 
2020     // Output nodes
2021     oneOutNodeId = GTUtilsDashboard::getChildNodeId(os, thirdLevelNodeId2, 1);
2022     anotherOutNodeId = GTUtilsDashboard::getChildNodeId(os, thirdLevelNodeId2, 2);
2023 
2024     if (oneOutNodeId.contains("stderr")) {
2025         stdoutTitleNodeId = anotherOutNodeId;
2026         stderrTitleNodeId = oneOutNodeId;
2027     } else {
2028         stdoutTitleNodeId = oneOutNodeId;
2029         stderrTitleNodeId = anotherOutNodeId;
2030     }
2031 
2032     // Output log (stdout) node
2033     CHECK_SET_ERR(GTUtilsDashboard::isNodeVisible(os, stdoutTitleNodeId),
2034                   QString("Node with ID '%1' is unexpectedly invisible")
2035                       .arg(stdoutTitleNodeId));
2036 
2037     nodeText = GTUtilsDashboard::getNodeText(os, stdoutTitleNodeId);
2038     expectedNodeText = "Output log (stdout)";
2039     CHECK_SET_ERR(expectedNodeText == nodeText,
2040                   QString("Node with ID '%1' has unexpected text: expected '%2', got '%3'")
2041                       .arg(stdoutTitleNodeId)
2042                       .arg(expectedNodeText)
2043                       .arg(nodeText));
2044 
2045     childrenCount = GTUtilsDashboard::getChildrenNodesCount(os, stdoutTitleNodeId);
2046     expectedChildrenCount = 1;
2047     CHECK_SET_ERR(expectedChildrenCount == childrenCount,
2048                   QString("Node with ID '%1' has unexpected children count: expected %2, got %3")
2049                       .arg(stdoutTitleNodeId)
2050                       .arg(expectedChildrenCount)
2051                       .arg(childrenCount));
2052 
2053     stdoutDataNodeId = GTUtilsDashboard::getChildNodeId(os, stdoutTitleNodeId, 0);
2054 
2055     CHECK_SET_ERR(GTUtilsDashboard::isNodeVisible(os, stdoutDataNodeId),
2056                   QString("Node with ID '%1' is unexpectedly invisible")
2057                       .arg(stdoutDataNodeId));
2058 
2059     nodeText = GTUtilsDashboard::getNodeText(os, stdoutDataNodeId);
2060     expectedNodeTextPart = "--build";
2061     CHECK_SET_ERR(nodeText.contains(expectedNodeTextPart),
2062                   QString("Node with ID '%1' text doesn't contain expected text: expected part is '%2', full node text is '%3'")
2063                       .arg(stdoutDataNodeId)
2064                       .arg(expectedNodeTextPart)
2065                       .arg(nodeText));
2066 
2067     // Output log (stderr) node
2068     CHECK_SET_ERR(GTUtilsDashboard::isNodeVisible(os, stderrTitleNodeId),
2069                   QString("Node with ID '%1' is unexpectedly invisible")
2070                       .arg(stderrTitleNodeId));
2071 
2072     nodeText = GTUtilsDashboard::getNodeText(os, stderrTitleNodeId);
2073     expectedNodeText = "Output log (stderr)";
2074     CHECK_SET_ERR(expectedNodeText == nodeText,
2075                   QString("Node with ID '%1' has unexpected text: expected '%2', got '%3'")
2076                       .arg(stderrTitleNodeId)
2077                       .arg(expectedNodeText)
2078                       .arg(nodeText));
2079 
2080     childrenCount = GTUtilsDashboard::getChildrenNodesCount(os, stderrTitleNodeId);
2081     expectedChildrenCount = 1;
2082     CHECK_SET_ERR(expectedChildrenCount == childrenCount,
2083                   QString("Node with ID '%1' has unexpected children count: expected %2, got %3")
2084                       .arg(stderrTitleNodeId)
2085                       .arg(expectedChildrenCount)
2086                       .arg(childrenCount));
2087 
2088     stderrDataNodeId = GTUtilsDashboard::getChildNodeId(os, stderrTitleNodeId, 0);
2089 
2090     CHECK_SET_ERR(GTUtilsDashboard::isNodeVisible(os, stderrDataNodeId),
2091                   QString("Node with ID '%1' is unexpectedly invisible")
2092                       .arg(stderrDataNodeId));
2093 
2094     nodeText = GTUtilsDashboard::getNodeText(os, stderrDataNodeId);
2095     expectedNodeTextPart = "--build";
2096     CHECK_SET_ERR(nodeText.contains(expectedNodeTextPart),
2097                   QString("Node with ID '%1' text doesn't contain expected text: expected part is '%2', full node text is '%3'")
2098                       .arg(stderrDataNodeId)
2099                       .arg(expectedNodeTextPart)
2100                       .arg(nodeText));
2101 }
2102 
GUI_TEST_CLASS_DEFINITION(tool_launch_nodes_test_0015)2103 GUI_TEST_CLASS_DEFINITION(tool_launch_nodes_test_0015) {
2104     GTUtilsDialog::waitForDialogWhichMayRunOrNot(os, new StartupDialogFiller(os));
2105 
2106     //    1. Set the "_common_data/workflow/dashboard/fake_tools/fake_spades_stdout_only.py" as "SPAdes" external tool in the "Application Settings".
2107     const QString spadesToolName = "SPAdes";
2108     const QString spadesToolPath = QDir::toNativeSeparators(QFileInfo(testDir + "_common_data/workflow/dashboard/fake_tools/fake_spades_stdout_only.py").absoluteFilePath());
2109     GTUtilsExternalTools::setToolUrl(os, spadesToolName, spadesToolPath);
2110     GTUtilsTaskTreeView::waitTaskFinished(os);
2111 
2112     //    2. Open "_common_data/workflow/dashboard/spades.uwl".
2113     GTFileDialog::openFile(os, testDir + "_common_data/workflow/dashboard/spades.uwl");
2114     GTUtilsTaskTreeView::waitTaskFinished(os);
2115 
2116     //    3. Click "Read File URL(s)" element.
2117     GTUtilsWorkflowDesigner::click(os, "Read File URL(s)");
2118 
2119     //    4. Add "data/samples/FASTQ/eas.fastq" file to "Dataset 1" dataset.
2120     GTUtilsWorkflowDesigner::setDatasetInputFile(os, dataDir + "samples/FASTQ/eas.fastq", true);
2121 
2122     //    5. Launch the workflow.
2123     GTUtilsWorkflowDesigner::runWorkflow(os);
2124 
2125     //    6. Wait the workflow execution finish.
2126     GTUtilsTaskTreeView::waitTaskFinished(os);
2127 
2128     //    7. Switch to an "External Tools" tab.
2129     GTUtilsDashboard::openTab(os, GTUtilsDashboard::ExternalTools);
2130 
2131     //    8. Expand the third-level node "SPAdes run".
2132     const QString spadesRunNodeId = GTUtilsDashboard::getDescendantNodeId(os, GTUtilsDashboard::TREE_ROOT_ID, {0, 0, 0});
2133     GTUtilsDashboard::expandNode(os, spadesRunNodeId);
2134 
2135     //    Expected result:
2136     //        the third-level node "SPAdes run" has child node "Output log (stdout)".
2137     const QString stdoutTitleNodeId = GTUtilsDashboard::getChildNodeId(os, spadesRunNodeId, 1);
2138 
2139     QString nodeText = GTUtilsDashboard::getNodeText(os, stdoutTitleNodeId);
2140     QString expectedNodeText = "Output log (stdout)";
2141     CHECK_SET_ERR(nodeText.startsWith(expectedNodeText),
2142                   QString("Node with ID '%1' has unexpected text: expected '%2', got '%3'")
2143                       .arg(stdoutTitleNodeId)
2144                       .arg(expectedNodeText)
2145                       .arg(nodeText));
2146 
2147     const QString stdoutDataNodeId = GTUtilsDashboard::getChildNodeId(os, stdoutTitleNodeId, 0);
2148 
2149     //        the "Output log (stdout)" node content has significant size (~100 kb of text).
2150     nodeText = GTUtilsDashboard::getNodeText(os, stdoutDataNodeId);
2151     int expectedLength = 80000;
2152     CHECK_SET_ERR(nodeText.size() > expectedLength,
2153                   QString("Node with ID '%1' text is not long enough: expected length is at least %2, actual text length is %3")
2154                       .arg(stdoutDataNodeId)
2155                       .arg(expectedLength)
2156                       .arg(nodeText.size()));
2157 
2158     //        the "Output log (stdout)" node content ends with the following message: "The external tool output is too large and can't be visualized on the dashboard. Find full output in this file.", where "this file" is a link to the log file.
2159     QString expectedNodeTextPart = "The external tool output is too large and can't be visualized on the dashboard.";
2160     CHECK_SET_ERR(nodeText.contains(expectedNodeTextPart),
2161                   QString("Node with ID '%1' text doesn't contains the expected part: expected part '%2', last 300 symbols of the text '%3'")
2162                       .arg(stdoutDataNodeId)
2163                       .arg(expectedNodeTextPart)
2164                       .arg(nodeText.right(300)));
2165 
2166     //        the link from the previous item is correct: it points to a file with the same data; the file size is not less than the node contents size; the file name contains "stdout".
2167     const QString url = GTUtilsDashboard::getLogUrlFromOutputContent(os, stdoutDataNodeId);
2168 
2169     const QFileInfo fileInfo(url);
2170     CHECK_SET_ERR(fileInfo.exists(), QString("File with URL '%1' doesn't exist").arg(url));
2171     CHECK_SET_ERR(fileInfo.size() >= nodeText.size(),
2172                   QString("File with URL '%1' size is less than node '%2' text")
2173                       .arg(url)
2174                       .arg(stdoutDataNodeId));
2175 
2176     const QString expectedFileNamePart = "stdout";
2177     CHECK_SET_ERR(fileInfo.fileName().contains(expectedFileNamePart),
2178                   QString("File name '%1' doesn't contain '%2'")
2179                       .arg(url)
2180                       .arg(expectedFileNamePart));
2181 
2182     QString fileData = GTFile::readAll(os, url).replace("\n", "<br/>").replace("\r", "");
2183     CHECK_SET_ERR(fileData.startsWith(nodeText.left(500)),
2184                   QString("File '%1' content is not equal to the expected text: '%2', file: '%3'")
2185                       .arg(url)
2186                       .arg(nodeText.left(500))
2187                       .arg(fileData.left(500)));
2188 }
2189 
GUI_TEST_CLASS_DEFINITION(tool_launch_nodes_test_0016)2190 GUI_TEST_CLASS_DEFINITION(tool_launch_nodes_test_0016) {
2191     GTUtilsDialog::waitForDialogWhichMayRunOrNot(os, new StartupDialogFiller(os));
2192 
2193     //    1. Set the "_common_data/workflow/dashboard/fake_tools/fake_spades_stderr_only.py" as "SPAdes" external tool in the "Application Settings".
2194     const QString spadesToolName = "SPAdes";
2195     const QString spadesToolPath = QDir::toNativeSeparators(QFileInfo(testDir + "_common_data/workflow/dashboard/fake_tools/fake_spades_stderr_only.py").absoluteFilePath());
2196     GTUtilsExternalTools::setToolUrl(os, spadesToolName, spadesToolPath);
2197     GTUtilsTaskTreeView::waitTaskFinished(os);
2198 
2199     //    2. Open "_common_data/workflow/dashboard/spades.uwl".
2200     GTFileDialog::openFile(os, testDir + "_common_data/workflow/dashboard/spades.uwl");
2201     GTUtilsTaskTreeView::waitTaskFinished(os);
2202 
2203     //    3. Click "Read File URL(s)" element.
2204     GTUtilsWorkflowDesigner::click(os, "Read File URL(s)");
2205 
2206     //    4. Add "data/samples/FASTQ/eas.fastq" file to "Dataset 1" dataset.
2207     GTUtilsWorkflowDesigner::setDatasetInputFile(os, dataDir + "samples/FASTQ/eas.fastq", true);
2208 
2209     //    5. Launch the workflow.
2210     GTUtilsWorkflowDesigner::runWorkflow(os);
2211 
2212     //    6. Wait the workflow execution finish.
2213     GTUtilsTaskTreeView::waitTaskFinished(os);
2214 
2215     //    7. Switch to an "External Tools" tab.
2216     GTUtilsDashboard::openTab(os, GTUtilsDashboard::ExternalTools);
2217 
2218     //    8. Expand the third-level node "SPAdes run".
2219     const QString spadesRunNodeId = GTUtilsDashboard::getDescendantNodeId(os, GTUtilsDashboard::TREE_ROOT_ID, {0, 0, 0});
2220     GTUtilsDashboard::expandNode(os, spadesRunNodeId);
2221 
2222     //    Expected result:
2223     //        the third-level node "SPAdes run" has child node "Output log (stderr)".
2224     const QString stderrTitleNodeId = GTUtilsDashboard::getChildNodeId(os, spadesRunNodeId, 1);
2225 
2226     QString nodeText = GTUtilsDashboard::getNodeText(os, stderrTitleNodeId);
2227     QString expectedNodeText = "Output log (stderr)";
2228     CHECK_SET_ERR(expectedNodeText == nodeText,
2229                   QString("Node with ID '%1' has unexpected text: expected '%2', got '%3'")
2230                       .arg(stderrTitleNodeId)
2231                       .arg(expectedNodeText)
2232                       .arg(nodeText));
2233 
2234     const QString stderrDataNodeId = GTUtilsDashboard::getChildNodeId(os, stderrTitleNodeId, 0);
2235 
2236     //        the "Output log (stderr)" node content has significant size (~100 kb of text).
2237     nodeText = GTUtilsDashboard::getNodeText(os, stderrDataNodeId);
2238     int expectedLength = 80000;
2239     CHECK_SET_ERR(nodeText.size() > expectedLength,
2240                   QString("Node with ID '%1' text is not long enough: expected length is at least %2, actual text length is %3")
2241                       .arg(stderrDataNodeId)
2242                       .arg(expectedLength)
2243                       .arg(nodeText.size()));
2244 
2245     //        the "Output log (stderr)" node content ends with the following message: "The external tool output is too large and can't be visualized on the dashboard. Find full output in this file", where "this file" is a link to the log file.
2246     const QString expectedNodeTextPart = "The external tool output is too large and can't be visualized on the dashboard.";
2247     CHECK_SET_ERR(nodeText.contains(expectedNodeTextPart),
2248                   QString("Node with ID '%1' text doesn't ends with the expected part: expected part '%2', last 300 symbols of the text '%3'")
2249                       .arg(stderrDataNodeId)
2250                       .arg(expectedNodeTextPart)
2251                       .arg(nodeText.right(300)));
2252 
2253     //        the link from the previous item is correct: it points to a file with the same data; the file size is not less than the node contents size; the file name contains "stderr".
2254     const QString url = GTUtilsDashboard::getLogUrlFromOutputContent(os, stderrDataNodeId);
2255 
2256     const QFileInfo fileInfo(url);
2257     CHECK_SET_ERR(fileInfo.exists(), QString("File with URL '%1' doesn't exist").arg(url));
2258     CHECK_SET_ERR(fileInfo.size() >= nodeText.size(),
2259                   QString("File with URL '%1' size is less than node '%2' text")
2260                       .arg(url)
2261                       .arg(stderrDataNodeId));
2262 
2263     const QString expectedFileNamePart = "stderr";
2264     CHECK_SET_ERR(fileInfo.fileName().contains(expectedFileNamePart),
2265                   QString("File name '%1' doesn't contain '%2'")
2266                       .arg(url)
2267                       .arg(expectedFileNamePart));
2268 
2269     QString fileData = GTFile::readAll(os, url).replace("\n", "<br/>").replace("\r", "");
2270     ;
2271     CHECK_SET_ERR(fileData.startsWith(nodeText.left(500)),
2272                   QString("File '%1' content is not equal to the expected text: '%2', file: '%3'")
2273                       .arg(url)
2274                       .arg(nodeText.left(500))
2275                       .arg(fileData.left(500)));
2276 }
2277 
GUI_TEST_CLASS_DEFINITION(tool_launch_nodes_test_0017)2278 GUI_TEST_CLASS_DEFINITION(tool_launch_nodes_test_0017) {
2279     GTUtilsDialog::waitForDialog(os, new StartupDialogFiller(os));
2280 
2281     //    1. Set the "_common_data/workflow/dashboard/fake_tools/fake_spades_stdout_and_stderr.py" as "SPAdes" external tool in the "Application Settings".
2282     const QString spadesToolName = "SPAdes";
2283     const QString spadesToolPath = QDir::toNativeSeparators(QFileInfo(testDir + "_common_data/workflow/dashboard/fake_tools/fake_spades_stdout_and_stderr.py").absoluteFilePath());
2284     GTUtilsExternalTools::setToolUrl(os, spadesToolName, spadesToolPath);
2285     GTUtilsTaskTreeView::waitTaskFinished(os);
2286 
2287     //    2. Open "_common_data/workflow/dashboard/spades.uwl".
2288     GTFileDialog::openFile(os, testDir + "_common_data/workflow/dashboard/spades.uwl");
2289     GTUtilsTaskTreeView::waitTaskFinished(os);
2290 
2291     //    3. Click "Read File URL(s)" element.
2292     GTUtilsWorkflowDesigner::click(os, "Read File URL(s)");
2293 
2294     //    4. Add "data/samples/FASTQ/eas.fastq" file to "Dataset 1" dataset.
2295     GTUtilsWorkflowDesigner::setDatasetInputFile(os, dataDir + "samples/FASTQ/eas.fastq", true);
2296 
2297     //    5. Launch the workflow.
2298     GTUtilsWorkflowDesigner::runWorkflow(os);
2299 
2300     //    6. Wait the workflow execution finish.
2301     GTUtilsTaskTreeView::waitTaskFinished(os);
2302 
2303     //    7. Switch to an "External Tools" tab.
2304     GTUtilsDashboard::openTab(os, GTUtilsDashboard::ExternalTools);
2305 
2306     //    8. Expand the third-level node "SPAdes run".
2307     const QString spadesRunNodeId = GTUtilsDashboard::getDescendantNodeId(os, GTUtilsDashboard::TREE_ROOT_ID, {0, 0, 0});
2308     GTUtilsDashboard::expandNode(os, spadesRunNodeId);
2309 
2310     //    Expected result:
2311     //        the third-level node "SPAdes run" has child nodes "Output log (stdout)" and "Output log (stderr)".
2312     const QString oneOutNodeId = GTUtilsDashboard::getChildNodeId(os, spadesRunNodeId, 1);
2313     const QString anotherOutNodeId = GTUtilsDashboard::getChildNodeId(os, spadesRunNodeId, 2);
2314 
2315     QString stdoutTitleNodeId;
2316     QString stderrTitleNodeId;
2317     if (oneOutNodeId.contains("stderr")) {
2318         stdoutTitleNodeId = anotherOutNodeId;
2319         stderrTitleNodeId = oneOutNodeId;
2320     } else {
2321         stdoutTitleNodeId = oneOutNodeId;
2322         stderrTitleNodeId = anotherOutNodeId;
2323     }
2324 
2325     QString nodeText = GTUtilsDashboard::getNodeText(os, stderrTitleNodeId);
2326     QString expectedNodeText = "Output log (stderr)";
2327     CHECK_SET_ERR(expectedNodeText == nodeText,
2328                   QString("Node with ID '%1' has unexpected text: expected '%2', got '%3'")
2329                       .arg(stderrTitleNodeId)
2330                       .arg(expectedNodeText)
2331                       .arg(nodeText));
2332 
2333     nodeText = GTUtilsDashboard::getNodeText(os, stdoutTitleNodeId);
2334     expectedNodeText = "Output log (stdout)";
2335     CHECK_SET_ERR(expectedNodeText == nodeText,
2336                   QString("Node with ID '%1' has unexpected text: expected '%2', got '%3'")
2337                       .arg(stdoutTitleNodeId)
2338                       .arg(expectedNodeText)
2339                       .arg(nodeText));
2340 
2341     const QString stdoutDataNodeId = GTUtilsDashboard::getChildNodeId(os, stdoutTitleNodeId, 0);
2342     const QString stderrDataNodeId = GTUtilsDashboard::getChildNodeId(os, stderrTitleNodeId, 0);
2343 
2344     //        both "Output log (stdout)" and "Output log (stderr)" nodes contents have significant size (~100 kb of text).
2345     QString stdoutNodeText = GTUtilsDashboard::getNodeText(os, stdoutDataNodeId);
2346     int expectedLength = 80000;
2347     CHECK_SET_ERR(stdoutNodeText.size() > expectedLength,
2348                   QString("Node with ID '%1' text is not long enough: expected length is at least %2, actual text length is %3")
2349                       .arg(stdoutDataNodeId)
2350                       .arg(expectedLength)
2351                       .arg(stdoutNodeText.size()));
2352 
2353     QString stderrNodeText = GTUtilsDashboard::getNodeText(os, stderrDataNodeId);
2354     expectedLength = 80000;
2355     CHECK_SET_ERR(stderrNodeText.size() > expectedLength,
2356                   QString("Node with ID '%1' text is not long enough: expected length is at least %2, actual text length is %3")
2357                       .arg(stderrDataNodeId)
2358                       .arg(expectedLength)
2359                       .arg(stderrNodeText.size()));
2360 
2361     //        both "Output log (stdout)" and "Output log (stderr)" nodes contents ends with the following message: "The external tool output is too large and can't be visualized on the dashboard. Find full output in  %logUrl% this file", where %logUrl% is a link to log file.
2362     const QString expectedNodeTextPart = "The external tool output is too large and can't be visualized on the dashboard.";
2363     CHECK_SET_ERR(stdoutNodeText.contains(expectedNodeTextPart),
2364                   QString("Node with ID '%1' text doesn't ends with the expected part: expected part '%2', last 300 symbols of the text '%3'")
2365                       .arg(stderrDataNodeId)
2366                       .arg(expectedNodeTextPart)
2367                       .arg(stdoutNodeText.right(300)));
2368 
2369     CHECK_SET_ERR(stderrNodeText.contains(expectedNodeTextPart),
2370                   QString("Node with ID '%1' text doesn't ends with the expected part: expected part '%2', last 300 symbols of the text '%3'")
2371                       .arg(stderrDataNodeId)
2372                       .arg(expectedNodeTextPart)
2373                       .arg(stderrNodeText.right(300)));
2374 
2375     //        the links from the previous item are correct: they point to files with the same data as in nodes; the file sizes are not less than the appropriate nodes contents size; the appropriate files names contain "stdout" and "stderr".
2376     const QString stdoutLogUrl = GTUtilsDashboard::getLogUrlFromOutputContent(os, stdoutDataNodeId);
2377 
2378     const QFileInfo stdoutFileInfo(stdoutLogUrl);
2379     CHECK_SET_ERR(stdoutFileInfo.exists(), QString("File with URL '%1' doesn't exist").arg(stdoutLogUrl));
2380     CHECK_SET_ERR(stdoutFileInfo.size() >= stdoutNodeText.size(),
2381                   QString("File with URL '%1' size is less than node '%2' text")
2382                       .arg(stdoutLogUrl)
2383                       .arg(stdoutDataNodeId));
2384 
2385     QString expectedFileNamePart = "stdout";
2386     CHECK_SET_ERR(stdoutFileInfo.fileName().contains(expectedFileNamePart),
2387                   QString("File name '%1' doesn't contain '%2'")
2388                       .arg(stdoutLogUrl)
2389                       .arg(expectedFileNamePart));
2390 
2391     QString fileData = GTFile::readAll(os, stdoutLogUrl).replace("\n", "<br/>").replace("\r", "");
2392     CHECK_SET_ERR(fileData.startsWith(stdoutNodeText.left(500)),
2393                   QString("File '%1' content is not equal to the expected text: '%2', file: '%3'")
2394                       .arg(stdoutLogUrl)
2395                       .arg(stdoutNodeText.left(500))
2396                       .arg(fileData.left(500)));
2397 
2398     const QString stderrLogUrl = GTUtilsDashboard::getLogUrlFromOutputContent(os, stderrDataNodeId);
2399     const QFileInfo stderrFileInfo(stderrLogUrl);
2400     CHECK_SET_ERR(stderrFileInfo.exists(), QString("File with URL '%1' doesn't exist").arg(stderrLogUrl));
2401     CHECK_SET_ERR(stderrFileInfo.size() >= stderrNodeText.size(),
2402                   QString("File with URL '%1' size is less than node '%2' text")
2403                       .arg(stderrLogUrl)
2404                       .arg(stderrDataNodeId));
2405 
2406     expectedFileNamePart = "stderr";
2407     CHECK_SET_ERR(stderrFileInfo.fileName().contains(expectedFileNamePart),
2408                   QString("File name '%1' doesn't contain '%2'")
2409                       .arg(stderrLogUrl)
2410                       .arg(expectedFileNamePart));
2411 
2412     fileData = GTFile::readAll(os, stderrLogUrl).replace("\n", "<br/>").replace("\r", "");
2413     ;
2414     CHECK_SET_ERR(fileData.startsWith(stderrNodeText.left(500)),
2415                   QString("File '%1' content is not equal to the expected text: '%2', file: '%3'")
2416                       .arg(stderrLogUrl)
2417                       .arg(stderrNodeText.left(500))
2418                       .arg(fileData.left(500)));
2419 }
2420 
GUI_TEST_CLASS_DEFINITION(view_opening_test_0001)2421 GUI_TEST_CLASS_DEFINITION(view_opening_test_0001) {
2422     //    1. Set "_common_data/workflow/dashboard/workflow_outputs/empty_workflow_output" as workflow output folder in the "Application Settings".
2423     const QFileInfo originalWorkflowOutputDir = testDir + "_common_data/workflow/dashboard/workflow_outputs/empty_workflow_output";
2424     const QFileInfo testWorkflowOutputDir = sandBoxDir + "empty_workflow_output";
2425     GTFile::copyDir(os, originalWorkflowOutputDir.absoluteFilePath(), testWorkflowOutputDir.absoluteFilePath());
2426     setWorkflowOutputDir(os, testWorkflowOutputDir.absoluteFilePath());
2427 
2428     //    2. Wait for scan task finish.
2429     GTUtilsTaskTreeView::waitTaskFinished(os);
2430 
2431     //    3. Open Workflow Designer.
2432     GTUtilsWorkflowDesigner::openWorkflowDesigner(os);
2433 
2434     //    Expected result:
2435     //        - "Dashboards manager" button on the toolbar is active.
2436     //        - There is no "Go to Dashboard" button on the toolbar.
2437     QWidget *dashboardsManagerButton = GTToolbar::getWidgetForActionTooltip(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Dashboards manager");
2438     CHECK_SET_ERR(nullptr != dashboardsManagerButton, "'Dashboards manager' is nullptr");
2439     CHECK_SET_ERR(dashboardsManagerButton->isEnabled(), "'Dashboards manager' button is unexpectedly disabled");
2440 
2441     QWidget *viewSwitchButton = GTToolbar::getWidgetForActionTooltip(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Show dashboard");
2442     CHECK_SET_ERR(nullptr != viewSwitchButton, "'Go to Dashboards' is nullptr");
2443     CHECK_SET_ERR(!viewSwitchButton->isVisible(), "'Go to Dashboards' button is unexpectedly invisible");
2444 
2445     //    4. Click to the "Dashboards manager" button on the toolbar.
2446     //    5. Expected result: a messagebox appears. It contains the following text: "You do not have any dashboards yet. You need to run some workflow to use Dashboards Manager."
2447     //    6. Close the messagebox.
2448     GTUtilsDialog::waitForDialog(os, new MessageBoxDialogFiller(os, "OK", "You do not have any dashboards yet. You need to run some workflow to use Dashboards Manager."));
2449     GTWidget::click(os, dashboardsManagerButton);
2450 }
2451 
GUI_TEST_CLASS_DEFINITION(view_opening_test_0002)2452 GUI_TEST_CLASS_DEFINITION(view_opening_test_0002) {
2453     //    1. Set "_common_data/workflow/dashboard/workflow_outputs/two_visible_dashboards" as workflow output folder in the "Application Settings".
2454     const QFileInfo originalWorkflowOutputDir = testDir + "_common_data/workflow/dashboard/workflow_outputs/two_visible_dashboards";
2455     const QFileInfo testWorkflowOutputDir = sandBoxDir + "two_visible_dashboards";
2456     GTFile::copyDir(os, originalWorkflowOutputDir.absoluteFilePath(), testWorkflowOutputDir.absoluteFilePath());
2457     setWorkflowOutputDir(os, testWorkflowOutputDir.absoluteFilePath());
2458 
2459     //    2. Wait for scan task finish.
2460     GTUtilsTaskTreeView::waitTaskFinished(os);
2461 
2462     //    3. Open Workflow Designer.
2463     GTUtilsWorkflowDesigner::openWorkflowDesigner(os);
2464 
2465     //    Expected result:
2466     //        - "Dashboards manager" button on the toolbar is active.
2467     //        - There is "Go to Dashboard" button on the toolbar. The button text is exactly as written.
2468     QWidget *dashboardsManagerButton = GTToolbar::getWidgetForActionTooltip(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Dashboards manager");
2469     CHECK_SET_ERR(dashboardsManagerButton != nullptr, "'Dashboards manager' is nullptr");
2470     CHECK_SET_ERR(dashboardsManagerButton->isEnabled(), "'Dashboards manager' button is unexpectedly disabled");
2471 
2472     QAbstractButton *viewSwitchButton = qobject_cast<QAbstractButton *>(GTToolbar::getWidgetForActionTooltip(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Show dashboard"));
2473     CHECK_SET_ERR(viewSwitchButton != nullptr, "'Go to Dashboards' is nullptr");
2474     CHECK_SET_ERR(viewSwitchButton->isVisible(), "View switch button is unexpectedly invisible");
2475     CHECK_SET_ERR(viewSwitchButton->isEnabled(), "View switch button is unexpectedly disabled");
2476 
2477     QString expectedButtonText = "Go to Dashboard";
2478     QString actualButtonText = viewSwitchButton->text();
2479     CHECK_SET_ERR(expectedButtonText == actualButtonText,
2480                   QString("View switch button has an unexpected text: expected '%1', got '%2'")
2481                       .arg(expectedButtonText)
2482                       .arg(actualButtonText));
2483 
2484     //    4. Click to the "Dashboards manager" button on the toolbar.
2485     //    Expected result: the "Dashboards Manager" dialog appears. It contains two items, both of them are checked. Their names are "Extract consensus as sequence 1" and "Extract consensus as sequence 2".
2486     //    5. Cancel the dialog.
2487     class Scenario : public CustomScenario {
2488     public:
2489         void run(HI::GUITestOpStatus &os) override {
2490             QWidget *dialog = GTWidget::getActiveModalWidget(os);
2491             const QList<QPair<QString, bool>> expectedDashboardsState({qMakePair(QString("Extract consensus as sequence 1"), true),
2492                                                                        qMakePair(QString("Extract consensus as sequence 2"), true)});
2493             const QList<QPair<QString, bool>> actualDashboardsState = DashboardsManagerDialogFiller::getDashboardsState(os);
2494 
2495             CHECK_SET_ERR(expectedDashboardsState.size() == actualDashboardsState.size(),
2496                           QString("Expected dashboards count is not equal to the actual dashboards list size: expected %1, got %2")
2497                               .arg(expectedDashboardsState.size())
2498                               .arg(actualDashboardsState.size()));
2499 
2500             for (int i = 0; i < expectedDashboardsState.size(); ++i) {
2501                 const QString expectedDashboardName = expectedDashboardsState[i].first;
2502                 const QString actualDashboardName = actualDashboardsState[i].first;
2503                 CHECK_SET_ERR(expectedDashboardName == actualDashboardName,
2504                               QString("Dashboard number %1 has an unexpected name: expected '%2', got '%3'")
2505                                   .arg(i)
2506                                   .arg(expectedDashboardName)
2507                                   .arg(actualDashboardName));
2508 
2509                 const bool expectedDashboardState = expectedDashboardsState[i].second;
2510                 const bool actualDashboardState = actualDashboardsState[i].second;
2511                 CHECK_SET_ERR(expectedDashboardState == actualDashboardState,
2512                               QString("Dashboard number %1 has an unexpected state: it should be %2, but it is '%3'")
2513                                   .arg(i)
2514                                   .arg(expectedDashboardState ? "visible" : "invisible")
2515                                   .arg(actualDashboardState ? "visible" : "invisible"));
2516             }
2517 
2518             GTUtilsDialog::clickButtonBox(os, dialog, QDialogButtonBox::Cancel);
2519         }
2520     };
2521 
2522     GTUtilsDialog::waitForDialog(os, new DashboardsManagerDialogFiller(os, new Scenario()));
2523     GTWidget::click(os, dashboardsManagerButton);
2524 
2525     //    6. Click to the "Go to Dashboards" button on the toolbar.
2526     GTWidget::click(os, viewSwitchButton);
2527 
2528     //    Expected result:
2529     //        - There is "To Workflow Designer" button on the toolbar. The button text is exactly as written.
2530     //        - There are two tabs with dashboards. Their names are "Extract consensus as sequence 1" and "Extract consensus as sequence 2".
2531     //        - The "Extract consensus as sequence 2" dashboard is active.
2532     //        - The dashboard is correctly displayed.
2533     CHECK_SET_ERR(viewSwitchButton->isVisible(), "View switch button is unexpectedly invisible");
2534     CHECK_SET_ERR(viewSwitchButton->isEnabled(), "View switch button is unexpectedly disabled");
2535 
2536     expectedButtonText = "To Workflow Designer";
2537     actualButtonText = viewSwitchButton->text();
2538     CHECK_SET_ERR(expectedButtonText == actualButtonText,
2539                   QString("View switch button has an unexpected text: expected '%1', got '%2'")
2540                       .arg(expectedButtonText)
2541                       .arg(actualButtonText));
2542 
2543     QTabWidget *dashboardsView = GTUtilsDashboard::getTabWidget(os);
2544     CHECK_SET_ERR(dashboardsView != nullptr, "Dashboards view is nullptr");
2545 
2546     int expectedTabsCount = 2;
2547     int actualTabsCount = dashboardsView->count();
2548     CHECK_SET_ERR(expectedTabsCount == actualTabsCount,
2549                   QString("There is an incorrect count of tabs in the Dashboard View: expected %1, got %2")
2550                       .arg(expectedTabsCount)
2551                       .arg(actualTabsCount));
2552 
2553     int expectedActiveTabIndex = 1;
2554     int actualActiveTabIndex = dashboardsView->currentIndex();
2555     CHECK_SET_ERR(expectedActiveTabIndex == actualActiveTabIndex,
2556                   QString("There is an incorrect active tab: expected index is %1, actual index is %2")
2557                       .arg(expectedActiveTabIndex)
2558                       .arg(actualActiveTabIndex));
2559 
2560     QString expectedTabName = "Extract consensus as sequence 2";
2561     QString actualTabName = GTUtilsDashboard::getDashboardName(os, expectedActiveTabIndex);
2562     CHECK_SET_ERR(expectedTabName == actualTabName,
2563                   QString("Active dashboard has an unexpected name: expect '%1', got '%2'")
2564                       .arg(expectedTabName)
2565                       .arg(actualTabName));
2566 
2567     QStringList outputFiles = GTUtilsDashboard::getOutputFiles(os);
2568     CHECK_SET_ERR(!outputFiles.isEmpty(), "Active dashboard is not displayed properly");
2569 
2570     //    7. Click to the "To Workflow Designer" button on the toolbar.
2571     GTWidget::click(os, viewSwitchButton);
2572 
2573     //    Expected result: there is "Go to Dashboard" button on the toolbar. The button text is exactly as written.
2574     CHECK_SET_ERR(viewSwitchButton->isVisible(), "View switch button is unexpectedly invisible");
2575     CHECK_SET_ERR(viewSwitchButton->isEnabled(), "View switch button is unexpectedly disabled");
2576 
2577     expectedButtonText = "Go to Dashboard";
2578     actualButtonText = viewSwitchButton->text();
2579     CHECK_SET_ERR(expectedButtonText == actualButtonText,
2580                   QString("View switch button has an unexpected text: expected '%1', got '%2'")
2581                       .arg(expectedButtonText)
2582                       .arg(actualButtonText));
2583 }
2584 
GUI_TEST_CLASS_DEFINITION(view_opening_test_0003)2585 GUI_TEST_CLASS_DEFINITION(view_opening_test_0003) {
2586     //    1. Set "_common_data/workflow/dashboard/workflow_outputs/one_visible_one_invisible" as workflow output folder in the "Application Settings".
2587     const QFileInfo originalWorkflowOutputDir = testDir + "_common_data/workflow/dashboard/workflow_outputs/one_visible_one_invisible";
2588     const QFileInfo testWorkflowOutputDir = sandBoxDir + "one_visible_one_invisible";
2589     GTFile::copyDir(os, originalWorkflowOutputDir.absoluteFilePath(), testWorkflowOutputDir.absoluteFilePath());
2590     setWorkflowOutputDir(os, testWorkflowOutputDir.absoluteFilePath());
2591 
2592     //    2. Wait for scan task finish.
2593     GTUtilsTaskTreeView::waitTaskFinished(os);
2594 
2595     //    3. Open Workflow Designer.
2596     GTUtilsWorkflowDesigner::openWorkflowDesigner(os);
2597 
2598     //    Expected result:
2599     //        - "Dashboards manager" button on the toolbar is active.
2600     //        - There is "Go to Dashboard" button on the toolbar. The button text is exactly as written.
2601     QWidget *dashboardsManagerButton = GTToolbar::getWidgetForActionTooltip(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Dashboards manager");
2602     CHECK_SET_ERR(nullptr != dashboardsManagerButton, "'Dashboards manager' is nullptr");
2603     CHECK_SET_ERR(dashboardsManagerButton->isEnabled(), "'Dashboards manager' button is unexpectedly disabled");
2604 
2605     QAbstractButton *viewSwitchButton = qobject_cast<QAbstractButton *>(GTToolbar::getWidgetForActionTooltip(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Show dashboard"));
2606     CHECK_SET_ERR(nullptr != viewSwitchButton, "'Go to Dashboards' is nullptr");
2607     CHECK_SET_ERR(viewSwitchButton->isVisible(), "View switch button is unexpectedly invisible");
2608     CHECK_SET_ERR(viewSwitchButton->isEnabled(), "View switch button is unexpectedly disabled");
2609 
2610     QString expectedButtonText = "Go to Dashboard";
2611     QString actualButtonText = viewSwitchButton->text();
2612     CHECK_SET_ERR(expectedButtonText == actualButtonText,
2613                   QString("View switch button has an unexpected text: expected '%1', got '%2'")
2614                       .arg(expectedButtonText)
2615                       .arg(actualButtonText));
2616 
2617     //    4. Click to the "Dashboards manager" button on the toolbar.
2618     //    Expected result: the "Dashboards Manager" dialog appears. It contains two items, the first one is unchecked, the second one is checked. Their names are "Extract consensus as sequence 1" and "Extract consensus as sequence 2".
2619     //    5. Cancel the dialog.
2620     class Scenario : public CustomScenario {
2621     public:
2622         void run(HI::GUITestOpStatus &os) override {
2623             QWidget *dialog = GTWidget::getActiveModalWidget(os);
2624             const QList<QPair<QString, bool>> expectedDashboardsState({qMakePair(QString("Extract consensus as sequence 1"), false),
2625                                                                        qMakePair(QString("Extract consensus as sequence 2"), true)});
2626             const QList<QPair<QString, bool>> actualDashboardsState = DashboardsManagerDialogFiller::getDashboardsState(os);
2627 
2628             CHECK_SET_ERR(expectedDashboardsState.size() == actualDashboardsState.size(),
2629                           QString("Expected dashboards count is not equal to the actual dashboards list size: expected %1, got %2")
2630                               .arg(expectedDashboardsState.size())
2631                               .arg(actualDashboardsState.size()));
2632 
2633             for (int i = 0; i < expectedDashboardsState.size(); ++i) {
2634                 const QString expectedDashboardName = expectedDashboardsState[i].first;
2635                 const QString actualDashboardName = actualDashboardsState[i].first;
2636                 CHECK_SET_ERR(expectedDashboardName == actualDashboardName,
2637                               QString("Dashboard number %1 has an unexpected name: expected '%2', got '%3'")
2638                                   .arg(i)
2639                                   .arg(expectedDashboardName)
2640                                   .arg(actualDashboardName));
2641 
2642                 const bool expectedDashboardState = expectedDashboardsState[i].second;
2643                 const bool actualDashboardState = actualDashboardsState[i].second;
2644                 CHECK_SET_ERR(expectedDashboardState == actualDashboardState,
2645                               QString("Dashboard number %1 has an unexpected state: it should be %2, but it is '%3'")
2646                                   .arg(i)
2647                                   .arg(expectedDashboardState ? "visible" : "invisible")
2648                                   .arg(actualDashboardState ? "visible" : "invisible"));
2649             }
2650 
2651             GTUtilsDialog::clickButtonBox(os, dialog, QDialogButtonBox::Cancel);
2652         }
2653     };
2654 
2655     GTUtilsDialog::waitForDialog(os, new DashboardsManagerDialogFiller(os, new Scenario()));
2656     GTWidget::click(os, dashboardsManagerButton);
2657 
2658     //    6. Click to the "Go to Dashboards" button on the toolbar.
2659     GTWidget::click(os, viewSwitchButton);
2660 
2661     //    Expected result:
2662     //        - There is "To Workflow Designer" button on the toolbar. The button text is exactly as written.
2663     //        - There is one tab with dashboard. Its name is "Extract consensus as sequence 2".
2664     //        - The "Extract consensus as sequence 2" dashboard is active.
2665     //        - The dashboard is correctly displayed.
2666     CHECK_SET_ERR(viewSwitchButton->isVisible(), "View switch button is unexpectedly invisible");
2667     CHECK_SET_ERR(viewSwitchButton->isEnabled(), "View switch button is unexpectedly disabled");
2668 
2669     expectedButtonText = "To Workflow Designer";
2670     actualButtonText = viewSwitchButton->text();
2671     CHECK_SET_ERR(expectedButtonText == actualButtonText,
2672                   QString("View switch button has an unexpected text: expected '%1', got '%2'")
2673                       .arg(expectedButtonText)
2674                       .arg(actualButtonText));
2675 
2676     QTabWidget *dashboardsView = GTUtilsDashboard::getTabWidget(os);
2677     CHECK_SET_ERR(dashboardsView != nullptr, "Dashboards view is nullptr");
2678 
2679     int expectedTabsCount = 1;
2680     int actualTabsCount = dashboardsView->count();
2681     CHECK_SET_ERR(expectedTabsCount == actualTabsCount,
2682                   QString("There is an incorrect count of tabs in the Dashboard View: expected %1, got %2")
2683                       .arg(expectedTabsCount)
2684                       .arg(actualTabsCount));
2685 
2686     int expectedActiveTabIndex = 0;
2687     int actualActiveTabIndex = dashboardsView->currentIndex();
2688     CHECK_SET_ERR(expectedActiveTabIndex == actualActiveTabIndex,
2689                   QString("There is an incorrect active tab: expected index is %1, actual index is %2")
2690                       .arg(expectedActiveTabIndex)
2691                       .arg(actualActiveTabIndex));
2692 
2693     QString expectedTabName = "Extract consensus as sequence 2";
2694     QString actualTabName = GTUtilsDashboard::getDashboardName(os, expectedActiveTabIndex);
2695     CHECK_SET_ERR(expectedTabName == actualTabName,
2696                   QString("Active dashboard has an unexpected name: expect '%1', got '%2'")
2697                       .arg(expectedTabName)
2698                       .arg(actualTabName));
2699 
2700     QStringList outputFiles = GTUtilsDashboard::getOutputFiles(os);
2701     CHECK_SET_ERR(!outputFiles.isEmpty(), "Active dashboard is not displayed properly");
2702 
2703     //    7. Click to the "To Workflow Designer" button on the toolbar.
2704     GTWidget::click(os, viewSwitchButton);
2705 
2706     //    Expected result: there is "Go to Dashboard" button on the toolbar. The button text is exactly as written.
2707     CHECK_SET_ERR(viewSwitchButton->isVisible(), "View switch button is unexpectedly invisible");
2708     CHECK_SET_ERR(viewSwitchButton->isEnabled(), "View switch button is unexpectedly disabled");
2709 
2710     expectedButtonText = "Go to Dashboard";
2711     actualButtonText = viewSwitchButton->text();
2712     CHECK_SET_ERR(expectedButtonText == actualButtonText,
2713                   QString("View switch button has an unexpected text: expected '%1', got '%2'")
2714                       .arg(expectedButtonText)
2715                       .arg(actualButtonText));
2716 }
2717 
GUI_TEST_CLASS_DEFINITION(view_opening_test_0004)2718 GUI_TEST_CLASS_DEFINITION(view_opening_test_0004) {
2719     //    1. Set "_common_data/workflow/dashboard/workflow_outputs/two_invisible_dashboards" as workflow output folder in the "Application Settings".
2720     const QFileInfo originalWorkflowOutputDir = testDir + "_common_data/workflow/dashboard/workflow_outputs/two_invisible_dashboards";
2721     const QFileInfo testWorkflowOutputDir = sandBoxDir + "two_invisible_dashboards";
2722     GTFile::copyDir(os, originalWorkflowOutputDir.absoluteFilePath(), testWorkflowOutputDir.absoluteFilePath());
2723     setWorkflowOutputDir(os, testWorkflowOutputDir.absoluteFilePath());
2724 
2725     //    2. Wait for scan task finish.
2726     GTUtilsTaskTreeView::waitTaskFinished(os);
2727 
2728     //    3. Open Workflow Designer.
2729     GTUtilsWorkflowDesigner::openWorkflowDesigner(os);
2730 
2731     //    Expected result:
2732     //        - "Dashboards manager" button on the toolbar is active.
2733     //        - There is no "Go to Dashboard" button on the toolbar.
2734     QWidget *dashboardsManagerButton = GTToolbar::getWidgetForActionTooltip(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Dashboards manager");
2735     CHECK_SET_ERR(nullptr != dashboardsManagerButton, "'Dashboards manager' is nullptr");
2736     CHECK_SET_ERR(dashboardsManagerButton->isEnabled(), "'Dashboards manager' button is unexpectedly disabled");
2737 
2738     QWidget *viewSwitchButton = GTToolbar::getWidgetForActionTooltip(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Show dashboard");
2739     CHECK_SET_ERR(nullptr != viewSwitchButton, "'Go to Dashboards' is nullptr");
2740     CHECK_SET_ERR(!viewSwitchButton->isVisible(), "'Go to Dashboards' button is unexpectedly invisible");
2741 
2742     //    4. Click to the "Dashboards manager" button on the toolbar.
2743     //    Expected result: the "Dashboards Manager" dialog appears. It contains two items, both of them are unchecked. Their names are "Extract consensus as sequence 1" and "Extract consensus as sequence 2".
2744     //    5. Cancel the dialog.
2745     class Scenario : public CustomScenario {
2746     public:
2747         void run(HI::GUITestOpStatus &os) override {
2748             QWidget *dialog = GTWidget::getActiveModalWidget(os);
2749             const QList<QPair<QString, bool>> expectedDashboardsState({qMakePair(QString("Extract consensus as sequence 1"), false),
2750                                                                        qMakePair(QString("Extract consensus as sequence 2"), false)});
2751             const QList<QPair<QString, bool>> actualDashboardsState = DashboardsManagerDialogFiller::getDashboardsState(os);
2752 
2753             CHECK_SET_ERR(expectedDashboardsState.size() == actualDashboardsState.size(),
2754                           QString("Expected dashboards count is not equal to the actual dashboards list size: expected %1, got %2")
2755                               .arg(expectedDashboardsState.size())
2756                               .arg(actualDashboardsState.size()));
2757 
2758             for (int i = 0; i < expectedDashboardsState.size(); ++i) {
2759                 const QString expectedDashboardName = expectedDashboardsState[i].first;
2760                 const QString actualDashboardName = actualDashboardsState[i].first;
2761                 CHECK_SET_ERR(expectedDashboardName == actualDashboardName,
2762                               QString("Dashboard number %1 has an unexpected name: expected '%2', got '%3'")
2763                                   .arg(i)
2764                                   .arg(expectedDashboardName)
2765                                   .arg(actualDashboardName));
2766 
2767                 const bool expectedDashboardState = expectedDashboardsState[i].second;
2768                 const bool actualDashboardState = actualDashboardsState[i].second;
2769                 CHECK_SET_ERR(expectedDashboardState == actualDashboardState,
2770                               QString("Dashboard number %1 has an unexpected state: it should be %2, but it is '%3'")
2771                                   .arg(i)
2772                                   .arg(expectedDashboardState ? "visible" : "invisible")
2773                                   .arg(actualDashboardState ? "visible" : "invisible"));
2774             }
2775 
2776             GTUtilsDialog::clickButtonBox(os, dialog, QDialogButtonBox::Cancel);
2777         }
2778     };
2779 
2780     GTUtilsDialog::waitForDialog(os, new DashboardsManagerDialogFiller(os, new Scenario()));
2781     GTWidget::click(os, dashboardsManagerButton);
2782 }
2783 
GUI_TEST_CLASS_DEFINITION(output_dir_scanning_test_0001)2784 GUI_TEST_CLASS_DEFINITION(output_dir_scanning_test_0001) {
2785     //    1. Set "_common_data/workflow/dashboard/workflow_outputs/two_visible_two_invisible" as workflow output folder in the "Application Settings".
2786     const QFileInfo originalWorkflowOutputDir = testDir + "_common_data/workflow/dashboard/workflow_outputs/two_visible_two_invisible";
2787     const QFileInfo testWorkflowOutputDir = sandBoxDir + "two_visible_two_invisible";
2788     GTFile::copyDir(os, originalWorkflowOutputDir.absoluteFilePath(), testWorkflowOutputDir.absoluteFilePath());
2789     setWorkflowOutputDir(os, testWorkflowOutputDir.absoluteFilePath());
2790 
2791     //    2. Wait for scan task finish.
2792     GTUtilsTaskTreeView::waitTaskFinished(os);
2793 
2794     //    3. Open Workflow Designer.
2795     GTUtilsWorkflowDesigner::openWorkflowDesigner(os);
2796     int tabIndex1 = GTUtilsMdi::getCurrentTab(os);
2797 
2798     //    4. Open Workflow Designer.
2799     GTUtilsWorkflowDesigner::openWorkflowDesigner(os);
2800 
2801     //    5. Click to the "Go to Dashboards" button on the toolbar.
2802     QAbstractButton *viewSwitchButton = qobject_cast<QAbstractButton *>(
2803         GTToolbar::getWidgetForActionTooltip(os,
2804                                              GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI),
2805                                              "Show dashboard"));
2806     CHECK_SET_ERR(nullptr != viewSwitchButton, "'Go to Dashboards' is nullptr");
2807     CHECK_SET_ERR(viewSwitchButton->isVisible(), "View switch button is unexpectedly invisible");
2808     CHECK_SET_ERR(viewSwitchButton->isEnabled(), "View switch button is unexpectedly disabled");
2809     GTWidget::click(os, viewSwitchButton);
2810 
2811     //    6. Set "_common_data/workflow/dashboard/workflow_outputs/empty_workflow_output" as workflow output folder in the "Application Settings".
2812     const QFileInfo originalWorkflowOutputDir2 = testDir + "_common_data/workflow/dashboard/workflow_outputs/empty_workflow_output";
2813     const QFileInfo testWorkflowOutputDir2 = sandBoxDir + "empty_workflow_output";
2814     GTFile::copyDir(os, originalWorkflowOutputDir2.absoluteFilePath(), testWorkflowOutputDir2.absoluteFilePath());
2815     setWorkflowOutputDir(os, testWorkflowOutputDir2.absoluteFilePath());
2816 
2817     //    7. Wait for scan task finish.
2818     GTUtilsTaskTreeView::waitTaskFinished(os);
2819 
2820     //    Expected result:
2821     //        - The Workflow Designer switches to the scene view mode.
2822     //        - There is no scene/dashboards switch button on the toolbar.
2823     //        - The "Dashboards manager" button on the toolbar is active.
2824     QWidget *dashboardsManagerButton = GTToolbar::getWidgetForActionTooltip(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Dashboards manager");
2825     CHECK_SET_ERR(nullptr != dashboardsManagerButton, "'Dashboards manager' is nullptr");
2826     CHECK_SET_ERR(dashboardsManagerButton->isEnabled(), "'Dashboards manager' button is unexpectedly disabled");
2827 
2828     QWidget *viewSwitchButton2 = GTToolbar::getWidgetForActionTooltip(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Show dashboard");
2829     CHECK_SET_ERR(nullptr == viewSwitchButton2 ||
2830                       !viewSwitchButton2->isVisible(),
2831                   "'Go to Dashboards' is visible");
2832 
2833     //    8. Click to the "Dashboards manager" button on the toolbar.
2834     //    Expected result: the "Dashboards Manager" dialog appears. It contains the following text: "You do not have any dashboards yet. You need to run some workflow to use Dashboards Manager."
2835     //    9. Close the messagebox.
2836     GTUtilsDialog::waitForDialog(os, new MessageBoxDialogFiller(os, "OK", "You do not have any dashboards yet. You need to run some workflow to use Dashboards Manager."));
2837     GTWidget::click(os, dashboardsManagerButton);
2838 
2839     //    10. Switch to another Workflow Designer.
2840     coreLog.info(QString("Try to switch to tab %1(%2)")
2841                      .arg(tabIndex1)
2842                      .arg(GTUtilsMdi::getTabBar(os)->tabText(tabIndex1)));
2843     GTUtilsMdi::clickTab(os, tabIndex1);
2844 
2845     //    Expected result:
2846     //      - The Workflow Designer is in the scene view mode.
2847     //      - There is no scene/dashboards switch button on the toolbar.
2848     //      - The "Dashboards manager" button on the toolbar is active.
2849     dashboardsManagerButton = GTToolbar::getWidgetForActionTooltip(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Dashboards manager");
2850     CHECK_SET_ERR(nullptr != dashboardsManagerButton, "'Dashboards manager' is nullptr");
2851     CHECK_SET_ERR(dashboardsManagerButton->isEnabled(), "'Dashboards manager' button is unexpectedly disabled");
2852 
2853     viewSwitchButton2 = GTToolbar::getWidgetForActionTooltip(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Show dashboard");
2854     CHECK_SET_ERR(nullptr == viewSwitchButton2 ||
2855                       !viewSwitchButton2->isVisible(),
2856                   "'Go to Dashboards' is visible");
2857 
2858     //    11. Click to the "Dashboards manager" button on the toolbar.
2859     //    Expected result: a messagebox appears. It contains the following text: "You do not have any dashboards yet. You need to run some workflow to use Dashboards Manager."
2860     //    12. Close the messagebox.
2861     GTUtilsDialog::waitForDialog(os, new MessageBoxDialogFiller(os, "OK", "You do not have any dashboards yet. You need to run some workflow to use Dashboards Manager."));
2862     GTWidget::click(os, dashboardsManagerButton);
2863 }
2864 
GUI_TEST_CLASS_DEFINITION(output_dir_scanning_test_0002)2865 GUI_TEST_CLASS_DEFINITION(output_dir_scanning_test_0002) {
2866     //    1. Set "_common_data/workflow/dashboard/workflow_outputs/two_visible_two_invisible" as workflow output folder in the "Application Settings".
2867     const QFileInfo originalWorkflowOutputDir = testDir + "_common_data/workflow/dashboard/workflow_outputs/two_visible_two_invisible";
2868     const QFileInfo testWorkflowOutputDir = sandBoxDir + "two_visible_two_invisible";
2869     GTFile::copyDir(os, originalWorkflowOutputDir.absoluteFilePath(), testWorkflowOutputDir.absoluteFilePath());
2870     setWorkflowOutputDir(os, testWorkflowOutputDir.absoluteFilePath());
2871 
2872     //    2. Wait for scan task finish.
2873     GTUtilsTaskTreeView::waitTaskFinished(os);
2874 
2875     //    3. Open Workflow Designer.
2876     GTUtilsWorkflowDesigner::openWorkflowDesigner(os);
2877     int tabIndex1 = GTUtilsMdi::getCurrentTab(os);
2878 
2879     //    4. Open Workflow Designer.
2880     GTUtilsWorkflowDesigner::openWorkflowDesigner(os);
2881 
2882     //    5. Click to the "Go to Dashboards" button on the toolbar.
2883     QAbstractButton *viewSwitchButton = qobject_cast<QAbstractButton *>(
2884         GTToolbar::getWidgetForActionTooltip(os,
2885                                              GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI),
2886                                              "Show dashboard"));
2887     CHECK_SET_ERR(nullptr != viewSwitchButton, "'Go to Dashboards' is nullptr");
2888     CHECK_SET_ERR(viewSwitchButton->isVisible(), "View switch button is unexpectedly invisible");
2889     CHECK_SET_ERR(viewSwitchButton->isEnabled(), "View switch button is unexpectedly disabled");
2890     GTWidget::click(os, viewSwitchButton);
2891 
2892     //    6. Set "_common_data/workflow/dashboard/workflow_outputs/two_visible_dashboards" as workflow output folder in the "Application Settings".
2893     const QFileInfo originalWorkflowOutputDir2 = testDir + "_common_data/workflow/dashboard/workflow_outputs/two_visible_dashboards";
2894     const QFileInfo testWorkflowOutputDir2 = sandBoxDir + "two_visible_dashboards";
2895     GTFile::copyDir(os, originalWorkflowOutputDir2.absoluteFilePath(), testWorkflowOutputDir2.absoluteFilePath());
2896     setWorkflowOutputDir(os, testWorkflowOutputDir2.absoluteFilePath());
2897 
2898     //    7. Wait for scan task finish.
2899     GTUtilsTaskTreeView::waitTaskFinished(os);
2900 
2901     //    Expected result:
2902     //    - The Workflow Designer is in the dashboards view mode.
2903     //    - There are two tabs with dashboards. Their names are "Extract consensus as sequence 1" and "Extract consensus as sequence 2".
2904     //    - The "Extract consensus as sequence 2" dashboard is active.
2905     //    - The dashboard is correctly displayed.
2906     //    - The "Dashboards manager" button on the toolbar is active.
2907     CHECK_SET_ERR(viewSwitchButton->isVisible(), "View switch button is unexpectedly invisible");
2908     CHECK_SET_ERR(viewSwitchButton->isEnabled(), "View switch button is unexpectedly disabled");
2909 
2910     QString expectedButtonText = "To Workflow Designer";
2911     QString actualButtonText = viewSwitchButton->text();
2912     CHECK_SET_ERR(expectedButtonText == actualButtonText,
2913                   QString("View switch button has an unexpected text: expected '%1', got '%2'")
2914                       .arg(expectedButtonText)
2915                       .arg(actualButtonText));
2916 
2917     coreLog.info("Trying get GTUtilsDashboard::getTabWidget(os)");
2918     QTabWidget *dashboardsView = GTUtilsDashboard::getTabWidget(os);
2919     CHECK_SET_ERR(nullptr != dashboardsView, "Dashboards view is nullptr");
2920     coreLog.info("Successfully got GTUtilsDashboard::getTabWidget(os)");
2921 
2922     const int expectedTabsCount = 2;
2923     const int actualTabsCount = dashboardsView->count();
2924     CHECK_SET_ERR(expectedTabsCount == actualTabsCount,
2925                   QString("There is an incorrect count of tabs in the Dashboard View: expected %1, got %2")
2926                       .arg(expectedTabsCount)
2927                       .arg(actualTabsCount));
2928 
2929     const int expectedActiveTabIndex = 1;
2930     const int actualActiveTabIndex = dashboardsView->currentIndex();
2931     CHECK_SET_ERR(expectedActiveTabIndex == actualActiveTabIndex,
2932                   QString("There is an incorrect active tab: expected index is %1, actual index is %2")
2933                       .arg(expectedActiveTabIndex)
2934                       .arg(actualActiveTabIndex));
2935 
2936     const QString expectedTabName = "Extract consensus as sequence 2";
2937     const QString actualTabName = GTUtilsDashboard::getDashboardName(os, expectedActiveTabIndex);
2938     CHECK_SET_ERR(expectedTabName == actualTabName,
2939                   QString("Active dashboard has an unexpected name: expect '%1', got '%2'")
2940                       .arg(expectedTabName)
2941                       .arg(actualTabName));
2942 
2943     const QStringList outputFiles = GTUtilsDashboard::getOutputFiles(os);
2944     CHECK_SET_ERR(!outputFiles.isEmpty(), "Active dashboard is not displayed properly");
2945 
2946     QWidget *dashboardsManagerButton = GTToolbar::getWidgetForActionTooltip(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Dashboards manager");
2947     CHECK_SET_ERR(nullptr != dashboardsManagerButton, "'Dashboards manager' is nullptr");
2948     CHECK_SET_ERR(dashboardsManagerButton->isEnabled(), "'Dashboards manager' button is unexpectedly disabled");
2949 
2950     //    8. Click to the "Dashboards manager" button on the toolbar.
2951     //    Expected result: the "Dashboards Manager" dialog appears. It contains two items, both of them are checked. Their names are "Extract consensus as sequence 1" and "Extract consensus as sequence 2".
2952     //    9. Close the messagebox.
2953     class Scenario : public CustomScenario {
2954     public:
2955         void run(HI::GUITestOpStatus &os) override {
2956             QWidget *dialog = GTWidget::getActiveModalWidget(os);
2957             const QList<QPair<QString, bool>> expectedDashboardsState({qMakePair(QString("Extract consensus as sequence 1"), true),
2958                                                                        qMakePair(QString("Extract consensus as sequence 2"), true)});
2959             const QList<QPair<QString, bool>> actualDashboardsState = DashboardsManagerDialogFiller::getDashboardsState(os);
2960 
2961             CHECK_SET_ERR(expectedDashboardsState.size() == actualDashboardsState.size(),
2962                           QString("Expected dashboards count is not equal to the actual dashboards list size: expected %1, got %2")
2963                               .arg(expectedDashboardsState.size())
2964                               .arg(actualDashboardsState.size()));
2965 
2966             for (int i = 0; i < expectedDashboardsState.size(); ++i) {
2967                 const QString expectedDashboardName = expectedDashboardsState[i].first;
2968                 const QString actualDashboardName = actualDashboardsState[i].first;
2969                 CHECK_SET_ERR(expectedDashboardName == actualDashboardName,
2970                               QString("Dashboard number %1 has an unexpected name: expected '%2', got '%3'")
2971                                   .arg(i)
2972                                   .arg(expectedDashboardName)
2973                                   .arg(actualDashboardName));
2974 
2975                 const bool expectedDashboardState = expectedDashboardsState[i].second;
2976                 const bool actualDashboardState = actualDashboardsState[i].second;
2977                 CHECK_SET_ERR(expectedDashboardState == actualDashboardState,
2978                               QString("Dashboard number %1 has an unexpected state: it should be %2, but it is '%3'")
2979                                   .arg(i)
2980                                   .arg(expectedDashboardState ? "visible" : "invisible")
2981                                   .arg(actualDashboardState ? "visible" : "invisible"));
2982             }
2983 
2984             GTUtilsDialog::clickButtonBox(os, dialog, QDialogButtonBox::Cancel);
2985         }
2986     };
2987 
2988     GTUtilsDialog::waitForDialog(os, new DashboardsManagerDialogFiller(os, new Scenario()));
2989     GTWidget::click(os, dashboardsManagerButton);
2990 
2991     //    10. Switch to another Workflow Designer.
2992     coreLog.info(QString("Try to switch to tab %1(%2)")
2993                      .arg(tabIndex1)
2994                      .arg(GTUtilsMdi::getTabBar(os)->tabText(tabIndex1)));
2995     GTUtilsMdi::clickTab(os, tabIndex1);
2996 
2997     //    Expected result:
2998     //      - The Workflow Designer is in the scene view mode.
2999     //      - The "Dashboards manager" button on the toolbar is active.
3000     dashboardsManagerButton = GTToolbar::getWidgetForActionTooltip(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Dashboards manager");
3001     CHECK_SET_ERR(nullptr != dashboardsManagerButton, "'Dashboards manager' is nullptr");
3002     CHECK_SET_ERR(dashboardsManagerButton->isEnabled(), "'Dashboards manager' button is unexpectedly disabled");
3003 
3004     QWidget *viewSwitchButton2 = GTToolbar::getWidgetForActionTooltip(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Show dashboard");
3005     CHECK_SET_ERR(nullptr != viewSwitchButton2 &&
3006                       viewSwitchButton2->isVisible(),
3007                   "'Go to Dashboards' is invisible");
3008 
3009     //    11. Click to the "Dashboards manager" button on the toolbar.
3010     //    12. Cancel the dialog
3011     //    Expected result:
3012     //    - There are two tabs with dashboards. Their names are "Extract consensus as sequence 1" and "Extract consensus as sequence 2".
3013     //    - The "Extract consensus as sequence 2" dashboard is active.
3014     //    - The dashboard is correctly displayed.
3015     GTUtilsDialog::waitForDialog(os, new DashboardsManagerDialogFiller(os, new Scenario()));
3016     GTWidget::click(os, dashboardsManagerButton);
3017 
3018     //    13. Click to the "Go to Dashboards" button on the toolbar.
3019     //    Expected result:
3020     //    - There are two tabs with dashboards. Their names are "Extract consensus as sequence 1" and "Extract consensus as sequence 2".
3021     //    - The "Extract consensus as sequence 2" dashboard is active.
3022     //    - The dashboard is correctly displayed.
3023     viewSwitchButton = qobject_cast<QAbstractButton *>(
3024         GTToolbar::getWidgetForActionTooltip(os,
3025                                              GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI),
3026                                              "Show dashboard"));
3027     CHECK_SET_ERR(nullptr != viewSwitchButton, "'Go to Dashboards' is nullptr");
3028     CHECK_SET_ERR(viewSwitchButton->isVisible(), "View switch button is unexpectedly invisible");
3029     CHECK_SET_ERR(viewSwitchButton->isEnabled(), "View switch button is unexpectedly disabled");
3030     GTWidget::click(os, viewSwitchButton);
3031 
3032     dashboardsView = GTUtilsDashboard::getTabWidget(os);
3033     CHECK_SET_ERR(nullptr != dashboardsView, "Dashboards view is nullptr");
3034 
3035     const int expectedTabsCount2 = 2;
3036     const int actualTabsCount2 = dashboardsView->count();
3037     CHECK_SET_ERR(expectedTabsCount2 == actualTabsCount2,
3038                   QString("There is an incorrect count of tabs in the Dashboard View: expected %1, got %2")
3039                       .arg(expectedTabsCount2)
3040                       .arg(actualTabsCount2));
3041 
3042     const int expectedActiveTabIndex2 = 1;
3043     const int actualActiveTabIndex2 = dashboardsView->currentIndex();
3044     CHECK_SET_ERR(expectedActiveTabIndex2 == actualActiveTabIndex2,
3045                   QString("There is an incorrect active tab: expected index is %1, actual index is %2")
3046                       .arg(expectedActiveTabIndex2)
3047                       .arg(actualActiveTabIndex2));
3048 
3049     const QString expectedTabName2 = "Extract consensus as sequence 2";
3050     const QString actualTabName2 = GTUtilsDashboard::getDashboardName(os, expectedActiveTabIndex2);
3051     CHECK_SET_ERR(expectedTabName2 == actualTabName2,
3052                   QString("Active dashboard has an unexpected name: expect '%1', got '%2'")
3053                       .arg(expectedTabName2)
3054                       .arg(actualTabName2));
3055 
3056     const QStringList outputFiles2 = GTUtilsDashboard::getOutputFiles(os);
3057     CHECK_SET_ERR(!outputFiles2.isEmpty(), "Active dashboard is not displayed properly");
3058 }
3059 
GUI_TEST_CLASS_DEFINITION(output_dir_scanning_test_0003)3060 GUI_TEST_CLASS_DEFINITION(output_dir_scanning_test_0003) {
3061     //    1. Set "_common_data/workflow/dashboard/workflow_outputs/two_visible_two_invisible" as workflow output folder in the "Application Settings".
3062     const QFileInfo originalWorkflowOutputDir = testDir + "_common_data/workflow/dashboard/workflow_outputs/two_visible_two_invisible";
3063     const QFileInfo testWorkflowOutputDir = sandBoxDir + "two_visible_two_invisible";
3064     GTFile::copyDir(os, originalWorkflowOutputDir.absoluteFilePath(), testWorkflowOutputDir.absoluteFilePath());
3065     setWorkflowOutputDir(os, testWorkflowOutputDir.absoluteFilePath());
3066 
3067     //    2. Wait for scan task finish.
3068     GTUtilsTaskTreeView::waitTaskFinished(os);
3069 
3070     //    3. Open Workflow Designer.
3071     GTUtilsWorkflowDesigner::openWorkflowDesigner(os);
3072     int tabIndex1 = GTUtilsMdi::getCurrentTab(os);
3073     GTUtilsTaskTreeView::waitTaskFinished(os);
3074 
3075     //    4. Open Workflow Designer.
3076     GTUtilsWorkflowDesigner::openWorkflowDesigner(os);
3077     GTUtilsTaskTreeView::waitTaskFinished(os);
3078 
3079     //    5. Click to the "Go to Dashboards" button on the toolbar.
3080     QAbstractButton *viewSwitchButton = qobject_cast<QAbstractButton *>(
3081         GTToolbar::getWidgetForActionTooltip(os,
3082                                              GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI),
3083                                              "Show dashboard"));
3084     CHECK_SET_ERR(nullptr != viewSwitchButton, "'Go to Dashboards' is nullptr");
3085     CHECK_SET_ERR(viewSwitchButton->isVisible(), "View switch button is unexpectedly invisible");
3086     CHECK_SET_ERR(viewSwitchButton->isEnabled(), "View switch button is unexpectedly disabled");
3087     GTWidget::click(os, viewSwitchButton);
3088 
3089     //    6. Set "_common_data/workflow/dashboard/workflow_outputs/one_visible_one_invisible" as workflow output folder in the "Application Settings".
3090     const QFileInfo originalWorkflowOutputDir2 = testDir + "_common_data/workflow/dashboard/workflow_outputs/one_visible_one_invisible";
3091     const QFileInfo testWorkflowOutputDir2 = sandBoxDir + "one_visible_one_invisible";
3092     GTFile::copyDir(os, originalWorkflowOutputDir2.absoluteFilePath(), testWorkflowOutputDir2.absoluteFilePath());
3093     setWorkflowOutputDir(os, testWorkflowOutputDir2.absoluteFilePath());
3094 
3095     //    7. Wait for scan task finish.
3096     GTUtilsTaskTreeView::waitTaskFinished(os);
3097 
3098     //    Expected result:
3099     //    - The Workflow Designer is in the dashboards view mode.
3100     //    - There is one tab with a dashboard. Its name is "Extract consensus as sequence 2".
3101     //    - The "Extract consensus as sequence 2" dashboard is active.
3102     //    - The dashboard is correctly displayed.
3103     //    - The "Dashboards manager" button on the toolbar is active.
3104     CHECK_SET_ERR(viewSwitchButton->isVisible(), "View switch button is unexpectedly invisible");
3105     CHECK_SET_ERR(viewSwitchButton->isEnabled(), "View switch button is unexpectedly disabled");
3106 
3107     QString expectedButtonText = "To Workflow Designer";
3108     QString actualButtonText = viewSwitchButton->text();
3109     CHECK_SET_ERR(expectedButtonText == actualButtonText,
3110                   QString("View switch button has an unexpected text: expected '%1', got '%2'")
3111                       .arg(expectedButtonText)
3112                       .arg(actualButtonText));
3113 
3114     QTabWidget *dashboardsView = GTUtilsDashboard::getTabWidget(os);
3115     CHECK_SET_ERR(nullptr != dashboardsView, "Dashboards view is nullptr");
3116 
3117     const int expectedTabsCount = 1;
3118     const int actualTabsCount = dashboardsView->count();
3119     CHECK_SET_ERR(expectedTabsCount == actualTabsCount,
3120                   QString("There is an incorrect count of tabs in the Dashboard View: expected %1, got %2")
3121                       .arg(expectedTabsCount)
3122                       .arg(actualTabsCount));
3123 
3124     const int expectedActiveTabIndex = 0;
3125     const int actualActiveTabIndex = dashboardsView->currentIndex();
3126     CHECK_SET_ERR(expectedActiveTabIndex == actualActiveTabIndex,
3127                   QString("There is an incorrect active tab: expected index is %1, actual index is %2")
3128                       .arg(expectedActiveTabIndex)
3129                       .arg(actualActiveTabIndex));
3130 
3131     const QString expectedTabName = "Extract consensus as sequence 2";
3132     const QString actualTabName = GTUtilsDashboard::getDashboardName(os, expectedActiveTabIndex);
3133     CHECK_SET_ERR(expectedTabName == actualTabName,
3134                   QString("Active dashboard has an unexpected name: expect '%1', got '%2'")
3135                       .arg(expectedTabName)
3136                       .arg(actualTabName));
3137 
3138     const QStringList outputFiles = GTUtilsDashboard::getOutputFiles(os);
3139     CHECK_SET_ERR(!outputFiles.isEmpty(), "Active dashboard is not displayed properly");
3140 
3141     QWidget *dashboardsManagerButton = GTToolbar::getWidgetForActionTooltip(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Dashboards manager");
3142     CHECK_SET_ERR(nullptr != dashboardsManagerButton, "'Dashboards manager' is nullptr");
3143     CHECK_SET_ERR(dashboardsManagerButton->isEnabled(), "'Dashboards manager' button is unexpectedly disabled");
3144 
3145     //    8. Click to the "Dashboards manager" button on the toolbar.
3146     //    Expected result: the "Dashboards Manager" dialog appears. It contains two items, both of them are checked. Their names are "Extract consensus as sequence 1" and "Extract consensus as sequence 2".
3147     //    9. Close the messagebox.
3148     class Scenario : public CustomScenario {
3149     public:
3150         void run(HI::GUITestOpStatus &os) override {
3151             QWidget *dialog = GTWidget::getActiveModalWidget(os);
3152             const QList<QPair<QString, bool>> expectedDashboardsState({qMakePair(QString("Extract consensus as sequence 1"), false),
3153                                                                        qMakePair(QString("Extract consensus as sequence 2"), true)});
3154             const QList<QPair<QString, bool>> actualDashboardsState = DashboardsManagerDialogFiller::getDashboardsState(os);
3155 
3156             CHECK_SET_ERR(expectedDashboardsState.size() == actualDashboardsState.size(),
3157                           QString("Expected dashboards count is not equal to the actual dashboards list size: expected %1, got %2")
3158                               .arg(expectedDashboardsState.size())
3159                               .arg(actualDashboardsState.size()));
3160 
3161             for (int i = 0; i < expectedDashboardsState.size(); ++i) {
3162                 const QString expectedDashboardName = expectedDashboardsState[i].first;
3163                 const QString actualDashboardName = actualDashboardsState[i].first;
3164                 CHECK_SET_ERR(expectedDashboardName == actualDashboardName,
3165                               QString("Dashboard number %1 has an unexpected name: expected '%2', got '%3'")
3166                                   .arg(i)
3167                                   .arg(expectedDashboardName)
3168                                   .arg(actualDashboardName));
3169 
3170                 const bool expectedDashboardState = expectedDashboardsState[i].second;
3171                 const bool actualDashboardState = actualDashboardsState[i].second;
3172                 CHECK_SET_ERR(expectedDashboardState == actualDashboardState,
3173                               QString("Dashboard number %1 has an unexpected state: it should be %2, but it is '%3'")
3174                                   .arg(i)
3175                                   .arg(expectedDashboardState ? "visible" : "invisible")
3176                                   .arg(actualDashboardState ? "visible" : "invisible"));
3177             }
3178 
3179             GTUtilsDialog::clickButtonBox(os, dialog, QDialogButtonBox::Cancel);
3180         }
3181     };
3182 
3183     GTUtilsDialog::waitForDialog(os, new DashboardsManagerDialogFiller(os, new Scenario()));
3184     GTWidget::click(os, dashboardsManagerButton);
3185 
3186     //    10. Switch to another Workflow Designer.
3187     coreLog.info(QString("Try to switch to tab %1(%2)")
3188                      .arg(tabIndex1)
3189                      .arg(GTUtilsMdi::getTabBar(os)->tabText(tabIndex1)));
3190     GTUtilsMdi::clickTab(os, tabIndex1);
3191 
3192     //    Expected result:
3193     //      - The Workflow Designer is in the scene view mode.
3194     //      - The "Dashboards manager" button on the toolbar is active.
3195     dashboardsManagerButton = GTToolbar::getWidgetForActionTooltip(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Dashboards manager");
3196     CHECK_SET_ERR(nullptr != dashboardsManagerButton, "'Dashboards manager' is nullptr");
3197     CHECK_SET_ERR(dashboardsManagerButton->isEnabled(), "'Dashboards manager' button is unexpectedly disabled");
3198 
3199     //    11. Click to the "Dashboards manager" button on the toolbar.
3200     //    12. Cancel the dialog
3201     //    Expected result:
3202     //    - There are two tabs with dashboards. Their names are "Extract consensus as sequence 1" and "Extract consensus as sequence 2".
3203     //    - The "Extract consensus as sequence 2" dashboard is active.
3204     //    - The dashboard is correctly displayed.
3205     GTUtilsDialog::waitForDialog(os, new DashboardsManagerDialogFiller(os, new Scenario()));
3206     GTWidget::click(os, dashboardsManagerButton);
3207 
3208     //    13. Click to the "Go to Dashboards" button on the toolbar.
3209     //    Expected result:
3210     //    - There is one tab with a dashboard. Its name is "Extract consensus as sequence 2".
3211     //    - The "Extract consensus as sequence 2" dashboard is active.
3212     //    - The dashboard is correctly displayed.
3213     viewSwitchButton = qobject_cast<QAbstractButton *>(
3214         GTToolbar::getWidgetForActionTooltip(os,
3215                                              GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI),
3216                                              "Show dashboard"));
3217     CHECK_SET_ERR(nullptr != viewSwitchButton, "'Go to Dashboards' is nullptr");
3218     CHECK_SET_ERR(viewSwitchButton->isVisible(), "View switch button is unexpectedly invisible");
3219     CHECK_SET_ERR(viewSwitchButton->isEnabled(), "View switch button is unexpectedly disabled");
3220     GTWidget::click(os, viewSwitchButton);
3221 
3222     dashboardsView = GTUtilsDashboard::getTabWidget(os);
3223     CHECK_SET_ERR(nullptr != dashboardsView, "Dashboards view is nullptr");
3224 
3225     const int expectedTabsCount2 = 1;
3226     const int actualTabsCount2 = dashboardsView->count();
3227     CHECK_SET_ERR(expectedTabsCount2 == actualTabsCount2,
3228                   QString("There is an incorrect count of tabs in the Dashboard View: expected %1, got %2")
3229                       .arg(expectedTabsCount2)
3230                       .arg(actualTabsCount2));
3231 
3232     const int expectedActiveTabIndex2 = 0;
3233     const int actualActiveTabIndex2 = dashboardsView->currentIndex();
3234     CHECK_SET_ERR(expectedActiveTabIndex2 == actualActiveTabIndex2,
3235                   QString("There is an incorrect active tab: expected index is %1, actual index is %2")
3236                       .arg(expectedActiveTabIndex2)
3237                       .arg(actualActiveTabIndex2));
3238 
3239     const QString expectedTabName2 = "Extract consensus as sequence 2";
3240     const QString actualTabName2 = GTUtilsDashboard::getDashboardName(os, expectedActiveTabIndex2);
3241     CHECK_SET_ERR(expectedTabName2 == actualTabName2,
3242                   QString("Active dashboard has an unexpected name: expect '%1', got '%2'")
3243                       .arg(expectedTabName2)
3244                       .arg(actualTabName2));
3245 
3246     const QStringList outputFiles2 = GTUtilsDashboard::getOutputFiles(os);
3247     CHECK_SET_ERR(!outputFiles2.isEmpty(), "Active dashboard is not displayed properly");
3248 }
3249 
GUI_TEST_CLASS_DEFINITION(output_dir_scanning_test_0004)3250 GUI_TEST_CLASS_DEFINITION(output_dir_scanning_test_0004) {
3251     //    1. Set "_common_data/workflow/dashboard/workflow_outputs/two_visible_two_invisible" as workflow output folder in the "Application Settings".
3252     const QFileInfo originalWorkflowOutputDir = testDir + "_common_data/workflow/dashboard/workflow_outputs/two_visible_two_invisible";
3253     const QFileInfo testWorkflowOutputDir = sandBoxDir + "two_visible_two_invisible";
3254     GTFile::copyDir(os, originalWorkflowOutputDir.absoluteFilePath(), testWorkflowOutputDir.absoluteFilePath());
3255     setWorkflowOutputDir(os, testWorkflowOutputDir.absoluteFilePath());
3256 
3257     //    2. Wait for scan task finish.
3258     GTUtilsTaskTreeView::waitTaskFinished(os);
3259 
3260     //    3. Open Workflow Designer.
3261     GTUtilsWorkflowDesigner::openWorkflowDesigner(os);
3262     int tabIndex1 = GTUtilsMdi::getCurrentTab(os);
3263     GTUtilsTaskTreeView::waitTaskFinished(os);
3264 
3265     //    4. Open Workflow Designer.
3266     GTUtilsWorkflowDesigner::openWorkflowDesigner(os);
3267     GTUtilsTaskTreeView::waitTaskFinished(os);
3268 
3269     //    5. Click to the "Go to Dashboards" button on the toolbar.
3270     QAbstractButton *viewSwitchButton = qobject_cast<QAbstractButton *>(
3271         GTToolbar::getWidgetForActionTooltip(os,
3272                                              GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI),
3273                                              "Show dashboard"));
3274     CHECK_SET_ERR(nullptr != viewSwitchButton, "'Go to Dashboards' is nullptr");
3275     CHECK_SET_ERR(viewSwitchButton->isVisible(), "View switch button is unexpectedly invisible");
3276     CHECK_SET_ERR(viewSwitchButton->isEnabled(), "View switch button is unexpectedly disabled");
3277     GTWidget::click(os, viewSwitchButton);
3278 
3279     //    6. Set "_common_data/workflow/dashboard/workflow_outputs/two_invisible_dashboards" as workflow output folder in the "Application Settings".
3280     const QFileInfo originalWorkflowOutputDir2 = testDir + "_common_data/workflow/dashboard/workflow_outputs/two_invisible_dashboards";
3281     const QFileInfo testWorkflowOutputDir2 = sandBoxDir + "two_invisible_dashboards";
3282     GTFile::copyDir(os, originalWorkflowOutputDir2.absoluteFilePath(), testWorkflowOutputDir2.absoluteFilePath());
3283     setWorkflowOutputDir(os, testWorkflowOutputDir2.absoluteFilePath());
3284 
3285     //    7. Wait for scan task finish.
3286     GTUtilsTaskTreeView::waitTaskFinished(os);
3287 
3288     //    Expected result:
3289     //    - The Workflow Designer is in the scene view mode.
3290     //    - There is no scene/dashboards switch button on the toolbar.
3291     //    - The "Dashboards manager" button on the toolbar is active.
3292     CHECK_SET_ERR(!viewSwitchButton->isVisible(), "View switch button is unexpectedly visible");
3293 
3294     QTabWidget *dashboardsView = GTUtilsDashboard::getTabWidget(os);
3295     CHECK_SET_ERR(nullptr != dashboardsView, "Dashboards view is nullptr");
3296 
3297     QWidget *dashboardsManagerButton = GTToolbar::getWidgetForActionTooltip(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Dashboards manager");
3298     CHECK_SET_ERR(nullptr != dashboardsManagerButton, "'Dashboards manager' is nullptr");
3299     CHECK_SET_ERR(dashboardsManagerButton->isEnabled(), "'Dashboards manager' button is unexpectedly disabled");
3300 
3301     //    8. Click to the "Dashboards manager" button on the toolbar.
3302     //    Expected result: the "Dashboards Manager" dialog appears. It contains two items, both of them are unchecked. Their names are "Extract consensus as sequence 1" and "Extract consensus as sequence 2".
3303     //    9. Close the messagebox.
3304     class Scenario : public CustomScenario {
3305     public:
3306         void run(HI::GUITestOpStatus &os) override {
3307             QWidget *dialog = GTWidget::getActiveModalWidget(os);
3308             const QList<QPair<QString, bool>> expectedDashboardsState({qMakePair(QString("Extract consensus as sequence 1"), false),
3309                                                                        qMakePair(QString("Extract consensus as sequence 2"), false)});
3310             const QList<QPair<QString, bool>> actualDashboardsState = DashboardsManagerDialogFiller::getDashboardsState(os);
3311 
3312             CHECK_SET_ERR(expectedDashboardsState.size() == actualDashboardsState.size(),
3313                           QString("Expected dashboards count is not equal to the actual dashboards list size: expected %1, got %2")
3314                               .arg(expectedDashboardsState.size())
3315                               .arg(actualDashboardsState.size()));
3316 
3317             for (int i = 0; i < expectedDashboardsState.size(); ++i) {
3318                 const QString expectedDashboardName = expectedDashboardsState[i].first;
3319                 const QString actualDashboardName = actualDashboardsState[i].first;
3320                 CHECK_SET_ERR(expectedDashboardName == actualDashboardName,
3321                               QString("Dashboard number %1 has an unexpected name: expected '%2', got '%3'")
3322                                   .arg(i)
3323                                   .arg(expectedDashboardName)
3324                                   .arg(actualDashboardName));
3325 
3326                 const bool expectedDashboardState = expectedDashboardsState[i].second;
3327                 const bool actualDashboardState = actualDashboardsState[i].second;
3328                 CHECK_SET_ERR(expectedDashboardState == actualDashboardState,
3329                               QString("Dashboard number %1 has an unexpected state: it should be %2, but it is '%3'")
3330                                   .arg(i)
3331                                   .arg(expectedDashboardState ? "visible" : "invisible")
3332                                   .arg(actualDashboardState ? "visible" : "invisible"));
3333             }
3334 
3335             GTUtilsDialog::clickButtonBox(os, dialog, QDialogButtonBox::Cancel);
3336         }
3337     };
3338 
3339     GTUtilsDialog::waitForDialog(os, new DashboardsManagerDialogFiller(os, new Scenario()));
3340     GTWidget::click(os, dashboardsManagerButton);
3341 
3342     //    10. Switch to another Workflow Designer.
3343     coreLog.info(QString("Try to switch to tab %1(%2)")
3344                      .arg(tabIndex1)
3345                      .arg(GTUtilsMdi::getTabBar(os)->tabText(tabIndex1)));
3346     GTUtilsMdi::clickTab(os, tabIndex1);
3347 
3348     //    Expected result:
3349     //      - The Workflow Designer is in the scene view mode.
3350     //      - There is no scene/dashboards switch button on the toolbar.
3351     //      - The "Dashboards manager" button on the toolbar is active.
3352     viewSwitchButton = qobject_cast<QAbstractButton *>(
3353         GTToolbar::getWidgetForActionTooltip(os,
3354                                              GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI),
3355                                              "Show dashboard"));
3356     CHECK_SET_ERR(nullptr == viewSwitchButton || !viewSwitchButton->isVisible(), "View switch button is unexpectedly visible");
3357 
3358     QTabWidget *dashboardsView2 = GTUtilsDashboard::getTabWidget(os);
3359     CHECK_SET_ERR(nullptr != dashboardsView2, "Dashboards view is nullptr");
3360 
3361     dashboardsManagerButton = GTToolbar::getWidgetForActionTooltip(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Dashboards manager");
3362     CHECK_SET_ERR(nullptr != dashboardsManagerButton, "'Dashboards manager' is nullptr");
3363     CHECK_SET_ERR(dashboardsManagerButton->isEnabled(), "'Dashboards manager' button is unexpectedly disabled");
3364 
3365     //    11. Click to the "Dashboards manager" button on the toolbar.
3366     //    12. Cancel the dialog
3367     //    Expected result:
3368     //    Expected result: the "Dashboards Manager" dialog appears. It contains two items, both of them are unchecked. Their names are "Extract consensus as sequence 1" and "Extract consensus as sequence 2".
3369     GTUtilsDialog::waitForDialog(os, new DashboardsManagerDialogFiller(os, new Scenario()));
3370     GTWidget::click(os, dashboardsManagerButton);
3371 }
3372 
GUI_TEST_CLASS_DEFINITION(output_dir_scanning_test_0005_1)3373 GUI_TEST_CLASS_DEFINITION(output_dir_scanning_test_0005_1) {
3374     //    1. Set "_common_data/workflow/dashboard/workflow_outputs/two_visible_two_invisible" as workflow output folder in the "Application Settings".
3375     const QFileInfo originalWorkflowOutputDir = testDir + "_common_data/workflow/dashboard/workflow_outputs/two_visible_two_invisible";
3376     const QFileInfo testWorkflowOutputDir = sandBoxDir + "two_visible_two_invisible";
3377     GTFile::copyDir(os, originalWorkflowOutputDir.absoluteFilePath(), testWorkflowOutputDir.absoluteFilePath());
3378     setWorkflowOutputDir(os, testWorkflowOutputDir.absoluteFilePath());
3379 
3380     //    2. Wait for scan task finish.
3381     GTUtilsTaskTreeView::waitTaskFinished(os);
3382 
3383     //    3. Open Workflow Designer.
3384     GTUtilsWorkflowDesigner::openWorkflowDesigner(os);
3385     GTUtilsTaskTreeView::waitTaskFinished(os);
3386     int tabIndex1 = GTUtilsMdi::getCurrentTab(os);
3387 
3388     //    4. Open "Align sequence with MUSCLE" sample.
3389     GTUtilsWorkflowDesigner::addSample(os, "Align sequences with MUSCLE", GTUtilsMdi::activeWindow(os));
3390 
3391     //    5. Cancel the wizard.
3392     GTKeyboardDriver::keyClick(Qt::Key_Escape);
3393 
3394     //    6. Click to the "Read alignment" element.
3395     GTMouseDriver::moveTo(GTUtilsWorkflowDesigner::getItemCenter(os, "Read alignment"));
3396     GTMouseDriver::click();
3397 
3398     //    7. Add "_common_data/clustal/200_sequences.aln" file to "Dataset 1" dataset.
3399     GTUtilsWorkflowDesigner::setDatasetInputFile(os, testDir + "_common_data/clustal/200_sequences.aln");
3400 
3401     //    8. Open Workflow Designer.
3402     GTUtilsWorkflowDesigner::openWorkflowDesigner(os);
3403     GTUtilsTaskTreeView::waitTaskFinished(os);
3404     int tabIndex2 = GTUtilsMdi::getCurrentTab(os);
3405 
3406     //    9. Open "Align sequence with MUSCLE" sample.
3407     GTUtilsWorkflowDesigner::addSample(os, "Align sequences with MUSCLE", GTUtilsMdi::activeWindow(os));
3408 
3409     //    10. Cancel the wizard.
3410     GTKeyboardDriver::keyClick(Qt::Key_Escape);
3411 
3412     //    11. Click to the "Read alignment" element.
3413     GTMouseDriver::moveTo(GTUtilsWorkflowDesigner::getItemCenter(os, "Read alignment"));
3414     GTMouseDriver::click();
3415 
3416     //    12. Add "_common_data/clustal/200_sequences.aln" file to "Dataset 1" dataset.
3417     GTUtilsWorkflowDesigner::setDatasetInputFile(os, testDir + "_common_data/clustal/200_sequences.aln");
3418 
3419     //    13. Open Workflow Designer.
3420     GTUtilsWorkflowDesigner::openWorkflowDesigner(os);
3421     GTUtilsTaskTreeView::waitTaskFinished(os);
3422 
3423     //    14. Click to the "Go to Dashboards" button on the toolbar.
3424     QAbstractButton *viewSwitchButton = qobject_cast<QAbstractButton *>(
3425         GTToolbar::getWidgetForActionTooltip(os,
3426                                              GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI),
3427                                              "Show dashboard"));
3428     CHECK_SET_ERR(nullptr != viewSwitchButton, "'Go to Dashboards' is nullptr");
3429     CHECK_SET_ERR(viewSwitchButton->isVisible(), "View switch button is unexpectedly invisible");
3430     CHECK_SET_ERR(viewSwitchButton->isEnabled(), "View switch button is unexpectedly disabled");
3431     GTWidget::click(os, viewSwitchButton);
3432 
3433     //    15. Switch to first Workflow Designer.
3434     coreLog.info(QString("Try to switch to tab %1(%2)")
3435                      .arg(tabIndex1)
3436                      .arg(GTUtilsMdi::getTabBar(os)->tabText(tabIndex1)));
3437     GTUtilsMdi::clickTab(os, tabIndex1);
3438 
3439     //    16. Launch the workflow. Do not wait for the task finish.
3440     coreLog.info("Try to start workflow #1");
3441     GTUtilsWorkflowDesigner::runWorkflow(os);
3442     coreLog.info("It seems that workflow was started");
3443 
3444     //    17. Switch to the second Workflow Designer.
3445     coreLog.info(QString("Try to switch to tab %1(%2)")
3446                      .arg(tabIndex2)
3447                      .arg(GTUtilsMdi::getTabBar(os)->tabText(tabIndex2)));
3448     GTUtilsMdi::clickTab(os, tabIndex2);
3449 
3450     //    18. Launch the workflow. Do not wait for the task finish.
3451     coreLog.info("Try to start workflow #2");
3452     GTUtilsWorkflowDesigner::runWorkflow(os);
3453     coreLog.info("It seems that workflow was started");
3454 }
3455 
setUpMuscleSchemeInNewWdWindow(GUITestOpStatus & os,const QString & file)3456 static int setUpMuscleSchemeInNewWdWindow(GUITestOpStatus &os, const QString &file) {
3457     //    Open Workflow Designer.
3458     GTUtilsWorkflowDesigner::openWorkflowDesigner(os);
3459     GTUtilsTaskTreeView::waitTaskFinished(os);
3460     int tabIndex = GTUtilsMdi::getCurrentTab(os);
3461 
3462     // Open "Align sequence with MUSCLE" sample.
3463     GTUtilsWorkflowDesigner::addSample(os, "Align sequences with MUSCLE", GTUtilsMdi::activeWindow(os));
3464 
3465     // Cancel the wizard.
3466     GTKeyboardDriver::keyClick(Qt::Key_Escape);
3467 
3468     // Click to the "Read alignment" element.
3469     GTMouseDriver::moveTo(GTUtilsWorkflowDesigner::getItemCenter(os, "Read alignment"));
3470     GTMouseDriver::click();
3471 
3472     //  Add "file" file to "Dataset 1" dataset.
3473     GTUtilsWorkflowDesigner::setDatasetInputFile(os, file);
3474 
3475     return tabIndex;
3476 }
3477 
GUI_TEST_CLASS_DEFINITION(output_dir_scanning_test_0005)3478 GUI_TEST_CLASS_DEFINITION(output_dir_scanning_test_0005) {
3479     //   Set "_common_data/workflow/dashboard/workflow_outputs/two_visible_two_invisible" as workflow output folder in the "Application Settings".
3480     QFileInfo originalWorkflowOutputDir = testDir + "_common_data/workflow/dashboard/workflow_outputs/two_visible_two_invisible";
3481     QFileInfo testWorkflowOutputDir = sandBoxDir + "two_visible_two_invisible";
3482     GTFile::copyDir(os, originalWorkflowOutputDir.absoluteFilePath(), testWorkflowOutputDir.absoluteFilePath());
3483     setWorkflowOutputDir(os, testWorkflowOutputDir.absoluteFilePath());
3484     //   Wait for scan task finish.
3485     GTUtilsTaskTreeView::waitTaskFinished(os);
3486 
3487     QString msaFilePath = testDir + "_common_data/clustal/100_sequences.aln";
3488     int tabIndex1 = setUpMuscleSchemeInNewWdWindow(os, msaFilePath);
3489     int tabIndex2 = setUpMuscleSchemeInNewWdWindow(os, msaFilePath);
3490 
3491     //   Open Workflow Designer.
3492     GTUtilsWorkflowDesigner::openWorkflowDesigner(os);
3493     int tabIndex3 = GTUtilsMdi::getCurrentTab(os);
3494     GTUtilsTaskTreeView::waitTaskFinished(os);
3495 
3496     //   Click to the "Go to Dashboards" button on the toolbar.
3497     QAbstractButton *viewSwitchButton = qobject_cast<QAbstractButton *>(
3498         GTToolbar::getWidgetForActionTooltip(os,
3499                                              GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI),
3500                                              "Show dashboard"));
3501     CHECK_SET_ERR(viewSwitchButton != nullptr, "'Go to Dashboards' is nullptr");
3502     CHECK_SET_ERR(viewSwitchButton->isVisible(), "View switch button is unexpectedly invisible");
3503     CHECK_SET_ERR(viewSwitchButton->isEnabled(), "View switch button is unexpectedly disabled");
3504     GTWidget::click(os, viewSwitchButton);
3505 
3506     //    Switch to first Workflow Designer.
3507     coreLog.info(QString("Try to switch to tab %1(%2)")
3508                      .arg(tabIndex1)
3509                      .arg(GTUtilsMdi::getTabBar(os)->tabText(tabIndex1)));
3510     GTUtilsMdi::clickTab(os, tabIndex1);
3511 
3512     //    16. Launch the workflow. Do not wait for the task finish.
3513     coreLog.info("Try to start workflow #1");
3514     GTUtilsWorkflowDesigner::runWorkflow(os);
3515     coreLog.info("It seems that workflow was started");
3516 
3517     //    Switch to the second Workflow Designer.
3518     coreLog.info(QString("Try to switch to tab %1(%2)")
3519                      .arg(tabIndex2)
3520                      .arg(GTUtilsMdi::getTabBar(os)->tabText(tabIndex2)));
3521     GTUtilsMdi::clickTab(os, tabIndex2);
3522 
3523     //    Launch the workflow. Do not wait for the task finish.
3524     coreLog.info("Try to start workflow #2");
3525     GTUtilsWorkflowDesigner::runWorkflow(os);
3526     coreLog.info("It seems that workflow was started");
3527 
3528     //    Set "_common_data/workflow/dashboard/workflow_outputs/empty_workflow_output" as workflow output folder in the "Application Settings".
3529     QFileInfo originalWorkflowOutputDir2 = testDir + "_common_data/workflow/dashboard/workflow_outputs/empty_workflow_output";
3530     QFileInfo testWorkflowOutputDir2 = sandBoxDir + "empty_workflow_output";
3531     GTFile::copyDir(os, originalWorkflowOutputDir2.absoluteFilePath(), testWorkflowOutputDir2.absoluteFilePath());
3532     setWorkflowOutputDir(os, testWorkflowOutputDir2.absoluteFilePath());
3533 
3534     //    Wait for all tasks finish. The scan task is supposed to finish before align tasks.
3535     //        Expected result:
3536     //          - The Workflow Designer is in the dashboards view mode.
3537     //          - There are two dashboard tabs. Their names are "Align sequence with MUSCLE 2" and "Align sequence with MUSCLE 1".
3538     //          - The "Align sequence with MUSCLE 2" dashboard is active.
3539     //          - The "Dashboards manager" button on the toolbar is active.
3540     GTUtilsTaskTreeView::waitTaskFinished(os, 90000);
3541 
3542     viewSwitchButton = qobject_cast<QAbstractButton *>(GTToolbar::getWidgetForActionTooltip(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Show workflow"));
3543     CHECK_SET_ERR(viewSwitchButton != nullptr, "'To Workflow Designer' is nullptr");
3544     CHECK_SET_ERR(viewSwitchButton->isVisible(), "View switch button is unexpectedly invisible");
3545     CHECK_SET_ERR(viewSwitchButton->isEnabled(), "View switch button is unexpectedly disabled");
3546 
3547     QString expectedButtonText = "To Workflow Designer";
3548     QString actualButtonText = viewSwitchButton->text();
3549     CHECK_SET_ERR(actualButtonText == expectedButtonText,
3550                   QString("View switch button has an unexpected text: expected '%1', got '%2'")
3551                       .arg(expectedButtonText)
3552                       .arg(actualButtonText));
3553 
3554     coreLog.info("Trying get GTUtilsDashboard::getTabWidget(os)");
3555     QTabWidget *dashboardsView = GTUtilsDashboard::getTabWidget(os);
3556     CHECK_SET_ERR(dashboardsView != nullptr, "Dashboards view is nullptr");
3557     coreLog.info("Successfully got GTUtilsDashboard::getTabWidget(os)");
3558 
3559     int expectedTabsCount = 2;
3560     int actualTabsCount = dashboardsView->count();
3561     CHECK_SET_ERR(actualTabsCount == expectedTabsCount,
3562                   QString("There is an incorrect count of tabs in the Dashboard View: expected %1, got %2")
3563                       .arg(expectedTabsCount)
3564                       .arg(actualTabsCount));
3565 
3566     int expectedActiveTabIndex = 0;
3567     int actualActiveTabIndex = dashboardsView->currentIndex();
3568     CHECK_SET_ERR(expectedActiveTabIndex == actualActiveTabIndex,
3569                   QString("There is an incorrect active tab: expected index is %1, actual index is %2")
3570                       .arg(expectedActiveTabIndex)
3571                       .arg(actualActiveTabIndex));
3572 
3573     QString expectedTabName = "Align sequences with MUSCLE 2";
3574     QString actualTabName = GTUtilsDashboard::getDashboardName(os, expectedActiveTabIndex);
3575     CHECK_SET_ERR(expectedTabName == actualTabName,
3576                   QString("Active dashboard has an unexpected name: expect '%1', got '%2'")
3577                       .arg(expectedTabName)
3578                       .arg(actualTabName));
3579 
3580     QStringList outputFiles = GTUtilsDashboard::getOutputFiles(os);
3581     CHECK_SET_ERR(!outputFiles.isEmpty(), "Active dashboard is not displayed properly");
3582 
3583     QWidget *dashboardsManagerButton = GTToolbar::getWidgetForActionTooltip(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Dashboards manager");
3584     CHECK_SET_ERR(nullptr != dashboardsManagerButton, "'Dashboards manager' is nullptr");
3585     CHECK_SET_ERR(dashboardsManagerButton->isEnabled(), "'Dashboards manager' button is unexpectedly disabled");
3586 
3587     //    Click to the "Dashboards manager" button on the toolbar.
3588     //    Expected result: the "Dashboards Manager" dialog appears. It contains two items, both of them are checked. Their names are "Align sequence with MUSCLE 1" and "Align sequence with MUSCLE 2".
3589     //    Cancel the dialog
3590     class Scenario : public CustomScenario {
3591     public:
3592         void run(HI::GUITestOpStatus &os) override {
3593             QWidget *dialog = GTWidget::getActiveModalWidget(os);
3594             const QList<QPair<QString, bool>> expectedDashboardsState({qMakePair(QString("Align sequences with MUSCLE 1"), true),
3595                                                                        qMakePair(QString("Align sequences with MUSCLE 2"), true)});
3596             const QList<QPair<QString, bool>> actualDashboardsState = DashboardsManagerDialogFiller::getDashboardsState(os);
3597 
3598             CHECK_SET_ERR(expectedDashboardsState.size() == actualDashboardsState.size(),
3599                           QString("Expected dashboards count is not equal to the actual dashboards list size: expected %1, got %2")
3600                               .arg(expectedDashboardsState.size())
3601                               .arg(actualDashboardsState.size()));
3602 
3603             for (int i = 0; i < expectedDashboardsState.size(); ++i) {
3604                 const QString expectedDashboardName = expectedDashboardsState[i].first;
3605                 const QString actualDashboardName = actualDashboardsState[i].first;
3606                 CHECK_SET_ERR(expectedDashboardName == actualDashboardName,
3607                               QString("Dashboard number %1 has an unexpected name: expected '%2', got '%3'")
3608                                   .arg(i)
3609                                   .arg(expectedDashboardName)
3610                                   .arg(actualDashboardName));
3611 
3612                 const bool expectedDashboardState = expectedDashboardsState[i].second;
3613                 const bool actualDashboardState = actualDashboardsState[i].second;
3614                 CHECK_SET_ERR(expectedDashboardState == actualDashboardState,
3615                               QString("Dashboard number %1 has an unexpected state: it should be %2, but it is '%3'")
3616                                   .arg(i)
3617                                   .arg(expectedDashboardState ? "visible" : "invisible")
3618                                   .arg(actualDashboardState ? "visible" : "invisible"));
3619             }
3620 
3621             GTUtilsDialog::clickButtonBox(os, dialog, QDialogButtonBox::Cancel);
3622         }
3623     };
3624 
3625     GTUtilsDialog::waitForDialog(os, new DashboardsManagerDialogFiller(os, new Scenario()));
3626     GTWidget::click(os, dashboardsManagerButton);
3627 
3628     //    Switch to the first Workflow Designer.
3629     //    Expected result:
3630     //     - The Workflow Designer is in the dashboards view mode.
3631     //     - There are two dashboard tabs. Their names are "Align sequence with MUSCLE 1" and "Align sequence with MUSCLE 2".
3632     //     - The "Align sequence with MUSCLE 1" dashboard is active.
3633     //     - The "Dashboards manager" button on the toolbar is active.
3634     coreLog.info(QString("Try to switch to tab %1(%2)")
3635                      .arg(tabIndex1)
3636                      .arg(GTUtilsMdi::getTabBar(os)->tabText(tabIndex1)));
3637     GTUtilsMdi::clickTab(os, tabIndex1);
3638     GTUtilsTaskTreeView::waitTaskFinished(os);
3639 
3640     viewSwitchButton = qobject_cast<QAbstractButton *>(
3641         GTToolbar::getWidgetForActionTooltip(os,
3642                                              GTToolbar::getToolbar(os,
3643                                                                    MWTOOLBAR_ACTIVEMDI),
3644                                              "Show workflow"));
3645     CHECK_SET_ERR(nullptr != viewSwitchButton, "'To Workflow Designer' is nullptr");
3646     CHECK_SET_ERR(viewSwitchButton->isVisible(), "View switch button is unexpectedly invisible");
3647     CHECK_SET_ERR(viewSwitchButton->isEnabled(), "View switch button is unexpectedly disabled");
3648 
3649     expectedButtonText = "To Workflow Designer";
3650     actualButtonText = viewSwitchButton->text();
3651     CHECK_SET_ERR(expectedButtonText == actualButtonText,
3652                   QString("View switch button has an unexpected text: expected '%1', got '%2'")
3653                       .arg(expectedButtonText)
3654                       .arg(actualButtonText));
3655 
3656     coreLog.info("Trying get GTUtilsDashboard::getTabWidget(os)");
3657     dashboardsView = GTUtilsDashboard::getTabWidget(os);
3658     CHECK_SET_ERR(nullptr != dashboardsView, "Dashboards view is nullptr");
3659     coreLog.info("Successfully got GTUtilsDashboard::getTabWidget(os)");
3660 
3661     expectedTabsCount = 2;
3662     actualTabsCount = dashboardsView->count();
3663     CHECK_SET_ERR(expectedTabsCount == actualTabsCount,
3664                   QString("There is an incorrect count of tabs in the Dashboard View: expected %1, got %2")
3665                       .arg(expectedTabsCount)
3666                       .arg(actualTabsCount));
3667 
3668     expectedActiveTabIndex = 0;
3669     actualActiveTabIndex = dashboardsView->currentIndex();
3670     CHECK_SET_ERR(expectedActiveTabIndex == actualActiveTabIndex,
3671                   QString("There is an incorrect active tab: expected index is %1, actual index is %2")
3672                       .arg(expectedActiveTabIndex)
3673                       .arg(actualActiveTabIndex));
3674 
3675     expectedTabName = "Align sequences with MUSCLE 1";
3676     actualTabName = GTUtilsDashboard::getDashboardName(os, expectedActiveTabIndex);
3677     CHECK_SET_ERR(expectedTabName == actualTabName,
3678                   QString("Active dashboard has an unexpected name: expect '%1', got '%2'")
3679                       .arg(expectedTabName)
3680                       .arg(actualTabName));
3681 
3682     outputFiles = GTUtilsDashboard::getOutputFiles(os);
3683     CHECK_SET_ERR(!outputFiles.isEmpty(), "Active dashboard is not displayed properly");
3684 
3685     dashboardsManagerButton = GTToolbar::getWidgetForActionTooltip(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Dashboards manager");
3686     CHECK_SET_ERR(nullptr != dashboardsManagerButton, "'Dashboards manager' is nullptr");
3687     CHECK_SET_ERR(dashboardsManagerButton->isEnabled(), "'Dashboards manager' button is unexpectedly disabled");
3688 
3689     //    Click to the "Dashboards manager" button on the toolbar.
3690     //    Expected result:
3691     //     - the "Dashboards Manager" dialog appears.
3692     //       It contains two items, both of them are checked.
3693     //       Their names are "Align sequence with MUSCLE 1" and "Align sequence with MUSCLE 2".
3694     //     Cancel the dialog
3695     GTUtilsDialog::waitForDialog(os, new DashboardsManagerDialogFiller(os, new Scenario()));
3696     GTWidget::click(os, dashboardsManagerButton);
3697 
3698     //    Switch to the third Workflow Designer.
3699     //    Expected result:
3700     //     - The Workflow Designer is in the scene view mode.
3701     //     - The "Dashboards manager" button on the toolbar is active.
3702     coreLog.info(QString("Try to switch to tab %1(%2)")
3703                      .arg(tabIndex3)
3704                      .arg(GTUtilsMdi::getTabBar(os)->tabText(tabIndex3)));
3705     GTUtilsMdi::clickTab(os, tabIndex3);
3706 
3707     dashboardsManagerButton = GTToolbar::getWidgetForActionTooltip(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Dashboards manager");
3708     CHECK_SET_ERR(dashboardsManagerButton != nullptr, "'Dashboards manager' is nullptr");
3709     CHECK_SET_ERR(dashboardsManagerButton->isEnabled(), "'Dashboards manager' button is unexpectedly disabled");
3710 
3711     viewSwitchButton = qobject_cast<QAbstractButton *>(
3712         GTToolbar::getWidgetForActionTooltip(os,
3713                                              GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI),
3714                                              "Show dashboard"));
3715     CHECK_SET_ERR(viewSwitchButton != nullptr &&
3716                       viewSwitchButton->isVisible(),
3717                   "'Go to Dashboards' is invisible");
3718 
3719     //    Click to the "Dashboards manager" button on the toolbar.
3720     //    Expected result:
3721     //     - the "Dashboards Manager" dialog appears.
3722     //     - It contains two items, both of them are checked.
3723     //     - Their names are "Align sequence with MUSCLE 1" and "Align sequence with MUSCLE 2".
3724     //     Cancel the dialog.
3725     GTUtilsDialog::waitForDialog(os, new DashboardsManagerDialogFiller(os, new Scenario()));
3726     GTWidget::click(os, dashboardsManagerButton);
3727 
3728     //    Click to the "Go to Dashboards" button on the toolbar.
3729     //    Expected result:
3730     //     - There are two dashboard tabs.
3731     //       Their names are "Align sequence with MUSCLE 1" and "Align sequence with MUSCLE 2" (warning: two last tabs can be swapped,
3732     //       it depends on the task finish order, it is a correct situation).
3733     //     - The first dashboard is active.
3734     viewSwitchButton = qobject_cast<QAbstractButton *>(
3735         GTToolbar::getWidgetForActionTooltip(os,
3736                                              GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI),
3737                                              "Show dashboard"));
3738     CHECK_SET_ERR(viewSwitchButton != nullptr, "'Go to Dashboards' is nullptr");
3739     CHECK_SET_ERR(viewSwitchButton->isVisible(), "View switch button is unexpectedly invisible");
3740     CHECK_SET_ERR(viewSwitchButton->isEnabled(), "View switch button is unexpectedly disabled");
3741     GTWidget::click(os, viewSwitchButton);
3742 
3743     coreLog.info("Trying get GTUtilsDashboard::getTabWidget(os)");
3744     dashboardsView = GTUtilsDashboard::getTabWidget(os);
3745     CHECK_SET_ERR(dashboardsView != nullptr, "Dashboards view is nullptr");
3746     coreLog.info("Successfully got GTUtilsDashboard::getTabWidget(os)");
3747 
3748     expectedTabsCount = 2;
3749     actualTabsCount = dashboardsView->count();
3750     CHECK_SET_ERR(expectedTabsCount == actualTabsCount,
3751                   QString("There is an incorrect count of tabs in the Dashboard View: expected %1, got %2")
3752                       .arg(expectedTabsCount)
3753                       .arg(actualTabsCount));
3754 
3755     expectedActiveTabIndex = 0;
3756     actualActiveTabIndex = dashboardsView->currentIndex();
3757     CHECK_SET_ERR(expectedActiveTabIndex == actualActiveTabIndex,
3758                   QString("There is an incorrect active tab: expected index is %1, actual index is %2")
3759                       .arg(expectedActiveTabIndex)
3760                       .arg(actualActiveTabIndex));
3761 
3762     expectedTabName = "Align sequences with MUSCLE 1";
3763     actualTabName = GTUtilsDashboard::getDashboardName(os, expectedActiveTabIndex);
3764     CHECK_SET_ERR(expectedTabName == actualTabName,
3765                   QString("Active dashboard has an unexpected name: expect '%1', got '%2'")
3766                       .arg(expectedTabName)
3767                       .arg(actualTabName));
3768 }
3769 
GUI_TEST_CLASS_DEFINITION(output_dir_scanning_test_0006)3770 GUI_TEST_CLASS_DEFINITION(output_dir_scanning_test_0006) {
3771     //    1. Set "_common_data/workflow/dashboard/workflow_outputs/two_visible_two_invisible" as workflow output folder in the "Application Settings".
3772     const QFileInfo originalWorkflowOutputDir = testDir + "_common_data/workflow/dashboard/workflow_outputs/two_visible_two_invisible";
3773     const QFileInfo testWorkflowOutputDir = sandBoxDir + "two_visible_two_invisible";
3774     GTFile::copyDir(os, originalWorkflowOutputDir.absoluteFilePath(), testWorkflowOutputDir.absoluteFilePath());
3775     setWorkflowOutputDir(os, testWorkflowOutputDir.absoluteFilePath());
3776 
3777     //    2. Wait for scan task finish.
3778     GTUtilsTaskTreeView::waitTaskFinished(os);
3779 
3780     //    3. Open Workflow Designer.
3781     GTUtilsWorkflowDesigner::openWorkflowDesigner(os);
3782     GTUtilsTaskTreeView::waitTaskFinished(os);
3783     int tabIndex1 = GTUtilsMdi::getCurrentTab(os);
3784 
3785     //    4. Open "Align sequence with MUSCLE" sample.
3786     GTUtilsWorkflowDesigner::addSample(os, "Align sequences with MUSCLE", GTUtilsMdi::activeWindow(os));
3787 
3788     //    5. Cancel the wizard.
3789     GTKeyboardDriver::keyClick(Qt::Key_Escape);
3790 
3791     //    6. Click to the "Read alignment" element.
3792     GTMouseDriver::moveTo(GTUtilsWorkflowDesigner::getItemCenter(os, "Read alignment"));
3793     GTMouseDriver::click();
3794 
3795     //    7. Add "_common_data/clustal/200_sequences.aln" file to "Dataset 1" dataset.
3796     GTUtilsWorkflowDesigner::setDatasetInputFile(os, testDir + "_common_data/clustal/100_sequences.aln");
3797 
3798     //    8. Open Workflow Designer.
3799     GTUtilsWorkflowDesigner::openWorkflowDesigner(os);
3800     GTUtilsTaskTreeView::waitTaskFinished(os);
3801     int tabIndex2 = GTUtilsMdi::getCurrentTab(os);
3802 
3803     //    9. Open "Align sequence with MUSCLE" sample.
3804     GTUtilsWorkflowDesigner::addSample(os, "Align sequences with MUSCLE", GTUtilsMdi::activeWindow(os));
3805 
3806     //    10. Cancel the wizard.
3807     GTKeyboardDriver::keyClick(Qt::Key_Escape);
3808 
3809     //    11. Click to the "Read alignment" element.
3810     GTMouseDriver::moveTo(GTUtilsWorkflowDesigner::getItemCenter(os, "Read alignment"));
3811     GTMouseDriver::click();
3812 
3813     //    12. Add "_common_data/clustal/200_sequences.aln" file to "Dataset 1" dataset.
3814     GTUtilsWorkflowDesigner::setDatasetInputFile(os, testDir + "_common_data/clustal/100_sequences.aln");
3815 
3816     //    13. Open Workflow Designer.
3817     GTUtilsWorkflowDesigner::openWorkflowDesigner(os);
3818     int tabIndex3 = GTUtilsMdi::getCurrentTab(os);
3819     GTUtilsTaskTreeView::waitTaskFinished(os);
3820 
3821     //    14. Click to the "Go to Dashboards" button on the toolbar.
3822     QAbstractButton *viewSwitchButton = qobject_cast<QAbstractButton *>(
3823         GTToolbar::getWidgetForActionTooltip(os,
3824                                              GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI),
3825                                              "Show dashboard"));
3826     CHECK_SET_ERR(nullptr != viewSwitchButton, "'Go to Dashboards' is nullptr");
3827     CHECK_SET_ERR(viewSwitchButton->isVisible(), "View switch button is unexpectedly invisible");
3828     CHECK_SET_ERR(viewSwitchButton->isEnabled(), "View switch button is unexpectedly disabled");
3829     GTWidget::click(os, viewSwitchButton);
3830 
3831     //    15. Switch to first Workflow Designer.
3832     coreLog.info(QString("Try to switch to tab %1(%2)")
3833                      .arg(tabIndex1)
3834                      .arg(GTUtilsMdi::getTabBar(os)->tabText(tabIndex1)));
3835     GTUtilsMdi::clickTab(os, tabIndex1);
3836 
3837     //    16. Launch the workflow. Do not wait for the task finish.
3838     coreLog.info("Try to start workflow #1");
3839     GTUtilsWorkflowDesigner::runWorkflow(os);
3840     coreLog.info("It seems that workflow was started");
3841 
3842     //    17. Switch to the second Workflow Designer.
3843     coreLog.info(QString("Try to switch to tab %1(%2)")
3844                      .arg(tabIndex2)
3845                      .arg(GTUtilsMdi::getTabBar(os)->tabText(tabIndex2)));
3846     GTUtilsMdi::clickTab(os, tabIndex2);
3847 
3848     //    18. Launch the workflow. Do not wait for the task finish.
3849     coreLog.info("Try to start workflow #2");
3850     GTUtilsWorkflowDesigner::runWorkflow(os);
3851     coreLog.info("It seems that workflow was started");
3852 
3853     //    19. Set "_common_data/workflow/dashboard/workflow_outputs/two_visible_dashboards" as workflow output folder in the "Application Settings".
3854     const QFileInfo originalWorkflowOutputDir2 = testDir + "_common_data/workflow/dashboard/workflow_outputs/two_visible_dashboards";
3855     const QFileInfo testWorkflowOutputDir2 = sandBoxDir + "two_visible_dashboards";
3856     GTFile::copyDir(os, originalWorkflowOutputDir2.absoluteFilePath(), testWorkflowOutputDir2.absoluteFilePath());
3857     setWorkflowOutputDir(os, testWorkflowOutputDir2.absoluteFilePath());
3858 
3859     //    20. Wait for all tasks finish. The scan task is supposed to finish before align tasks.
3860     //        Expected result:
3861     //          - The Workflow Designer is in the dashboards view mode.
3862     //          - There are 4 dashboard tabs.
3863     //            Their names are "Align sequence with MUSCLE 2",
3864     //                            "Extract consensus as sequence 1",
3865     //                            "Extract consensus as sequence 2",
3866     //                            "Align sequence with MUSCLE 1".
3867     //          - The "Align sequence with MUSCLE 2" dashboard is active.
3868     //          - The "Dashboards manager" button on the toolbar is active.
3869     GTUtilsTaskTreeView::waitTaskFinished(os, 600000);
3870 
3871     viewSwitchButton = qobject_cast<QAbstractButton *>(
3872         GTToolbar::getWidgetForActionTooltip(os,
3873                                              GTToolbar::getToolbar(os,
3874                                                                    MWTOOLBAR_ACTIVEMDI),
3875                                              "Show workflow"));
3876     CHECK_SET_ERR(nullptr != viewSwitchButton, "'To Workflow Designer' is nullptr");
3877     CHECK_SET_ERR(viewSwitchButton->isVisible(), "View switch button is unexpectedly invisible");
3878     CHECK_SET_ERR(viewSwitchButton->isEnabled(), "View switch button is unexpectedly disabled");
3879 
3880     QString expectedButtonText = "To Workflow Designer";
3881     QString actualButtonText = viewSwitchButton->text();
3882     CHECK_SET_ERR(expectedButtonText == actualButtonText,
3883                   QString("View switch button has an unexpected text: expected '%1', got '%2'")
3884                       .arg(expectedButtonText)
3885                       .arg(actualButtonText));
3886 
3887     coreLog.info("Trying get GTUtilsDashboard::getTabWidget(os)");
3888     QTabWidget *dashboardsView = GTUtilsDashboard::getTabWidget(os);
3889     CHECK_SET_ERR(nullptr != dashboardsView, "Dashboards view is nullptr");
3890     coreLog.info("Successfully got GTUtilsDashboard::getTabWidget(os)");
3891 
3892     int expectedTabsCount = 4;
3893     int actualTabsCount = dashboardsView->count();
3894     CHECK_SET_ERR(expectedTabsCount == actualTabsCount,
3895                   QString("There is an incorrect count of tabs in the Dashboard View: expected %1, got %2")
3896                       .arg(expectedTabsCount)
3897                       .arg(actualTabsCount));
3898 
3899     int expectedActiveTabIndex = 0;
3900     int actualActiveTabIndex = dashboardsView->currentIndex();
3901     CHECK_SET_ERR(expectedActiveTabIndex == actualActiveTabIndex,
3902                   QString("There is an incorrect active tab: expected index is %1, actual index is %2")
3903                       .arg(expectedActiveTabIndex)
3904                       .arg(actualActiveTabIndex));
3905 
3906     QString expectedTabName = "Align sequences with MUSCLE 2";
3907     QString actualTabName = GTUtilsDashboard::getDashboardName(os, expectedActiveTabIndex);
3908     CHECK_SET_ERR(expectedTabName == actualTabName,
3909                   QString("Active dashboard has an unexpected name: expect '%1', got '%2'")
3910                       .arg(expectedTabName)
3911                       .arg(actualTabName));
3912 
3913     QStringList outputFiles = GTUtilsDashboard::getOutputFiles(os);
3914     CHECK_SET_ERR(!outputFiles.isEmpty(), "Active dashboard is not displayed properly");
3915 
3916     QWidget *dashboardsManagerButton = GTToolbar::getWidgetForActionTooltip(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Dashboards manager");
3917     CHECK_SET_ERR(nullptr != dashboardsManagerButton, "'Dashboards manager' is nullptr");
3918     CHECK_SET_ERR(dashboardsManagerButton->isEnabled(), "'Dashboards manager' button is unexpectedly disabled");
3919 
3920     //    21. Click to the "Dashboards manager" button on the toolbar.
3921     //    Expected result: the "Dashboards Manager" dialog appears. It contains four items, all of them are checked. Their names are "Extract consensus as sequence 1", "Extract consensus as sequence 2", "Align sequence with MUSCLE 1", "Align sequence with MUSCLE 2".
3922     //    22. Cancel the dialog
3923     class Scenario : public CustomScenario {
3924     public:
3925         static bool sorting(const QPair<QString, bool> &e1, const QPair<QString, bool> &e2) {
3926             if (e1.first < e2.first)
3927                 return true;
3928             return false;
3929         }
3930 
3931         void run(HI::GUITestOpStatus &os) override {
3932             QWidget *dialog = GTWidget::getActiveModalWidget(os);
3933             QList<QPair<QString, bool>> expectedDashboardsState({qMakePair(QString("Align sequences with MUSCLE 1"), true),
3934                                                                  qMakePair(QString("Align sequences with MUSCLE 2"), true),
3935                                                                  qMakePair(QString("Extract consensus as sequence 1"), true),
3936                                                                  qMakePair(QString("Extract consensus as sequence 2"), true)});
3937             std::sort(expectedDashboardsState.begin(), expectedDashboardsState.end(), sorting);
3938 
3939             QList<QPair<QString, bool>> actualDashboardsState = DashboardsManagerDialogFiller::getDashboardsState(os);
3940             std::sort(actualDashboardsState.begin(), actualDashboardsState.end(), sorting);
3941 
3942             CHECK_SET_ERR(expectedDashboardsState.size() == actualDashboardsState.size(),
3943                           QString("Expected dashboards count is not equal to the actual dashboards list size: expected %1, got %2")
3944                               .arg(expectedDashboardsState.size())
3945                               .arg(actualDashboardsState.size()));
3946 
3947             for (int i = 0; i < expectedDashboardsState.size(); ++i) {
3948                 const QString expectedDashboardName = expectedDashboardsState[i].first;
3949                 const QString actualDashboardName = actualDashboardsState[i].first;
3950                 CHECK_SET_ERR(expectedDashboardName == actualDashboardName,
3951                               QString("Dashboard number %1 has an unexpected name: expected '%2', got '%3'")
3952                                   .arg(i)
3953                                   .arg(expectedDashboardName)
3954                                   .arg(actualDashboardName));
3955 
3956                 const bool expectedDashboardState = expectedDashboardsState[i].second;
3957                 const bool actualDashboardState = actualDashboardsState[i].second;
3958                 CHECK_SET_ERR(expectedDashboardState == actualDashboardState,
3959                               QString("Dashboard number %1 has an unexpected state: it should be %2, but it is '%3'")
3960                                   .arg(i)
3961                                   .arg(expectedDashboardState ? "visible" : "invisible")
3962                                   .arg(actualDashboardState ? "visible" : "invisible"));
3963             }
3964 
3965             GTUtilsDialog::clickButtonBox(os, dialog, QDialogButtonBox::Cancel);
3966         }
3967     };
3968 
3969     GTUtilsDialog::waitForDialog(os, new DashboardsManagerDialogFiller(os, new Scenario()));
3970     GTWidget::click(os, dashboardsManagerButton);
3971 
3972     //    23. Switch to the first Workflow Designer.
3973     //    Expected result:
3974     //     - The Workflow Designer is in the dashboards view mode.
3975     //     - There are four dashboard tabs. Their names are "Align sequence with MUSCLE 1", "Extract consensus as sequence 1", "Extract consensus as sequence 2", "Align sequence with MUSCLE 2".
3976     //     - The "Align sequence with MUSCLE 1" dashboard is active.
3977     //     - The "Dashboards manager" button on the toolbar is active.
3978     coreLog.info(QString("Try to switch to tab %1(%2)")
3979                      .arg(tabIndex1)
3980                      .arg(GTUtilsMdi::getTabBar(os)->tabText(tabIndex1)));
3981     GTUtilsMdi::clickTab(os, tabIndex1);
3982     GTUtilsTaskTreeView::waitTaskFinished(os);
3983 
3984     viewSwitchButton = qobject_cast<QAbstractButton *>(
3985         GTToolbar::getWidgetForActionTooltip(os,
3986                                              GTToolbar::getToolbar(os,
3987                                                                    MWTOOLBAR_ACTIVEMDI),
3988                                              "Show workflow"));
3989     CHECK_SET_ERR(nullptr != viewSwitchButton, "'To Workflow Designer' is nullptr");
3990     CHECK_SET_ERR(viewSwitchButton->isVisible(), "View switch button is unexpectedly invisible");
3991     CHECK_SET_ERR(viewSwitchButton->isEnabled(), "View switch button is unexpectedly disabled");
3992 
3993     expectedButtonText = "To Workflow Designer";
3994     actualButtonText = viewSwitchButton->text();
3995     CHECK_SET_ERR(expectedButtonText == actualButtonText,
3996                   QString("View switch button has an unexpected text: expected '%1', got '%2'")
3997                       .arg(expectedButtonText)
3998                       .arg(actualButtonText));
3999 
4000     coreLog.info("Trying get GTUtilsDashboard::getTabWidget(os)");
4001     dashboardsView = GTUtilsDashboard::getTabWidget(os);
4002     CHECK_SET_ERR(nullptr != dashboardsView, "Dashboards view is nullptr");
4003     coreLog.info("Successfully got GTUtilsDashboard::getTabWidget(os)");
4004 
4005     expectedTabsCount = 4;
4006     actualTabsCount = dashboardsView->count();
4007     CHECK_SET_ERR(expectedTabsCount == actualTabsCount,
4008                   QString("There is an incorrect count of tabs in the Dashboard View: expected %1, got %2")
4009                       .arg(expectedTabsCount)
4010                       .arg(actualTabsCount));
4011 
4012     expectedActiveTabIndex = 0;
4013     actualActiveTabIndex = dashboardsView->currentIndex();
4014     CHECK_SET_ERR(expectedActiveTabIndex == actualActiveTabIndex,
4015                   QString("There is an incorrect active tab: expected index is %1, actual index is %2")
4016                       .arg(expectedActiveTabIndex)
4017                       .arg(actualActiveTabIndex));
4018 
4019     expectedTabName = "Align sequences with MUSCLE 1";
4020     actualTabName = GTUtilsDashboard::getDashboardName(os, expectedActiveTabIndex);
4021     CHECK_SET_ERR(expectedTabName == actualTabName,
4022                   QString("Active dashboard has an unexpected name: expect '%1', got '%2'")
4023                       .arg(expectedTabName)
4024                       .arg(actualTabName));
4025 
4026     outputFiles = GTUtilsDashboard::getOutputFiles(os);
4027     CHECK_SET_ERR(!outputFiles.isEmpty(), "Active dashboard is not displayed properly");
4028 
4029     dashboardsManagerButton = GTToolbar::getWidgetForActionTooltip(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Dashboards manager");
4030     CHECK_SET_ERR(nullptr != dashboardsManagerButton, "'Dashboards manager' is nullptr");
4031     CHECK_SET_ERR(dashboardsManagerButton->isEnabled(), "'Dashboards manager' button is unexpectedly disabled");
4032 
4033     //    24. Click to the "Dashboards manager" button on the toolbar.
4034     //    Expected result:
4035     //     - the "Dashboards Manager" dialog appears.
4036     //       It contains 4 items, all of them are checked.
4037     //       Their names are "Extract consensus as sequence 1", "Extract consensus as sequence 2", "Align sequence with MUSCLE 1", "Align sequence with MUSCLE 2".
4038     //    25. Cancel the dialog
4039     GTUtilsDialog::waitForDialog(os, new DashboardsManagerDialogFiller(os, new Scenario()));
4040     GTWidget::click(os, dashboardsManagerButton);
4041 
4042     //    26. Switch to the third Workflow Designer.
4043     //    Expected result:
4044     //     - The Workflow Designer is in the dashboard view mode.
4045     //     - The "Dashboards manager" button on the toolbar is active.
4046     //     - There are four dashboard tabs. Their names are "Extract consensus as sequence 1", "Extract consensus as sequence 2", "Align sequence with MUSCLE 1", "Align sequence with MUSCLE 2" (warning: two last tabs can be swapped, it depends on the task finish order, it is a correct situation).
4047     //     - The "Extract consensus as sequence 2" dashboard is active.
4048     coreLog.info(QString("Try to switch to tab %1(%2)")
4049                      .arg(tabIndex3)
4050                      .arg(GTUtilsMdi::getTabBar(os)->tabText(tabIndex3)));
4051     GTUtilsMdi::clickTab(os, tabIndex3);
4052     GTUtilsTaskTreeView::waitTaskFinished(os);
4053 
4054     viewSwitchButton = qobject_cast<QAbstractButton *>(
4055         GTToolbar::getWidgetForActionTooltip(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Show workflow"));
4056     CHECK_SET_ERR(nullptr != viewSwitchButton, "'To Workflow Designer' is nullptr");
4057     CHECK_SET_ERR(viewSwitchButton->isVisible(), "View switch button is unexpectedly invisible");
4058     CHECK_SET_ERR(viewSwitchButton->isEnabled(), "View switch button is unexpectedly disabled");
4059 
4060     expectedButtonText = "To Workflow Designer";
4061     actualButtonText = viewSwitchButton->text();
4062     CHECK_SET_ERR(expectedButtonText == actualButtonText,
4063                   QString("View switch button has an unexpected text: expected '%1', got '%2'")
4064                       .arg(expectedButtonText)
4065                       .arg(actualButtonText));
4066 
4067     coreLog.info("Trying get GTUtilsDashboard::getTabWidget(os)");
4068     dashboardsView = GTUtilsDashboard::getTabWidget(os);
4069     CHECK_SET_ERR(nullptr != dashboardsView, "Dashboards view is nullptr");
4070     coreLog.info("Successfully got GTUtilsDashboard::getTabWidget(os)");
4071 
4072     expectedTabsCount = 4;
4073     actualTabsCount = dashboardsView->count();
4074     CHECK_SET_ERR(expectedTabsCount == actualTabsCount,
4075                   QString("There is an incorrect count of tabs in the Dashboard View: expected %1, got %2")
4076                       .arg(expectedTabsCount)
4077                       .arg(actualTabsCount));
4078 
4079     actualActiveTabIndex = dashboardsView->currentIndex();
4080     CHECK_SET_ERR(actualActiveTabIndex >= 0 && actualActiveTabIndex < expectedTabsCount,
4081                   QString("There is an incorrect active tab: expected index is %1, actual index is %2")
4082                       .arg(expectedActiveTabIndex)
4083                       .arg(actualActiveTabIndex));
4084 
4085     expectedTabName = "Extract consensus as sequence 2";
4086     actualTabName = GTUtilsDashboard::getDashboardName(os, actualActiveTabIndex);
4087     CHECK_SET_ERR(expectedTabName == actualTabName,
4088                   QString("Active dashboard has an unexpected name: expect '%1', got '%2'")
4089                       .arg(expectedTabName)
4090                       .arg(actualTabName));
4091 
4092     outputFiles = GTUtilsDashboard::getOutputFiles(os);
4093     CHECK_SET_ERR(!outputFiles.isEmpty(), "Active dashboard is not displayed properly");
4094 
4095     dashboardsManagerButton = GTToolbar::getWidgetForActionTooltip(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Dashboards manager");
4096     CHECK_SET_ERR(nullptr != dashboardsManagerButton, "'Dashboards manager' is nullptr");
4097     CHECK_SET_ERR(dashboardsManagerButton->isEnabled(), "'Dashboards manager' button is unexpectedly disabled");
4098 
4099     //    27. Click to the "Dashboards manager" button on the toolbar.
4100     //    Expected result:
4101     //     - the "Dashboards Manager" dialog appears.
4102     //     - It contains two items, both of them are checked.
4103     //     - Their names are "Align sequence with MUSCLE 1" and "Align sequence with MUSCLE 2".
4104     //    28. Cancel the dialog.
4105     GTUtilsDialog::waitForDialog(os, new DashboardsManagerDialogFiller(os, new Scenario()));
4106     GTWidget::click(os, dashboardsManagerButton);
4107 }
4108 
GUI_TEST_CLASS_DEFINITION(output_dir_scanning_test_0007)4109 GUI_TEST_CLASS_DEFINITION(output_dir_scanning_test_0007) {
4110     //    1. Set "_common_data/workflow/dashboard/workflow_outputs/two_visible_two_invisible" as workflow output folder in the "Application Settings".
4111     const QFileInfo originalWorkflowOutputDir = testDir + "_common_data/workflow/dashboard/workflow_outputs/two_visible_two_invisible";
4112     const QFileInfo testWorkflowOutputDir = sandBoxDir + "two_visible_two_invisible";
4113     GTFile::copyDir(os, originalWorkflowOutputDir.absoluteFilePath(), testWorkflowOutputDir.absoluteFilePath());
4114     setWorkflowOutputDir(os, testWorkflowOutputDir.absoluteFilePath());
4115 
4116     //    2. Wait for scan task finish.
4117     GTUtilsTaskTreeView::waitTaskFinished(os);
4118 
4119     //    3. Open Workflow Designer.
4120     GTUtilsWorkflowDesigner::openWorkflowDesigner(os);
4121     GTUtilsTaskTreeView::waitTaskFinished(os);
4122     int tabIndex1 = GTUtilsMdi::getCurrentTab(os);
4123 
4124     //    4. Open "Align sequence with MUSCLE" sample.
4125     GTUtilsWorkflowDesigner::addSample(os, "Align sequences with MUSCLE", GTUtilsMdi::activeWindow(os));
4126 
4127     //    5. Cancel the wizard.
4128     GTKeyboardDriver::keyClick(Qt::Key_Escape);
4129 
4130     //    6. Click to the "Read alignment" element.
4131     GTMouseDriver::moveTo(GTUtilsWorkflowDesigner::getItemCenter(os, "Read alignment"));
4132     GTMouseDriver::click();
4133 
4134     //    7. Add "_common_data/clustal/200_sequences.aln" file to "Dataset 1" dataset.
4135     GTUtilsWorkflowDesigner::setDatasetInputFile(os, testDir + "_common_data/clustal/100_sequences.aln");
4136 
4137     //    8. Open Workflow Designer.
4138     GTUtilsWorkflowDesigner::openWorkflowDesigner(os);
4139     GTUtilsTaskTreeView::waitTaskFinished(os);
4140     int tabIndex2 = GTUtilsMdi::getCurrentTab(os);
4141 
4142     //    9. Open "Align sequence with MUSCLE" sample.
4143     GTUtilsWorkflowDesigner::addSample(os, "Align sequences with MUSCLE", GTUtilsMdi::activeWindow(os));
4144 
4145     //    10. Cancel the wizard.
4146     GTKeyboardDriver::keyClick(Qt::Key_Escape);
4147 
4148     //    11. Click to the "Read alignment" element.
4149     GTMouseDriver::moveTo(GTUtilsWorkflowDesigner::getItemCenter(os, "Read alignment"));
4150     GTMouseDriver::click();
4151 
4152     //    12. Add "_common_data/clustal/200_sequences.aln" file to "Dataset 1" dataset.
4153     GTUtilsWorkflowDesigner::setDatasetInputFile(os, testDir + "_common_data/clustal/100_sequences.aln");
4154 
4155     //    13. Open Workflow Designer.
4156     GTUtilsWorkflowDesigner::openWorkflowDesigner(os);
4157     int tabIndex3 = GTUtilsMdi::getCurrentTab(os);
4158     GTUtilsTaskTreeView::waitTaskFinished(os);
4159 
4160     //    14. Click to the "Go to Dashboards" button on the toolbar.
4161     QAbstractButton *viewSwitchButton = qobject_cast<QAbstractButton *>(
4162         GTToolbar::getWidgetForActionTooltip(os,
4163                                              GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI),
4164                                              "Show dashboard"));
4165     CHECK_SET_ERR(nullptr != viewSwitchButton, "'Go to Dashboards' is nullptr");
4166     CHECK_SET_ERR(viewSwitchButton->isVisible(), "View switch button is unexpectedly invisible");
4167     CHECK_SET_ERR(viewSwitchButton->isEnabled(), "View switch button is unexpectedly disabled");
4168     GTWidget::click(os, viewSwitchButton);
4169 
4170     //    15. Switch to first Workflow Designer.
4171     coreLog.info(QString("Try to switch to tab %1(%2)")
4172                      .arg(tabIndex1)
4173                      .arg(GTUtilsMdi::getTabBar(os)->tabText(tabIndex1)));
4174     GTUtilsMdi::clickTab(os, tabIndex1);
4175 
4176     //    16. Launch the workflow. Do not wait for the task finish.
4177     coreLog.info("Try to start workflow #1");
4178     GTUtilsWorkflowDesigner::runWorkflow(os);
4179     coreLog.info("It seems that workflow was started");
4180 
4181     //    17. Switch to the second Workflow Designer.
4182     coreLog.info(QString("Try to switch to tab %1(%2)")
4183                      .arg(tabIndex2)
4184                      .arg(GTUtilsMdi::getTabBar(os)->tabText(tabIndex2)));
4185     GTUtilsMdi::clickTab(os, tabIndex2);
4186 
4187     //    18. Launch the workflow. Do not wait for the task finish.
4188     coreLog.info("Try to start workflow #2");
4189     GTUtilsWorkflowDesigner::runWorkflow(os);
4190     coreLog.info("It seems that workflow was started");
4191 
4192     //    19. Set "_common_data/workflow/dashboard/workflow_outputs/one_visible_one_invisible" as workflow output folder in the "Application Settings".
4193     const QFileInfo originalWorkflowOutputDir2 = testDir + "_common_data/workflow/dashboard/workflow_outputs/one_visible_one_invisible";
4194     const QFileInfo testWorkflowOutputDir2 = sandBoxDir + "one_visible_one_invisible";
4195     GTFile::copyDir(os, originalWorkflowOutputDir2.absoluteFilePath(), testWorkflowOutputDir2.absoluteFilePath());
4196     setWorkflowOutputDir(os, testWorkflowOutputDir2.absoluteFilePath());
4197 
4198     //    20. Wait for all tasks finish. The scan task is supposed to finish before align tasks.
4199     //        Expected result:
4200     //          - The Workflow Designer is in the dashboards view mode.
4201     //          - There are 3 dashboard tabs.
4202     //            Their names are "Align sequence with MUSCLE 2",
4203     //                            "Extract consensus as sequence 2",
4204     //                            "Align sequence with MUSCLE 1".
4205     //          - The "Align sequence with MUSCLE 2" dashboard is active.
4206     //          - The "Dashboards manager" button on the toolbar is active.
4207     GTUtilsTaskTreeView::waitTaskFinished(os, 600000);
4208 
4209     viewSwitchButton = qobject_cast<QAbstractButton *>(
4210         GTToolbar::getWidgetForActionTooltip(os,
4211                                              GTToolbar::getToolbar(os,
4212                                                                    MWTOOLBAR_ACTIVEMDI),
4213                                              "Show workflow"));
4214     CHECK_SET_ERR(nullptr != viewSwitchButton, "'To Workflow Designer' is nullptr");
4215     CHECK_SET_ERR(viewSwitchButton->isVisible(), "View switch button is unexpectedly invisible");
4216     CHECK_SET_ERR(viewSwitchButton->isEnabled(), "View switch button is unexpectedly disabled");
4217 
4218     QString expectedButtonText = "To Workflow Designer";
4219     QString actualButtonText = viewSwitchButton->text();
4220     CHECK_SET_ERR(expectedButtonText == actualButtonText,
4221                   QString("View switch button has an unexpected text: expected '%1', got '%2'")
4222                       .arg(expectedButtonText)
4223                       .arg(actualButtonText));
4224 
4225     coreLog.info("Trying get GTUtilsDashboard::getTabWidget(os)");
4226     QTabWidget *dashboardsView = GTUtilsDashboard::getTabWidget(os);
4227     CHECK_SET_ERR(nullptr != dashboardsView, "Dashboards view is nullptr");
4228     coreLog.info("Successfully got GTUtilsDashboard::getTabWidget(os)");
4229 
4230     int expectedTabsCount = 3;
4231     int actualTabsCount = dashboardsView->count();
4232     CHECK_SET_ERR(expectedTabsCount == actualTabsCount,
4233                   QString("There is an incorrect count of tabs in the Dashboard View: expected %1, got %2")
4234                       .arg(expectedTabsCount)
4235                       .arg(actualTabsCount));
4236 
4237     int expectedActiveTabIndex = 0;
4238     int actualActiveTabIndex = dashboardsView->currentIndex();
4239     CHECK_SET_ERR(expectedActiveTabIndex == actualActiveTabIndex,
4240                   QString("There is an incorrect active tab: expected index is %1, actual index is %2")
4241                       .arg(expectedActiveTabIndex)
4242                       .arg(actualActiveTabIndex));
4243 
4244     QString expectedTabName = "Align sequences with MUSCLE 2";
4245     QString actualTabName = GTUtilsDashboard::getDashboardName(os, expectedActiveTabIndex);
4246     CHECK_SET_ERR(expectedTabName == actualTabName,
4247                   QString("Active dashboard has an unexpected name: expect '%1', got '%2'")
4248                       .arg(expectedTabName)
4249                       .arg(actualTabName));
4250 
4251     QStringList outputFiles = GTUtilsDashboard::getOutputFiles(os);
4252     CHECK_SET_ERR(!outputFiles.isEmpty(), "Active dashboard is not displayed properly");
4253 
4254     QWidget *dashboardsManagerButton = GTToolbar::getWidgetForActionTooltip(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Dashboards manager");
4255     CHECK_SET_ERR(nullptr != dashboardsManagerButton, "'Dashboards manager' is nullptr");
4256     CHECK_SET_ERR(dashboardsManagerButton->isEnabled(), "'Dashboards manager' button is unexpectedly disabled");
4257 
4258     //    21. Click to the "Dashboards manager" button on the toolbar.
4259     //    Expected result: the "Dashboards Manager" dialog appears. It contains 3 items, not all of them are checked. Their names are "Extract consensus as sequence 1", "Extract consensus as sequence 2", "Align sequence with MUSCLE 1", "Align sequence with MUSCLE 2".
4260     //    22. Cancel the dialog
4261     class Scenario : public CustomScenario {
4262     public:
4263         static bool sorting(const QPair<QString, bool> &e1, const QPair<QString, bool> &e2) {
4264             if (e1.first < e2.first)
4265                 return true;
4266             return false;
4267         }
4268 
4269         void run(HI::GUITestOpStatus &os) override {
4270             QWidget *dialog = GTWidget::getActiveModalWidget(os);
4271             QList<QPair<QString, bool>> expectedDashboardsState({qMakePair(QString("Align sequences with MUSCLE 1"), true),
4272                                                                  qMakePair(QString("Align sequences with MUSCLE 2"), true),
4273                                                                  qMakePair(QString("Extract consensus as sequence 1"), false),
4274                                                                  qMakePair(QString("Extract consensus as sequence 2"), true)});
4275             std::sort(expectedDashboardsState.begin(), expectedDashboardsState.end(), sorting);
4276 
4277             QList<QPair<QString, bool>> actualDashboardsState = DashboardsManagerDialogFiller::getDashboardsState(os);
4278             std::sort(actualDashboardsState.begin(), actualDashboardsState.end(), sorting);
4279 
4280             CHECK_SET_ERR(expectedDashboardsState.size() == actualDashboardsState.size(),
4281                           QString("Expected dashboards count is not equal to the actual dashboards list size: expected %1, got %2")
4282                               .arg(expectedDashboardsState.size())
4283                               .arg(actualDashboardsState.size()));
4284 
4285             for (int i = 0; i < expectedDashboardsState.size(); ++i) {
4286                 const QString expectedDashboardName = expectedDashboardsState[i].first;
4287                 const QString actualDashboardName = actualDashboardsState[i].first;
4288                 CHECK_SET_ERR(expectedDashboardName == actualDashboardName,
4289                               QString("Dashboard number %1 has an unexpected name: expected '%2', got '%3'")
4290                                   .arg(i)
4291                                   .arg(expectedDashboardName)
4292                                   .arg(actualDashboardName));
4293 
4294                 const bool expectedDashboardState = expectedDashboardsState[i].second;
4295                 const bool actualDashboardState = actualDashboardsState[i].second;
4296                 CHECK_SET_ERR(expectedDashboardState == actualDashboardState,
4297                               QString("Dashboard number %1 has an unexpected state: it should be %2, but it is '%3'")
4298                                   .arg(i)
4299                                   .arg(expectedDashboardState ? "visible" : "invisible")
4300                                   .arg(actualDashboardState ? "visible" : "invisible"));
4301             }
4302 
4303             GTUtilsDialog::clickButtonBox(os, dialog, QDialogButtonBox::Cancel);
4304         }
4305     };
4306 
4307     GTUtilsDialog::waitForDialog(os, new DashboardsManagerDialogFiller(os, new Scenario()));
4308     GTWidget::click(os, dashboardsManagerButton);
4309 
4310     //    23. Switch to the first Workflow Designer.
4311     //    Expected result:
4312     //     - The Workflow Designer is in the dashboards view mode.
4313     //     - There are 3 dashboard tabs. Their names are "Align sequence with MUSCLE 1", "Extract consensus as sequence 2", "Align sequence with MUSCLE 2".
4314     //     - The "Align sequence with MUSCLE 1" dashboard is active.
4315     //     - The "Dashboards manager" button on the toolbar is active.
4316     coreLog.info(QString("Try to switch to tab %1(%2)")
4317                      .arg(tabIndex1)
4318                      .arg(GTUtilsMdi::getTabBar(os)->tabText(tabIndex1)));
4319     GTUtilsMdi::clickTab(os, tabIndex1);
4320     GTUtilsTaskTreeView::waitTaskFinished(os);
4321 
4322     viewSwitchButton = qobject_cast<QAbstractButton *>(
4323         GTToolbar::getWidgetForActionTooltip(os,
4324                                              GTToolbar::getToolbar(os,
4325                                                                    MWTOOLBAR_ACTIVEMDI),
4326                                              "Show workflow"));
4327     CHECK_SET_ERR(nullptr != viewSwitchButton, "'To Workflow Designer' is nullptr");
4328     CHECK_SET_ERR(viewSwitchButton->isVisible(), "View switch button is unexpectedly invisible");
4329     CHECK_SET_ERR(viewSwitchButton->isEnabled(), "View switch button is unexpectedly disabled");
4330 
4331     expectedButtonText = "To Workflow Designer";
4332     actualButtonText = viewSwitchButton->text();
4333     CHECK_SET_ERR(expectedButtonText == actualButtonText,
4334                   QString("View switch button has an unexpected text: expected '%1', got '%2'")
4335                       .arg(expectedButtonText)
4336                       .arg(actualButtonText));
4337 
4338     coreLog.info("Trying get GTUtilsDashboard::getTabWidget(os)");
4339     dashboardsView = GTUtilsDashboard::getTabWidget(os);
4340     CHECK_SET_ERR(nullptr != dashboardsView, "Dashboards view is nullptr");
4341     coreLog.info("Successfully got GTUtilsDashboard::getTabWidget(os)");
4342 
4343     expectedTabsCount = 3;
4344     actualTabsCount = dashboardsView->count();
4345     CHECK_SET_ERR(expectedTabsCount == actualTabsCount,
4346                   QString("There is an incorrect count of tabs in the Dashboard View: expected %1, got %2")
4347                       .arg(expectedTabsCount)
4348                       .arg(actualTabsCount));
4349 
4350     expectedActiveTabIndex = 0;
4351     actualActiveTabIndex = dashboardsView->currentIndex();
4352     CHECK_SET_ERR(expectedActiveTabIndex == actualActiveTabIndex,
4353                   QString("There is an incorrect active tab: expected index is %1, actual index is %2")
4354                       .arg(expectedActiveTabIndex)
4355                       .arg(actualActiveTabIndex));
4356 
4357     expectedTabName = "Align sequences with MUSCLE 1";
4358     actualTabName = GTUtilsDashboard::getDashboardName(os, expectedActiveTabIndex);
4359     CHECK_SET_ERR(expectedTabName == actualTabName,
4360                   QString("Active dashboard has an unexpected name: expect '%1', got '%2'")
4361                       .arg(expectedTabName)
4362                       .arg(actualTabName));
4363 
4364     outputFiles = GTUtilsDashboard::getOutputFiles(os);
4365     CHECK_SET_ERR(!outputFiles.isEmpty(), "Active dashboard is not displayed properly");
4366 
4367     dashboardsManagerButton = GTToolbar::getWidgetForActionTooltip(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Dashboards manager");
4368     CHECK_SET_ERR(nullptr != dashboardsManagerButton, "'Dashboards manager' is nullptr");
4369     CHECK_SET_ERR(dashboardsManagerButton->isEnabled(), "'Dashboards manager' button is unexpectedly disabled");
4370 
4371     //    24. Click to the "Dashboards manager" button on the toolbar.
4372     //    Expected result:
4373     //     - the "Dashboards Manager" dialog appears.
4374     //       It contains 4 items, all of them are checked.
4375     //       Their names are "Extract consensus as sequence 1", "Extract consensus as sequence 2", "Align sequence with MUSCLE 1", "Align sequence with MUSCLE 2".
4376     //    25. Cancel the dialog
4377     GTUtilsDialog::waitForDialog(os, new DashboardsManagerDialogFiller(os, new Scenario()));
4378     GTWidget::click(os, dashboardsManagerButton);
4379 
4380     //    26. Switch to the third Workflow Designer.
4381     //    Expected result:
4382     //     - The Workflow Designer is in the dashboard view mode.
4383     //     - The "Dashboards manager" button on the toolbar is active.
4384     //     - There are 3 dashboard tabs. Their names are "Extract consensus as sequence 2", "Align sequence with MUSCLE 1", "Align sequence with MUSCLE 2" (warning: two last tabs can be swapped, it depends on the task finish order, it is a correct situation).
4385     //     - The "Extract consensus as sequence 2" dashboard is active.
4386     coreLog.info(QString("Try to switch to tab %1(%2)")
4387                      .arg(tabIndex3)
4388                      .arg(GTUtilsMdi::getTabBar(os)->tabText(tabIndex3)));
4389     GTUtilsMdi::clickTab(os, tabIndex3);
4390     GTUtilsTaskTreeView::waitTaskFinished(os);
4391 
4392     viewSwitchButton = qobject_cast<QAbstractButton *>(
4393         GTToolbar::getWidgetForActionTooltip(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Show workflow"));
4394     CHECK_SET_ERR(nullptr != viewSwitchButton, "'To Workflow Designer' is nullptr");
4395     CHECK_SET_ERR(viewSwitchButton->isVisible(), "View switch button is unexpectedly invisible");
4396     CHECK_SET_ERR(viewSwitchButton->isEnabled(), "View switch button is unexpectedly disabled");
4397 
4398     expectedButtonText = "To Workflow Designer";
4399     actualButtonText = viewSwitchButton->text();
4400     CHECK_SET_ERR(expectedButtonText == actualButtonText,
4401                   QString("View switch button has an unexpected text: expected '%1', got '%2'")
4402                       .arg(expectedButtonText)
4403                       .arg(actualButtonText));
4404 
4405     coreLog.info("Trying get GTUtilsDashboard::getTabWidget(os)");
4406     dashboardsView = GTUtilsDashboard::getTabWidget(os);
4407     CHECK_SET_ERR(nullptr != dashboardsView, "Dashboards view is nullptr");
4408     coreLog.info("Successfully got GTUtilsDashboard::getTabWidget(os)");
4409 
4410     expectedTabsCount = 3;
4411     actualTabsCount = dashboardsView->count();
4412     CHECK_SET_ERR(expectedTabsCount == actualTabsCount,
4413                   QString("There is an incorrect count of tabs in the Dashboard View: expected %1, got %2")
4414                       .arg(expectedTabsCount)
4415                       .arg(actualTabsCount));
4416 
4417     actualActiveTabIndex = dashboardsView->currentIndex();
4418     CHECK_SET_ERR(actualActiveTabIndex >= 0 && actualActiveTabIndex < expectedTabsCount,
4419                   QString("There is an incorrect active tab: expected index is %1, actual index is %2")
4420                       .arg(expectedActiveTabIndex)
4421                       .arg(actualActiveTabIndex));
4422 
4423     expectedTabName = "Extract consensus as sequence 2";
4424     actualTabName = GTUtilsDashboard::getDashboardName(os, actualActiveTabIndex);
4425     CHECK_SET_ERR(expectedTabName == actualTabName,
4426                   QString("Active dashboard has an unexpected name: expect '%1', got '%2'")
4427                       .arg(expectedTabName)
4428                       .arg(actualTabName));
4429 
4430     outputFiles = GTUtilsDashboard::getOutputFiles(os);
4431     CHECK_SET_ERR(!outputFiles.isEmpty(), "Active dashboard is not displayed properly");
4432 
4433     dashboardsManagerButton = GTToolbar::getWidgetForActionTooltip(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Dashboards manager");
4434     CHECK_SET_ERR(nullptr != dashboardsManagerButton, "'Dashboards manager' is nullptr");
4435     CHECK_SET_ERR(dashboardsManagerButton->isEnabled(), "'Dashboards manager' button is unexpectedly disabled");
4436 
4437     //    27. Click to the "Dashboards manager" button on the toolbar.
4438     //    Expected result:
4439     //     - the "Dashboards Manager" dialog appears.
4440     //     - It contains 4 items, not all of them are checked.
4441     //     - Their names are "Extract consensus as sequence 1", "Extract consensus as sequence 2", "Align sequence with MUSCLE 1" and "Align sequence with MUSCLE 2".
4442     //    28. Cancel the dialog.
4443     GTUtilsDialog::waitForDialog(os, new DashboardsManagerDialogFiller(os, new Scenario()));
4444     GTWidget::click(os, dashboardsManagerButton);
4445 }
4446 
GUI_TEST_CLASS_DEFINITION(output_dir_scanning_test_0008)4447 GUI_TEST_CLASS_DEFINITION(output_dir_scanning_test_0008) {
4448     //    1. Set "_common_data/workflow/dashboard/workflow_outputs/two_visible_two_invisible" as workflow output folder in the "Application Settings".
4449     const QFileInfo originalWorkflowOutputDir = testDir + "_common_data/workflow/dashboard/workflow_outputs/two_visible_two_invisible";
4450     const QFileInfo testWorkflowOutputDir = sandBoxDir + "two_visible_two_invisible";
4451     GTFile::copyDir(os, originalWorkflowOutputDir.absoluteFilePath(), testWorkflowOutputDir.absoluteFilePath());
4452     setWorkflowOutputDir(os, testWorkflowOutputDir.absoluteFilePath());
4453 
4454     //    2. Wait for scan task finish.
4455     GTUtilsTaskTreeView::waitTaskFinished(os);
4456 
4457     //    3. Open Workflow Designer.
4458     GTUtilsWorkflowDesigner::openWorkflowDesigner(os);
4459     GTUtilsTaskTreeView::waitTaskFinished(os);
4460     int tabIndex1 = GTUtilsMdi::getCurrentTab(os);
4461 
4462     //    4. Open "Align sequence with MUSCLE" sample.
4463     GTUtilsWorkflowDesigner::addSample(os, "Align sequences with MUSCLE", GTUtilsMdi::activeWindow(os));
4464 
4465     //    5. Cancel the wizard.
4466     GTKeyboardDriver::keyClick(Qt::Key_Escape);
4467 
4468     //    6. Click to the "Read alignment" element.
4469     GTMouseDriver::moveTo(GTUtilsWorkflowDesigner::getItemCenter(os, "Read alignment"));
4470     GTMouseDriver::click();
4471 
4472     //    7. Add "_common_data/clustal/200_sequences.aln" file to "Dataset 1" dataset.
4473     GTUtilsWorkflowDesigner::setDatasetInputFile(os, testDir + "_common_data/clustal/100_sequences.aln");
4474 
4475     //    8. Open Workflow Designer.
4476     GTUtilsWorkflowDesigner::openWorkflowDesigner(os);
4477     GTUtilsTaskTreeView::waitTaskFinished(os);
4478     int tabIndex2 = GTUtilsMdi::getCurrentTab(os);
4479 
4480     //    9. Open "Align sequence with MUSCLE" sample.
4481     GTUtilsWorkflowDesigner::addSample(os, "Align sequences with MUSCLE", GTUtilsMdi::activeWindow(os));
4482 
4483     //    10. Cancel the wizard.
4484     GTKeyboardDriver::keyClick(Qt::Key_Escape);
4485 
4486     //    11. Click to the "Read alignment" element.
4487     GTMouseDriver::moveTo(GTUtilsWorkflowDesigner::getItemCenter(os, "Read alignment"));
4488     GTMouseDriver::click();
4489 
4490     //    12. Add "_common_data/clustal/200_sequences.aln" file to "Dataset 1" dataset.
4491     GTUtilsWorkflowDesigner::setDatasetInputFile(os, testDir + "_common_data/clustal/100_sequences.aln");
4492 
4493     //    13. Open Workflow Designer.
4494     GTUtilsWorkflowDesigner::openWorkflowDesigner(os);
4495     int tabIndex3 = GTUtilsMdi::getCurrentTab(os);
4496     GTUtilsTaskTreeView::waitTaskFinished(os);
4497 
4498     //    14. Click to the "Go to Dashboards" button on the toolbar.
4499     QAbstractButton *viewSwitchButton = qobject_cast<QAbstractButton *>(
4500         GTToolbar::getWidgetForActionTooltip(os,
4501                                              GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI),
4502                                              "Show dashboard"));
4503     CHECK_SET_ERR(nullptr != viewSwitchButton, "'Go to Dashboards' is nullptr");
4504     CHECK_SET_ERR(viewSwitchButton->isVisible(), "View switch button is unexpectedly invisible");
4505     CHECK_SET_ERR(viewSwitchButton->isEnabled(), "View switch button is unexpectedly disabled");
4506     GTWidget::click(os, viewSwitchButton);
4507 
4508     //    15. Switch to first Workflow Designer.
4509     coreLog.info(QString("Try to switch to tab %1(%2)")
4510                      .arg(tabIndex1)
4511                      .arg(GTUtilsMdi::getTabBar(os)->tabText(tabIndex1)));
4512     GTUtilsMdi::clickTab(os, tabIndex1);
4513 
4514     //    16. Launch the workflow. Do not wait for the task finish.
4515     coreLog.info("Try to start workflow #1");
4516     GTUtilsWorkflowDesigner::runWorkflow(os);
4517     coreLog.info("It seems that workflow was started");
4518 
4519     //    17. Switch to the second Workflow Designer.
4520     coreLog.info(QString("Try to switch to tab %1(%2)")
4521                      .arg(tabIndex2)
4522                      .arg(GTUtilsMdi::getTabBar(os)->tabText(tabIndex2)));
4523     GTUtilsMdi::clickTab(os, tabIndex2);
4524 
4525     //    18. Launch the workflow. Do not wait for the task finish.
4526     coreLog.info("Try to start workflow #2");
4527     GTUtilsWorkflowDesigner::runWorkflow(os);
4528     coreLog.info("It seems that workflow was started");
4529 
4530     //    19. Set "_common_data/workflow/dashboard/workflow_outputs/two_invisible_dashboards" as workflow output folder in the "Application Settings".
4531     const QFileInfo originalWorkflowOutputDir2 = testDir + "_common_data/workflow/dashboard/workflow_outputs/two_invisible_dashboards";
4532     const QFileInfo testWorkflowOutputDir2 = sandBoxDir + "two_invisible_dashboards";
4533     GTFile::copyDir(os, originalWorkflowOutputDir2.absoluteFilePath(), testWorkflowOutputDir2.absoluteFilePath());
4534     setWorkflowOutputDir(os, testWorkflowOutputDir2.absoluteFilePath());
4535 
4536     //    20. Wait for all tasks finish. The scan task is supposed to finish before align tasks.
4537     //        Expected result:
4538     //          - The Workflow Designer is in the dashboards view mode.
4539     //          - There are 2 dashboard tabs.
4540     //            Their names are "Align sequence with MUSCLE 2",
4541     //                            "Align sequence with MUSCLE 1".
4542     //          - The "Align sequence with MUSCLE 2" dashboard is active.
4543     //          - The "Dashboards manager" button on the toolbar is active.
4544     GTUtilsTaskTreeView::waitTaskFinished(os, 600000);
4545 
4546     viewSwitchButton = qobject_cast<QAbstractButton *>(
4547         GTToolbar::getWidgetForActionTooltip(os,
4548                                              GTToolbar::getToolbar(os,
4549                                                                    MWTOOLBAR_ACTIVEMDI),
4550                                              "Show workflow"));
4551     CHECK_SET_ERR(nullptr != viewSwitchButton, "'To Workflow Designer' is nullptr");
4552     CHECK_SET_ERR(viewSwitchButton->isVisible(), "View switch button is unexpectedly invisible");
4553     CHECK_SET_ERR(viewSwitchButton->isEnabled(), "View switch button is unexpectedly disabled");
4554 
4555     QString expectedButtonText = "To Workflow Designer";
4556     QString actualButtonText = viewSwitchButton->text();
4557     CHECK_SET_ERR(expectedButtonText == actualButtonText,
4558                   QString("View switch button has an unexpected text: expected '%1', got '%2'")
4559                       .arg(expectedButtonText)
4560                       .arg(actualButtonText));
4561 
4562     coreLog.info("Trying get GTUtilsDashboard::getTabWidget(os)");
4563     QTabWidget *dashboardsView = GTUtilsDashboard::getTabWidget(os);
4564     CHECK_SET_ERR(nullptr != dashboardsView, "Dashboards view is nullptr");
4565     coreLog.info("Successfully got GTUtilsDashboard::getTabWidget(os)");
4566 
4567     int expectedTabsCount = 2;
4568     int actualTabsCount = dashboardsView->count();
4569     CHECK_SET_ERR(expectedTabsCount == actualTabsCount,
4570                   QString("There is an incorrect count of tabs in the Dashboard View: expected %1, got %2")
4571                       .arg(expectedTabsCount)
4572                       .arg(actualTabsCount));
4573 
4574     int expectedActiveTabIndex = 0;
4575     int actualActiveTabIndex = dashboardsView->currentIndex();
4576     CHECK_SET_ERR(expectedActiveTabIndex == actualActiveTabIndex,
4577                   QString("There is an incorrect active tab: expected index is %1, actual index is %2")
4578                       .arg(expectedActiveTabIndex)
4579                       .arg(actualActiveTabIndex));
4580 
4581     QString expectedTabName = "Align sequences with MUSCLE 2";
4582     QString actualTabName = GTUtilsDashboard::getDashboardName(os, expectedActiveTabIndex);
4583     CHECK_SET_ERR(expectedTabName == actualTabName,
4584                   QString("Active dashboard has an unexpected name: expect '%1', got '%2'")
4585                       .arg(expectedTabName)
4586                       .arg(actualTabName));
4587 
4588     QStringList outputFiles = GTUtilsDashboard::getOutputFiles(os);
4589     CHECK_SET_ERR(!outputFiles.isEmpty(), "Active dashboard is not displayed properly");
4590 
4591     QWidget *dashboardsManagerButton = GTToolbar::getWidgetForActionTooltip(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Dashboards manager");
4592     CHECK_SET_ERR(nullptr != dashboardsManagerButton, "'Dashboards manager' is nullptr");
4593     CHECK_SET_ERR(dashboardsManagerButton->isEnabled(), "'Dashboards manager' button is unexpectedly disabled");
4594 
4595     //    21. Click to the "Dashboards manager" button on the toolbar.
4596     //    Expected result: the "Dashboards Manager" dialog appears. It contains four items, not all of them are checked. Their names are "Extract consensus as sequence 1", "Extract consensus as sequence 2", "Align sequence with MUSCLE 1", "Align sequence with MUSCLE 2".
4597     //    22. Cancel the dialog
4598     class Scenario : public CustomScenario {
4599     public:
4600         static bool sorting(const QPair<QString, bool> &e1, const QPair<QString, bool> &e2) {
4601             if (e1.first < e2.first)
4602                 return true;
4603             return false;
4604         }
4605 
4606         void run(HI::GUITestOpStatus &os) override {
4607             QWidget *dialog = GTWidget::getActiveModalWidget(os);
4608             QList<QPair<QString, bool>> expectedDashboardsState({qMakePair(QString("Align sequences with MUSCLE 1"), true),
4609                                                                  qMakePair(QString("Align sequences with MUSCLE 2"), true),
4610                                                                  qMakePair(QString("Extract consensus as sequence 1"), false),
4611                                                                  qMakePair(QString("Extract consensus as sequence 2"), false)});
4612             std::sort(expectedDashboardsState.begin(), expectedDashboardsState.end(), sorting);
4613 
4614             QList<QPair<QString, bool>> actualDashboardsState = DashboardsManagerDialogFiller::getDashboardsState(os);
4615             std::sort(actualDashboardsState.begin(), actualDashboardsState.end(), sorting);
4616 
4617             CHECK_SET_ERR(expectedDashboardsState.size() == actualDashboardsState.size(),
4618                           QString("Expected dashboards count is not equal to the actual dashboards list size: expected %1, got %2")
4619                               .arg(expectedDashboardsState.size())
4620                               .arg(actualDashboardsState.size()));
4621 
4622             for (int i = 0; i < expectedDashboardsState.size(); ++i) {
4623                 const QString expectedDashboardName = expectedDashboardsState[i].first;
4624                 const QString actualDashboardName = actualDashboardsState[i].first;
4625                 CHECK_SET_ERR(expectedDashboardName == actualDashboardName,
4626                               QString("Dashboard number %1 has an unexpected name: expected '%2', got '%3'")
4627                                   .arg(i)
4628                                   .arg(expectedDashboardName)
4629                                   .arg(actualDashboardName));
4630 
4631                 const bool expectedDashboardState = expectedDashboardsState[i].second;
4632                 const bool actualDashboardState = actualDashboardsState[i].second;
4633                 CHECK_SET_ERR(expectedDashboardState == actualDashboardState,
4634                               QString("Dashboard number %1 has an unexpected state: it should be %2, but it is '%3'")
4635                                   .arg(i)
4636                                   .arg(expectedDashboardState ? "visible" : "invisible")
4637                                   .arg(actualDashboardState ? "visible" : "invisible"));
4638             }
4639 
4640             GTUtilsDialog::clickButtonBox(os, dialog, QDialogButtonBox::Cancel);
4641         }
4642     };
4643 
4644     GTUtilsDialog::waitForDialog(os, new DashboardsManagerDialogFiller(os, new Scenario()));
4645     GTWidget::click(os, dashboardsManagerButton);
4646 
4647     //    23. Switch to the first Workflow Designer.
4648     //    Expected result:
4649     //     - The Workflow Designer is in the dashboards view mode.
4650     //     - There are 2 dashboard tabs. Their names are "Extract consensus as sequence 2", "Align sequence with MUSCLE 2".
4651     //     - The "Align sequence with MUSCLE 1" dashboard is active.
4652     //     - The "Dashboards manager" button on the toolbar is active.
4653     coreLog.info(QString("Try to switch to tab %1(%2)")
4654                      .arg(tabIndex1)
4655                      .arg(GTUtilsMdi::getTabBar(os)->tabText(tabIndex1)));
4656     GTUtilsMdi::clickTab(os, tabIndex1);
4657     GTUtilsTaskTreeView::waitTaskFinished(os);
4658 
4659     viewSwitchButton = qobject_cast<QAbstractButton *>(
4660         GTToolbar::getWidgetForActionTooltip(os,
4661                                              GTToolbar::getToolbar(os,
4662                                                                    MWTOOLBAR_ACTIVEMDI),
4663                                              "Show workflow"));
4664     CHECK_SET_ERR(nullptr != viewSwitchButton, "'To Workflow Designer' is nullptr");
4665     CHECK_SET_ERR(viewSwitchButton->isVisible(), "View switch button is unexpectedly invisible");
4666     CHECK_SET_ERR(viewSwitchButton->isEnabled(), "View switch button is unexpectedly disabled");
4667 
4668     expectedButtonText = "To Workflow Designer";
4669     actualButtonText = viewSwitchButton->text();
4670     CHECK_SET_ERR(expectedButtonText == actualButtonText,
4671                   QString("View switch button has an unexpected text: expected '%1', got '%2'")
4672                       .arg(expectedButtonText)
4673                       .arg(actualButtonText));
4674 
4675     coreLog.info("Trying get GTUtilsDashboard::getTabWidget(os)");
4676     dashboardsView = GTUtilsDashboard::getTabWidget(os);
4677     CHECK_SET_ERR(nullptr != dashboardsView, "Dashboards view is nullptr");
4678     coreLog.info("Successfully got GTUtilsDashboard::getTabWidget(os)");
4679 
4680     expectedTabsCount = 2;
4681     actualTabsCount = dashboardsView->count();
4682     CHECK_SET_ERR(expectedTabsCount == actualTabsCount,
4683                   QString("There is an incorrect count of tabs in the Dashboard View: expected %1, got %2")
4684                       .arg(expectedTabsCount)
4685                       .arg(actualTabsCount));
4686 
4687     expectedActiveTabIndex = 0;
4688     actualActiveTabIndex = dashboardsView->currentIndex();
4689     CHECK_SET_ERR(expectedActiveTabIndex == actualActiveTabIndex,
4690                   QString("There is an incorrect active tab: expected index is %1, actual index is %2")
4691                       .arg(expectedActiveTabIndex)
4692                       .arg(actualActiveTabIndex));
4693 
4694     expectedTabName = "Align sequences with MUSCLE 1";
4695     actualTabName = GTUtilsDashboard::getDashboardName(os, expectedActiveTabIndex);
4696     CHECK_SET_ERR(expectedTabName == actualTabName,
4697                   QString("Active dashboard has an unexpected name: expect '%1', got '%2'")
4698                       .arg(expectedTabName)
4699                       .arg(actualTabName));
4700 
4701     outputFiles = GTUtilsDashboard::getOutputFiles(os);
4702     CHECK_SET_ERR(!outputFiles.isEmpty(), "Active dashboard is not displayed properly");
4703 
4704     dashboardsManagerButton = GTToolbar::getWidgetForActionTooltip(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Dashboards manager");
4705     CHECK_SET_ERR(nullptr != dashboardsManagerButton, "'Dashboards manager' is nullptr");
4706     CHECK_SET_ERR(dashboardsManagerButton->isEnabled(), "'Dashboards manager' button is unexpectedly disabled");
4707 
4708     //    24. Click to the "Dashboards manager" button on the toolbar.
4709     //    Expected result:
4710     //     - the "Dashboards Manager" dialog appears.
4711     //       It contains 4 items, not all of them are checked.
4712     //       Their names are "Extract consensus as sequence 1", "Extract consensus as sequence 2", "Align sequence with MUSCLE 1", "Align sequence with MUSCLE 2".
4713     //    25. Cancel the dialog
4714     GTUtilsDialog::waitForDialog(os, new DashboardsManagerDialogFiller(os, new Scenario()));
4715     GTWidget::click(os, dashboardsManagerButton);
4716 
4717     //    26. Switch to the third Workflow Designer.
4718     //    Expected result:
4719     //     - The Workflow Designer is in the scene view mode.
4720     //     - The "Dashboards manager" button on the toolbar is active.
4721     coreLog.info(QString("Try to switch to tab %1(%2)")
4722                      .arg(tabIndex3)
4723                      .arg(GTUtilsMdi::getTabBar(os)->tabText(tabIndex3)));
4724     GTUtilsMdi::clickTab(os, tabIndex3);
4725 
4726     dashboardsManagerButton = GTToolbar::getWidgetForActionTooltip(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Dashboards manager");
4727     CHECK_SET_ERR(nullptr != dashboardsManagerButton, "'Dashboards manager' is nullptr");
4728     CHECK_SET_ERR(dashboardsManagerButton->isEnabled(), "'Dashboards manager' button is unexpectedly disabled");
4729 
4730     viewSwitchButton = qobject_cast<QAbstractButton *>(
4731         GTToolbar::getWidgetForActionTooltip(os,
4732                                              GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI),
4733                                              "Show dashboard"));
4734     CHECK_SET_ERR(nullptr != viewSwitchButton &&
4735                       viewSwitchButton->isVisible(),
4736                   "'Go to Dashboards' is invisible");
4737 
4738     //    27. Click to the "Dashboards manager" button on the toolbar.
4739     //    Expected result:
4740     //     - the "Dashboards Manager" dialog appears. It contains four items. Their names are "Extract consensus as sequence 1", "Extract consensus as sequence 2", "Align sequence with MUSCLE 1", "Align sequence with MUSCLE 2".
4741     //     - "Extract consensus as sequence 1" and "Extract consensus as sequence 2" are unchecked, all other are checked.
4742     //    28. Cancel the dialog.
4743     GTUtilsDialog::waitForDialog(os, new DashboardsManagerDialogFiller(os, new Scenario()));
4744     GTWidget::click(os, dashboardsManagerButton);
4745 
4746     //    29. Click to the "Go to Dashboards" button on the toolbar.
4747     //    Expected result:
4748     //     - There are two dashboard tabs. Their names are "Align sequence with MUSCLE 1", "Align sequence with MUSCLE 2" (warning: two last tabs can be swapped, it depends on the task finish order, it is a correct situation).
4749     //     - The first dashboard is active.
4750     viewSwitchButton = qobject_cast<QAbstractButton *>(
4751         GTToolbar::getWidgetForActionTooltip(os,
4752                                              GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI),
4753                                              "Show dashboard"));
4754     CHECK_SET_ERR(nullptr != viewSwitchButton, "'Go to Dashboards' is nullptr");
4755     CHECK_SET_ERR(viewSwitchButton->isVisible(), "View switch button is unexpectedly invisible");
4756     CHECK_SET_ERR(viewSwitchButton->isEnabled(), "View switch button is unexpectedly disabled");
4757     GTWidget::click(os, viewSwitchButton);
4758 
4759     coreLog.info("Trying get GTUtilsDashboard::getTabWidget(os)");
4760     dashboardsView = GTUtilsDashboard::getTabWidget(os);
4761     CHECK_SET_ERR(nullptr != dashboardsView, "Dashboards view is nullptr");
4762     coreLog.info("Successfully got GTUtilsDashboard::getTabWidget(os)");
4763 
4764     expectedTabsCount = 2;
4765     actualTabsCount = dashboardsView->count();
4766     CHECK_SET_ERR(expectedTabsCount == actualTabsCount,
4767                   QString("There is an incorrect count of tabs in the Dashboard View: expected %1, got %2")
4768                       .arg(expectedTabsCount)
4769                       .arg(actualTabsCount));
4770 
4771     expectedActiveTabIndex = 0;
4772     actualActiveTabIndex = dashboardsView->currentIndex();
4773     CHECK_SET_ERR(expectedActiveTabIndex == actualActiveTabIndex,
4774                   QString("There is an incorrect active tab: expected index is %1, actual index is %2")
4775                       .arg(expectedActiveTabIndex)
4776                       .arg(actualActiveTabIndex));
4777 
4778     expectedTabName = "Align sequences with MUSCLE 1";
4779     actualTabName = GTUtilsDashboard::getDashboardName(os, expectedActiveTabIndex);
4780     CHECK_SET_ERR(expectedTabName == actualTabName,
4781                   QString("Active dashboard has an unexpected name: expect '%1', got '%2'")
4782                       .arg(expectedTabName)
4783                       .arg(actualTabName));
4784 }
4785 
4786 }  // namespace GUITest_common_scenarios_workflow_dashboard
4787 
4788 }  // namespace U2
4789