1 /**
2  * UGENE - Integrated Bioinformatics Tools.
3  * Copyright (C) 2008-2021 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 "GTUtilsAssemblyBrowser.h"
23 #include <drivers/GTKeyboardDriver.h>
24 #include <primitives/GTLineEdit.h>
25 #include <primitives/GTToolbar.h>
26 #include <primitives/GTWidget.h>
27 #include <utils/GTThread.h>
28 
29 #include <QApplication>
30 #include <QLabel>
31 #include <QLineEdit>
32 #include <QScrollBar>
33 #include <QSharedPointer>
34 
35 #include <U2Core/U2SafePoints.h>
36 
37 #include <U2View/AssemblyBrowser.h>
38 #include <U2View/AssemblyBrowserFactory.h>
39 #include <U2View/AssemblyModel.h>
40 
41 #include "GTGlobals.h"
42 #include "GTUtilsMdi.h"
43 #include "GTUtilsOptionsPanel.h"
44 #include "GTUtilsProjectTreeView.h"
45 #include "primitives/PopupChooser.h"
46 #include "utils/GTUtilsDialog.h"
47 
48 namespace U2 {
49 using namespace HI;
50 
51 #define GT_CLASS_NAME "GTUtilsAssemblyBrowser"
52 
53 #define GT_METHOD_NAME "getActiveAssemblyBrowserWindow"
getActiveAssemblyBrowserWindow(GUITestOpStatus & os)54 QWidget *GTUtilsAssemblyBrowser::getActiveAssemblyBrowserWindow(GUITestOpStatus &os) {
55     QWidget *widget = GTUtilsMdi::getActiveObjectViewWindow(os, AssemblyBrowserFactory::ID);
56     GTThread::waitForMainThread();
57     return widget;
58 }
59 #undef GT_METHOD_NAME
60 
61 #define GT_METHOD_NAME "checkAssemblyBrowserWindowIsActive"
checkAssemblyBrowserWindowIsActive(GUITestOpStatus & os)62 void GTUtilsAssemblyBrowser::checkAssemblyBrowserWindowIsActive(GUITestOpStatus &os) {
63     getActiveAssemblyBrowserWindow(os);
64 }
65 #undef GT_METHOD_NAME
66 
67 #define GT_METHOD_NAME "getView"
getView(HI::GUITestOpStatus & os,const QString & viewTitle)68 AssemblyBrowserUi *GTUtilsAssemblyBrowser::getView(HI::GUITestOpStatus &os, const QString &viewTitle) {
69     if (viewTitle.isEmpty()) {
70         checkAssemblyBrowserWindowIsActive(os);
71         QWidget *assemblyBrowserWindow = getActiveAssemblyBrowserWindow(os);
72         AssemblyBrowserUi *view = assemblyBrowserWindow->findChild<AssemblyBrowserUi *>();
73         GT_CHECK_RESULT(view != nullptr, "Active windows is not assembly browser", nullptr);
74         return view;
75     }
76     QString objectName = "assembly_browser_" + viewTitle;
77     AssemblyBrowserUi *view = qobject_cast<AssemblyBrowserUi *>(GTWidget::findWidget(os, objectName));
78     GT_CHECK_RESULT(view != nullptr, "Assembly browser wasn't found", nullptr);
79     return view;
80 }
81 #undef GT_METHOD_NAME
82 
addRefFromProject(HI::GUITestOpStatus & os,QString docName,QModelIndex parent)83 void GTUtilsAssemblyBrowser::addRefFromProject(HI::GUITestOpStatus &os, QString docName, QModelIndex parent) {
84     checkAssemblyBrowserWindowIsActive(os);
85     QWidget *renderArea = GTWidget::findWidget(os, "assembly_reads_area");
86     QModelIndex ref = GTUtilsProjectTreeView::findIndex(os, docName, parent);
87     GTUtilsProjectTreeView::dragAndDrop(os, ref, renderArea);
88 }
89 
90 #define GT_METHOD_NAME "hasReference"
hasReference(HI::GUITestOpStatus & os,const QString & viewTitle)91 bool GTUtilsAssemblyBrowser::hasReference(HI::GUITestOpStatus &os, const QString &viewTitle) {
92     AssemblyBrowserUi *view = getView(os, viewTitle);
93     GT_CHECK_RESULT(nullptr != view, "Assembly browser wasn't found", false);
94     return hasReference(os, view);
95 }
96 #undef GT_METHOD_NAME
97 
98 #define GT_METHOD_NAME "hasReference"
hasReference(HI::GUITestOpStatus & os,QWidget * view)99 bool GTUtilsAssemblyBrowser::hasReference(HI::GUITestOpStatus &os, QWidget *view) {
100     if (view == nullptr) {
101         view = getActiveAssemblyBrowserWindow(os);
102     }
103     QString objectName = "assembly_browser_" + view->objectName();
104     AssemblyBrowserUi *assemblyBrowser = qobject_cast<AssemblyBrowserUi *>(GTWidget::findWidget(os, objectName));
105     GT_CHECK_RESULT(assemblyBrowser != nullptr, "Assembly browser wasn't found", false);
106     return hasReference(os, assemblyBrowser);
107 }
108 #undef GT_METHOD_NAME
109 
110 #define GT_METHOD_NAME "hasReference"
hasReference(HI::GUITestOpStatus & os,AssemblyBrowserUi * assemblyBrowser)111 bool GTUtilsAssemblyBrowser::hasReference(HI::GUITestOpStatus &os, AssemblyBrowserUi *assemblyBrowser) {
112     GT_CHECK_RESULT(assemblyBrowser != nullptr, "Assembly browser is NULL", false);
113 
114     QSharedPointer<AssemblyModel> model = assemblyBrowser->getModel();
115     GT_CHECK_RESULT(!model.isNull(), "Assembly model is NULL", false);
116 
117     return model->hasReference();
118 }
119 #undef GT_METHOD_NAME
120 
121 #define GT_METHOD_NAME "getLength"
getLength(HI::GUITestOpStatus & os)122 qint64 GTUtilsAssemblyBrowser::getLength(HI::GUITestOpStatus &os) {
123     QWidget *mdi = getActiveAssemblyBrowserWindow(os);
124 
125     QWidget *infoOptionsPanel = GTWidget::findWidget(os, "OP_OPTIONS_WIDGET", mdi);
126     if (!infoOptionsPanel->isVisible()) {
127         GTWidget::click(os, GTWidget::findWidget(os, "OP_ASS_INFO", mdi));
128         infoOptionsPanel = GTWidget::findWidget(os, "OP_OPTIONS_WIDGET", mdi);
129     }
130     GT_CHECK_RESULT(infoOptionsPanel != nullptr, "Information options panel wasn't found", 0);
131 
132     QWidget *b = GTWidget::findWidget(os, "leLength", infoOptionsPanel);
133     QLineEdit *leLength = qobject_cast<QLineEdit *>(b);
134     GT_CHECK_RESULT(leLength != nullptr, "Length line edit wasn't found", 0);
135 
136     bool isConverted = false;
137     QString lengthString = leLength->text();
138     lengthString.replace(" ", "");
139     qint64 value = lengthString.toLongLong(&isConverted);
140     GT_CHECK_RESULT(isConverted, QString("Can't convert length to number: '%1'").arg(lengthString), 0);
141 
142     return value;
143 }
144 #undef GT_METHOD_NAME
145 
146 #define GT_METHOD_NAME "getReadsCount"
getReadsCount(HI::GUITestOpStatus & os)147 qint64 GTUtilsAssemblyBrowser::getReadsCount(HI::GUITestOpStatus &os) {
148     QWidget *mdi = getActiveAssemblyBrowserWindow(os);
149 
150     QWidget *infoOptionsPanel = GTWidget::findWidget(os, "OP_OPTIONS_WIDGET", mdi);
151     if (!infoOptionsPanel->isVisible()) {
152         GTWidget::click(os, GTWidget::findWidget(os, "OP_ASS_INFO", mdi));
153         infoOptionsPanel = GTWidget::findWidget(os, "OP_OPTIONS_WIDGET", mdi);
154     }
155     GT_CHECK_RESULT(infoOptionsPanel != nullptr, "Information options panel wasn't found", 0);
156 
157     QLineEdit *leReads = qobject_cast<QLineEdit *>(GTWidget::findWidget(os, "leReads", infoOptionsPanel));
158     GT_CHECK_RESULT(leReads != nullptr, "Length line edit wasn't found", 0);
159 
160     bool isConverted = false;
161     QString readsString = leReads->text();
162     readsString.replace(" ", "");
163     qint64 value = readsString.toLongLong(&isConverted);
164     GT_CHECK_RESULT(isConverted, QString("Can't convert reads count to number: '%1'").arg(readsString), 0);
165 
166     return value;
167 }
168 #undef GT_METHOD_NAME
169 
170 #define GT_METHOD_NAME "isWelcomeScreenVisible"
isWelcomeScreenVisible(HI::GUITestOpStatus & os)171 bool GTUtilsAssemblyBrowser::isWelcomeScreenVisible(HI::GUITestOpStatus &os) {
172     QWidget *window = getActiveAssemblyBrowserWindow(os);
173     QWidget *coveredRegionsLabel = GTWidget::findWidget(os, "CoveredRegionsLabel", window);
174     GT_CHECK_RESULT(coveredRegionsLabel != nullptr, "coveredRegionsLabel is NULL", false);
175     return coveredRegionsLabel->isVisible();
176 }
177 #undef GT_METHOD_NAME
178 
179 #define GT_METHOD_NAME "zoomIn"
zoomIn(HI::GUITestOpStatus & os,Method method)180 void GTUtilsAssemblyBrowser::zoomIn(HI::GUITestOpStatus &os, Method method) {
181     checkAssemblyBrowserWindowIsActive(os);
182     switch (method) {
183         case Button:
184             GTToolbar::clickButtonByTooltipOnToolbar(os, MWTOOLBAR_ACTIVEMDI, "Zoom in");
185             break;
186         case Hotkey:
187             if (!GTWidget::findWidget(os, "assembly_reads_area")->hasFocus()) {
188                 GTWidget::click(os, GTWidget::findWidget(os, "assembly_reads_area"));
189             }
190             GTKeyboardDriver::keyClick('+');
191             break;
192         default:
193             break;
194     }
195 }
196 #undef GT_METHOD_NAME
197 
198 #define GT_METHOD_NAME "zoomToMax"
zoomToMax(HI::GUITestOpStatus & os)199 void GTUtilsAssemblyBrowser::zoomToMax(HI::GUITestOpStatus &os) {
200     checkAssemblyBrowserWindowIsActive(os);
201     QToolBar *toolbar = GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI);
202     GT_CHECK(toolbar != nullptr, "Can't find the toolbar");
203 
204     QWidget *zoomInButton = GTToolbar::getWidgetForActionTooltip(os, toolbar, "Zoom in");
205     GT_CHECK(zoomInButton != nullptr, "Can't find the 'Zoom in' button");
206 
207     while (zoomInButton->isEnabled()) {
208         GTWidget::click(os, zoomInButton);
209     }
210 }
211 #undef GT_METHOD_NAME
212 
213 #define GT_METHOD_NAME "zoomToMin"
zoomToMin(HI::GUITestOpStatus & os)214 void GTUtilsAssemblyBrowser::zoomToMin(HI::GUITestOpStatus &os) {
215     checkAssemblyBrowserWindowIsActive(os);
216 
217     QToolBar *toolbar = GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI);
218     GT_CHECK(toolbar != nullptr, "Can't find the toolbar");
219 
220     QWidget *zoomOutButton = GTToolbar::getWidgetForActionTooltip(os, toolbar, "Zoom out");
221     GT_CHECK(zoomOutButton != nullptr, "Can't find the 'Zoom in' button");
222 
223     while (zoomOutButton->isEnabled()) {
224         GTWidget::click(os, zoomOutButton);
225     }
226 }
227 #undef GT_METHOD_NAME
228 
229 #define GT_METHOD_NAME "zoomToReads"
zoomToReads(GUITestOpStatus & os)230 void GTUtilsAssemblyBrowser::zoomToReads(GUITestOpStatus &os) {
231     checkAssemblyBrowserWindowIsActive(os);
232     QLabel *coveredRegionsLabel = GTWidget::findExactWidget<QLabel *>(os, "CoveredRegionsLabel");
233     emit coveredRegionsLabel->linkActivated("zoom");
234     GTGlobals::sleep(1000);
235 }
236 #undef GT_METHOD_NAME
237 
238 #define GT_METHOD_NAME "goToPosition"
goToPosition(HI::GUITestOpStatus & os,qint64 position,Method method)239 void GTUtilsAssemblyBrowser::goToPosition(HI::GUITestOpStatus &os, qint64 position, Method method) {
240     checkAssemblyBrowserWindowIsActive(os);
241 
242     QToolBar *toolbar = GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI);
243     GT_CHECK(toolbar != nullptr, "Can't find the toolbar");
244 
245     QLineEdit *positionLineEdit = GTWidget::findExactWidget<QLineEdit *>(os, "go_to_pos_line_edit", toolbar);
246     GTLineEdit::setText(os, positionLineEdit, QString::number(position));
247 
248     switch (method) {
249         case Button:
250             GTWidget::click(os, GTWidget::findWidget(os, "Go!"));
251             break;
252         default:
253             GTKeyboardDriver::keyClick(Qt::Key_Enter);
254             break;
255     }
256     GTGlobals::sleep(1000);
257     GTThread::waitForMainThread();
258 }
259 #undef GT_METHOD_NAME
260 
261 #define GT_METHOD_NAME "callContextMenu"
callContextMenu(HI::GUITestOpStatus & os,GTUtilsAssemblyBrowser::Area area)262 void GTUtilsAssemblyBrowser::callContextMenu(HI::GUITestOpStatus &os, GTUtilsAssemblyBrowser::Area area) {
263     checkAssemblyBrowserWindowIsActive(os);
264     QString widgetName;
265     switch (area) {
266         case Consensus:
267             widgetName = "Consensus area";
268             break;
269         case Overview:
270             widgetName = "Zoomable assembly overview";
271             break;
272         case Reads:
273             widgetName = "assembly_reads_area";
274             break;
275         default:
276             os.setError("Can't find the area");
277             FAIL(false, );
278     }
279 
280     GTWidget::click(os, GTWidget::findWidget(os, widgetName), Qt::RightButton);
281     GTGlobals::sleep(300);
282 }
283 #undef GT_METHOD_NAME
284 
285 #define GT_METHOD_NAME "callExportCoverageDialog"
callExportCoverageDialog(HI::GUITestOpStatus & os,Area area)286 void GTUtilsAssemblyBrowser::callExportCoverageDialog(HI::GUITestOpStatus &os, Area area) {
287     checkAssemblyBrowserWindowIsActive(os);
288 
289     switch (area) {
290         case Consensus:
291             GTUtilsDialog::waitForDialog(os, new PopupChooser(os, QStringList() << "Export coverage"));
292             break;
293         case Overview:
294             GTUtilsDialog::waitForDialog(os, new PopupChooser(os, QStringList() << "Export coverage"));
295             break;
296         case Reads:
297             GTUtilsDialog::waitForDialog(os, new PopupChooser(os, QStringList() << "Export"
298                                                                                 << "Export coverage"));
299             break;
300         default:
301             os.setError("Can't call the dialog on this area");
302             FAIL(false, );
303     }
304 
305     callContextMenu(os, area);
306 }
307 #undef GT_METHOD_NAME
308 
309 #define GT_METHOD_NAME "getScrollBar"
getScrollBar(GUITestOpStatus & os,Qt::Orientation orientation)310 QScrollBar *GTUtilsAssemblyBrowser::getScrollBar(GUITestOpStatus &os, Qt::Orientation orientation) {
311     AssemblyBrowserUi *ui = getView(os);
312     QList<QScrollBar *> scrollBars = ui->findChildren<QScrollBar *>();
313     foreach (QScrollBar *bar, scrollBars) {
314         if (bar->orientation() == orientation) {
315             return bar;
316         }
317     }
318 
319     GT_CHECK_RESULT(false, QString("Scrollbar with orientation %1 not found").arg(orientation), nullptr);
320 }
321 #undef GT_METHOD_NAME
322 
323 #define GT_METHOD_NAME "scrollToStart"
scrollToStart(GUITestOpStatus & os,Qt::Orientation orientation)324 void GTUtilsAssemblyBrowser::scrollToStart(GUITestOpStatus &os, Qt::Orientation orientation) {
325     QScrollBar *scrollBar = getScrollBar(os, orientation);
326     class MainThreadAction : public CustomScenario {
327     public:
328         MainThreadAction(QScrollBar *scrollbar)
329             : CustomScenario(), scrollbar(scrollbar) {
330         }
331         void run(HI::GUITestOpStatus &os) {
332             Q_UNUSED(os);
333             scrollbar->setValue(0);
334         }
335         QScrollBar *scrollbar;
336     };
337     GTThread::runInMainThread(os, new MainThreadAction(scrollBar));
338     GTThread::waitForMainThread();
339 }
340 #undef GT_METHOD_NAME
341 
342 #undef GT_CLASS_NAME
343 
344 }  // namespace U2
345