10404:f7d9c31f0c38 | 10405:df7e1694d0eb |
---|---|
11 import enum | 11 import enum |
12 import locale | 12 import locale |
13 import os | 13 import os |
14 | 14 |
15 from PyQt6.QtCore import QCoreApplication, QEvent, Qt, pyqtSignal, pyqtSlot | 15 from PyQt6.QtCore import QCoreApplication, QEvent, Qt, pyqtSignal, pyqtSlot |
16 from PyQt6.QtWidgets import QAbstractButton, QComboBox, QDialogButtonBox, QWidget | 16 from PyQt6.QtWidgets import ( |
17 QAbstractButton, | |
18 QComboBox, | |
19 QDialogButtonBox, | |
20 QTreeWidgetItem, | |
21 QWidget, | |
22 ) | |
17 | 23 |
18 from eric7 import Preferences | 24 from eric7 import Preferences |
19 from eric7.DataViews.PyCoverageDialog import PyCoverageDialog | 25 from eric7.DataViews.PyCoverageDialog import PyCoverageDialog |
20 from eric7.EricGui import EricPixmapCache | 26 from eric7.EricGui import EricPixmapCache |
21 from eric7.EricWidgets import EricMessageBox | 27 from eric7.EricWidgets import EricMessageBox |
31 ) | 37 ) |
32 | 38 |
33 from .Interfaces import Frameworks | 39 from .Interfaces import Frameworks |
34 from .Interfaces.TestExecutorBase import TestConfig, TestResult, TestResultCategory | 40 from .Interfaces.TestExecutorBase import TestConfig, TestResult, TestResultCategory |
35 from .Interfaces.TestFrameworkRegistry import TestFrameworkRegistry | 41 from .Interfaces.TestFrameworkRegistry import TestFrameworkRegistry |
36 from .TestResultsTree import TestResultsFilterModel, TestResultsModel, TestResultsTreeView | 42 from .TestResultsTree import ( |
43 TestResultsFilterModel, | |
44 TestResultsModel, | |
45 TestResultsTreeView, | |
46 ) | |
37 from .Ui_TestingWidget import Ui_TestingWidget | 47 from .Ui_TestingWidget import Ui_TestingWidget |
38 | 48 |
39 | 49 |
40 class TestingWidgetModes(enum.Enum): | 50 class TestingWidgetModes(enum.Enum): |
41 """ | 51 """ |
43 """ | 53 """ |
44 | 54 |
45 IDLE = 0 # idle, no test were run yet | 55 IDLE = 0 # idle, no test were run yet |
46 RUNNING = 1 # test run being performed | 56 RUNNING = 1 # test run being performed |
47 STOPPED = 2 # test run finished | 57 STOPPED = 2 # test run finished |
58 DISCOVERY = 3 # discovery of tests being performed | |
48 | 59 |
49 | 60 |
50 class TestingWidget(QWidget, Ui_TestingWidget): | 61 class TestingWidget(QWidget, Ui_TestingWidget): |
51 """ | 62 """ |
52 Class implementing a widget to orchestrate unit test execution. | 63 Class implementing a widget to orchestrate unit test execution. |
56 @signal testRunStopped() emitted after a test run has finished | 67 @signal testRunStopped() emitted after a test run has finished |
57 """ | 68 """ |
58 | 69 |
59 testFile = pyqtSignal(str, int, bool) | 70 testFile = pyqtSignal(str, int, bool) |
60 testRunStopped = pyqtSignal() | 71 testRunStopped = pyqtSignal() |
72 | |
73 TestCaseNameRole = Qt.ItemDataRole.UserRole | |
74 TestCaseFileRole = Qt.ItemDataRole.UserRole + 1 | |
75 TestCaseLinenoRole = Qt.ItemDataRole.UserRole + 2 | |
76 TestCaseIdRole = Qt.ItemDataRole.UserRole + 3 | |
61 | 77 |
62 def __init__(self, testfile=None, parent=None): | 78 def __init__(self, testfile=None, parent=None): |
63 """ | 79 """ |
64 Constructor | 80 Constructor |
65 | 81 |
130 """<p>This button opens a dialog containing the collected code""" | 146 """<p>This button opens a dialog containing the collected code""" |
131 """ coverage data.</p>""" | 147 """ coverage data.</p>""" |
132 ) | 148 ) |
133 ) | 149 ) |
134 | 150 |
151 self.__discoverButton = self.buttonBox.addButton( | |
152 self.tr("Discover"), QDialogButtonBox.ButtonRole.ActionRole | |
153 ) | |
154 self.__discoverButton.setToolTip(self.tr("Discover Tests")) | |
155 self.__discoverButton.setWhatsThis( | |
156 self.tr( | |
157 """<b>Discover Tests</b>""" | |
158 """<p>This button starts a discovery of available tests.</p>""" | |
159 ) | |
160 ) | |
161 | |
135 self.__startButton = self.buttonBox.addButton( | 162 self.__startButton = self.buttonBox.addButton( |
136 self.tr("Start"), QDialogButtonBox.ButtonRole.ActionRole | 163 self.tr("Start"), QDialogButtonBox.ButtonRole.ActionRole |
137 ) | 164 ) |
138 | 165 |
139 self.__startButton.setToolTip(self.tr("Start the selected testsuite")) | 166 self.__startButton.setToolTip(self.tr("Start the selected test suite")) |
140 self.__startButton.setWhatsThis( | 167 self.__startButton.setWhatsThis( |
141 self.tr("""<b>Start Test</b><p>This button starts the test run.</p>""") | 168 self.tr("""<b>Start Test</b><p>This button starts the test run.</p>""") |
142 ) | 169 ) |
143 | 170 |
144 self.__startFailedButton = self.buttonBox.addButton( | 171 self.__startFailedButton = self.buttonBox.addButton( |
498 """ | 525 """ |
499 Private slot to update the state of the buttons of the button box. | 526 Private slot to update the state of the buttons of the button box. |
500 """ | 527 """ |
501 failedAvailable = bool(self.__resultsModel.getFailedTests()) | 528 failedAvailable = bool(self.__resultsModel.getFailedTests()) |
502 | 529 |
530 # Discover button | |
531 if self.__mode in (TestingWidgetModes.IDLE, TestingWidgetModes.STOPPED): | |
532 self.__discoverButton.setEnabled( | |
533 bool(self.venvComboBox.currentText()) | |
534 and bool(self.frameworkComboBox.currentText()) | |
535 and ( | |
536 ( | |
537 self.discoverCheckBox.isChecked() | |
538 and bool(self.discoveryPicker.currentText()) | |
539 ) | |
540 ) | |
541 ) | |
542 else: | |
543 self.__discoverButton.setEnabled(False) | |
544 self.__discoverButton.setDefault(False) | |
545 | |
503 # Start button | 546 # Start button |
504 if self.__mode in (TestingWidgetModes.IDLE, TestingWidgetModes.STOPPED): | 547 if self.__mode in (TestingWidgetModes.IDLE, TestingWidgetModes.STOPPED): |
505 self.__startButton.setEnabled( | 548 self.__startButton.setEnabled( |
506 bool(self.venvComboBox.currentText()) | 549 bool(self.venvComboBox.currentText()) |
507 and bool(self.frameworkComboBox.currentText()) | 550 and bool(self.frameworkComboBox.currentText()) |
571 self.__mode = TestingWidgetModes.IDLE | 614 self.__mode = TestingWidgetModes.IDLE |
572 self.__updateButtonBoxButtons() | 615 self.__updateButtonBoxButtons() |
573 self.progressGroupBox.hide() | 616 self.progressGroupBox.hide() |
574 self.tabWidget.setCurrentIndex(0) | 617 self.tabWidget.setCurrentIndex(0) |
575 | 618 |
619 self.raise_() | |
620 self.activateWindow() | |
621 | |
622 @pyqtSlot() | |
623 def __setDiscoverMode(self): | |
624 """ | |
625 Private slot to switch the widget to test discovery mode. | |
626 """ | |
627 self.__mode = TestingWidgetModes.DISCOVERY | |
628 | |
629 self.__totalCount = 0 | |
630 | |
631 self.sbLabel.setText("Discovering Tests") | |
632 self.tabWidget.setCurrentIndex(0) | |
633 self.__updateButtonBoxButtons() | |
634 | |
576 @pyqtSlot() | 635 @pyqtSlot() |
577 def __setRunningMode(self): | 636 def __setRunningMode(self): |
578 """ | 637 """ |
579 Private slot to switch the widget to running mode. | 638 Private slot to switch the widget to running mode. |
580 """ | 639 """ |
625 self.__insertDiscovery(self.__project.getProjectPath()) | 684 self.__insertDiscovery(self.__project.getProjectPath()) |
626 else: | 685 else: |
627 self.__insertDiscovery(Preferences.getMultiProject("Workspace")) | 686 self.__insertDiscovery(Preferences.getMultiProject("Workspace")) |
628 | 687 |
629 self.__resetResults() | 688 self.__resetResults() |
689 | |
690 self.discoveryList.clear() | |
691 | |
692 @pyqtSlot(str) | |
693 def on_discoveryPicker_editTextChanged(self, txt): | |
694 """ | |
695 Private slot to handle a change of the discovery start directory. | |
696 | |
697 @param txt new discovery start directory | |
698 @type str | |
699 """ | |
700 self.discoveryList.clear() | |
630 | 701 |
631 @pyqtSlot() | 702 @pyqtSlot() |
632 def on_testsuitePicker_aboutToShowPathPickerDialog(self): | 703 def on_testsuitePicker_aboutToShowPathPickerDialog(self): |
633 """ | 704 """ |
634 Private slot called before the test file selection dialog is shown. | 705 Private slot called before the test file selection dialog is shown. |
666 Private slot called by a button of the button box clicked. | 737 Private slot called by a button of the button box clicked. |
667 | 738 |
668 @param button button that was clicked | 739 @param button button that was clicked |
669 @type QAbstractButton | 740 @type QAbstractButton |
670 """ | 741 """ |
742 if button == self.__discoverButton: | |
743 self.__discoverTests() | |
671 if button == self.__startButton: | 744 if button == self.__startButton: |
672 self.startTests() | 745 self.startTests() |
673 self.__saveRecent() | 746 self.__saveRecent() |
674 elif button == self.__stopButton: | 747 elif button == self.__stopButton: |
675 self.__stopTests() | 748 self.__stopTests() |
834 EricMessageBox.information( | 907 EricMessageBox.information( |
835 self, self.tr("Versions"), headerText + versionsText | 908 self, self.tr("Versions"), headerText + versionsText |
836 ) | 909 ) |
837 | 910 |
838 @pyqtSlot() | 911 @pyqtSlot() |
912 def __discoverTests(self): | |
913 """ | |
914 Private slot to discover tests but don't execute them. | |
915 """ | |
916 if self.__mode in (TestingWidgetModes.RUNNING, TestingWidgetModes.DISCOVERY): | |
917 return | |
918 | |
919 self.__recentLog = "" | |
920 | |
921 environment = self.venvComboBox.currentText() | |
922 framework = self.frameworkComboBox.currentText() | |
923 | |
924 discoveryStart = self.discoveryPicker.currentText() | |
925 | |
926 self.sbLabel.setText(self.tr("Discovering Tests")) | |
927 QCoreApplication.processEvents() | |
928 | |
929 interpreter = self.__determineInterpreter(environment) | |
930 config = TestConfig( | |
931 interpreter=interpreter, | |
932 discover=True, | |
933 discoveryStart=discoveryStart, | |
934 discoverOnly=True, | |
935 testNamePattern=self.testNamePatternEdit.text(), | |
936 testMarkerExpression=self.markerExpressionEdit.text(), | |
937 failFast=self.failfastCheckBox.isChecked(), | |
938 ) | |
939 | |
940 self.__testExecutor = self.__frameworkRegistry.createExecutor(framework, self) | |
941 self.__testExecutor.collected.connect(self.__testsDiscovered) | |
942 self.__testExecutor.collectError.connect(self.__testDiscoveryError) | |
943 self.__testExecutor.testFinished.connect(self.__testDiscoveryProcessFinished) | |
944 self.__testExecutor.discoveryAboutToBeStarted.connect( | |
945 self.__testDiscoveryAboutToBeStarted | |
946 ) | |
947 | |
948 self.__setDiscoverMode() | |
949 self.__testExecutor.discover(config, []) | |
950 | |
951 @pyqtSlot() | |
839 def startTests(self, failedOnly=False): | 952 def startTests(self, failedOnly=False): |
840 """ | 953 """ |
841 Public slot to start the test run. | 954 Public slot to start the test run. |
842 | 955 |
843 @param failedOnly flag indicating to run only failed tests | 956 @param failedOnly flag indicating to run only failed tests |
844 @type bool | 957 @type bool |
845 """ | 958 """ |
846 if self.__mode == TestingWidgetModes.RUNNING: | 959 if self.__mode in (TestingWidgetModes.RUNNING, TestingWidgetModes.DISCOVERY): |
847 return | 960 return |
848 | 961 |
849 self.__recentLog = "" | 962 self.__recentLog = "" |
850 | 963 |
851 self.__recentEnvironment = self.venvComboBox.currentText() | 964 self.__recentEnvironment = self.venvComboBox.currentText() |
878 os.path.splitext(mainScript)[0] + ".coverage" if mainScript else "" | 991 os.path.splitext(mainScript)[0] + ".coverage" if mainScript else "" |
879 ) | 992 ) |
880 else: | 993 else: |
881 coverageFile = "" | 994 coverageFile = "" |
882 interpreter = self.__determineInterpreter(self.__recentEnvironment) | 995 interpreter = self.__determineInterpreter(self.__recentEnvironment) |
996 testCases = self.__selectedTestCases() | |
997 if not testCases and self.discoveryList.topLevelItemCount() > 0: | |
998 ok = EricMessageBox.yesNo( | |
999 self, | |
1000 self.tr("Running Tests"), | |
1001 self.tr("No test case has been selected. Shall all test cases be run?"), | |
1002 ) | |
1003 if not ok: | |
1004 return | |
1005 | |
883 config = TestConfig( | 1006 config = TestConfig( |
884 interpreter=interpreter, | 1007 interpreter=interpreter, |
885 discover=discover, | 1008 discover=discover, |
886 discoveryStart=discoveryStart, | 1009 discoveryStart=discoveryStart, |
1010 testCases=testCases, | |
887 testFilename=testFileName, | 1011 testFilename=testFileName, |
888 testName=testName, | 1012 testName=testName, |
889 testNamePattern=self.testNamePatternEdit.text(), | 1013 testNamePattern=self.testNamePatternEdit.text(), |
890 testMarkerExpression=self.markerExpressionEdit.text(), | 1014 testMarkerExpression=self.markerExpressionEdit.text(), |
891 failFast=self.failfastCheckBox.isChecked(), | 1015 failFast=self.failfastCheckBox.isChecked(), |
924 def __testsCollected(self, testNames): | 1048 def __testsCollected(self, testNames): |
925 """ | 1049 """ |
926 Private slot handling the 'collected' signal of the executor. | 1050 Private slot handling the 'collected' signal of the executor. |
927 | 1051 |
928 @param testNames list of tuples containing the test id, the test name | 1052 @param testNames list of tuples containing the test id, the test name |
929 and a description of collected tests | 1053 a description, the file name, the line number and the test path as a list |
930 @type list of tuple of (str, str, str) | 1054 of collected tests |
1055 @type list of tuple of (str, str, str, str, int, list) | |
931 """ | 1056 """ |
932 testResults = [ | 1057 testResults = [ |
933 TestResult( | 1058 TestResult( |
934 category=TestResultCategory.PENDING, | 1059 category=TestResultCategory.PENDING, |
935 status=self.tr("pending"), | 1060 status=self.tr("pending"), |
937 id=id, | 1062 id=id, |
938 message=desc, | 1063 message=desc, |
939 filename=filename, | 1064 filename=filename, |
940 lineno=lineno, | 1065 lineno=lineno, |
941 ) | 1066 ) |
942 for id, name, desc, filename, lineno in testNames | 1067 for id, name, desc, filename, lineno, _ in testNames |
943 ] | 1068 ] |
944 self.__resultsModel.addTestResults(testResults) | 1069 self.__resultsModel.addTestResults(testResults) |
945 self.__resultsTree.resizeColumns() | 1070 self.__resultsTree.resizeColumns() |
946 | 1071 |
947 self.__totalCount += len(testResults) | 1072 self.__totalCount += len(testResults) |
1174 if self.__project: | 1299 if self.__project: |
1175 # running as part of eric IDE | 1300 # running as part of eric IDE |
1176 self.testFile.emit(filename, lineno, True) | 1301 self.testFile.emit(filename, lineno, True) |
1177 else: | 1302 else: |
1178 self.__openEditor(filename, lineno) | 1303 self.__openEditor(filename, lineno) |
1304 self.__resultsTree.resizeColumns() | |
1179 | 1305 |
1180 def __openEditor(self, filename, linenumber=1): | 1306 def __openEditor(self, filename, linenumber=1): |
1181 """ | 1307 """ |
1182 Private method to open an editor window for the given file. | 1308 Private method to open an editor window for the given file. |
1183 | 1309 |
1216 Private slot handling the selection of a status for items to be shown. | 1342 Private slot handling the selection of a status for items to be shown. |
1217 | 1343 |
1218 @param status selected status | 1344 @param status selected status |
1219 @type str | 1345 @type str |
1220 """ | 1346 """ |
1221 # TODO: not yet implemented | |
1222 if status == self.__allFilter: | 1347 if status == self.__allFilter: |
1223 status = "" | 1348 status = "" |
1224 | 1349 |
1225 self.__resultFilterModel.setStatusFilterString(status) | 1350 self.__resultFilterModel.setStatusFilterString(status) |
1226 | 1351 |
1352 if not self.__project: | |
1353 # running in standalone mode | |
1354 self.__resultsTree.resizeColumns() | |
1355 | |
1227 def __updateStatusFilterComboBox(self): | 1356 def __updateStatusFilterComboBox(self): |
1357 """ | |
1358 Private method to update the status filter dialog box. | |
1359 """ | |
1228 statusFilters = self.__resultsModel.getStatusFilterList() | 1360 statusFilters = self.__resultsModel.getStatusFilterList() |
1229 self.statusFilterComboBox.clear() | 1361 self.statusFilterComboBox.clear() |
1230 self.statusFilterComboBox.addItem(self.__allFilter) | 1362 self.statusFilterComboBox.addItem(self.__allFilter) |
1231 self.statusFilterComboBox.addItems(sorted(statusFilters)) | 1363 self.statusFilterComboBox.addItems(sorted(statusFilters)) |
1364 | |
1365 ############################################################################ | |
1366 ## Methods below are handling the discovery only mode. | |
1367 ############################################################################ | |
1368 | |
1369 def __findDiscoveryItem(self, modulePath): | |
1370 """ | |
1371 Private method to find an item given the module path. | |
1372 | |
1373 @param modulePath path of the module in dotted notation | |
1374 @type str | |
1375 @return reference to the item or None | |
1376 @rtype QTreeWidgetItem or None | |
1377 """ | |
1378 itm = self.discoveryList.topLevelItem(0) | |
1379 while itm is not None: | |
1380 if itm.data(0, TestingWidget.TestCaseNameRole) == modulePath: | |
1381 return itm | |
1382 | |
1383 itm = self.discoveryList.itemBelow(itm) | |
1384 | |
1385 return None | |
1386 | |
1387 @pyqtSlot(list) | |
1388 def __testsDiscovered(self, testNames): | |
1389 """ | |
1390 Private slot handling the 'collected' signal of the executor in discovery | |
1391 mode. | |
1392 | |
1393 @param testNames list of tuples containing the test id, the test name | |
1394 a description, the file name, the line number and the test path as a list | |
1395 of collected tests | |
1396 @type list of tuple of (str, str, str, str, int, list) | |
1397 """ | |
1398 for tid, _name, _desc, filename, lineno, testPath in testNames: | |
1399 parent = None | |
1400 for index in range(1, len(testPath) + 1): | |
1401 modulePath = ".".join(testPath[:index]) | |
1402 itm = self.__findDiscoveryItem(modulePath) | |
1403 if itm is not None: | |
1404 parent = itm | |
1405 else: | |
1406 if parent is None: | |
1407 itm = QTreeWidgetItem(self.discoveryList, [testPath[index - 1]]) | |
1408 else: | |
1409 itm = QTreeWidgetItem(parent, [testPath[index - 1]]) | |
1410 parent.setExpanded(True) | |
1411 itm.setFlags(itm.flags() | Qt.ItemFlag.ItemIsUserCheckable) | |
1412 itm.setCheckState(0, Qt.CheckState.Unchecked) | |
1413 itm.setData(0, TestingWidget.TestCaseNameRole, modulePath) | |
1414 itm.setData(0, TestingWidget.TestCaseLinenoRole, 0) | |
1415 if os.path.splitext(os.path.basename(filename))[0] == itm.text(0): | |
1416 itm.setData(0, TestingWidget.TestCaseFileRole, filename) | |
1417 elif parent: | |
1418 fn = parent.data(0, TestingWidget.TestCaseFileRole) | |
1419 if fn: | |
1420 itm.setData(0, TestingWidget.TestCaseFileRole, fn) | |
1421 parent = itm | |
1422 | |
1423 if parent: | |
1424 parent.setData(0, TestingWidget.TestCaseLinenoRole, lineno) | |
1425 parent.setData(0, TestingWidget.TestCaseIdRole, tid) | |
1426 | |
1427 self.__totalCount += len(testNames) | |
1428 | |
1429 self.sbLabel.setText(self.tr("Discovered %n Test(s)", "", self.__totalCount)) | |
1430 | |
1431 def __testDiscoveryError(self, errors): | |
1432 """ | |
1433 Private slot handling the 'collectError' signal of the executor. | |
1434 | |
1435 @param errors list of tuples containing the test name and a description | |
1436 of the error | |
1437 @type list of tuple of (str, str) | |
1438 """ | |
1439 for _testFile, error in errors: | |
1440 EricMessageBox.critical( | |
1441 self, | |
1442 self.tr("Discovery Error"), | |
1443 self.tr( | |
1444 "<p>There was an error while discovering tests in <b>{0}</b>.</p>" | |
1445 "<p>{1}</p>" | |
1446 ).format("<br/>".join(error.splitlines())), | |
1447 ) | |
1448 | |
1449 def __testDiscoveryProcessFinished(self, results, output): # noqa: U100 | |
1450 """ | |
1451 Private slot to handle the 'testFinished' signal of the executor in | |
1452 discovery mode. | |
1453 | |
1454 @param results list of test result objects (if not sent via the | |
1455 'testResult' signal) | |
1456 @type list of TestResult | |
1457 @param output string containing the test process output (if any) | |
1458 @type str | |
1459 """ | |
1460 self.__recentLog = output | |
1461 | |
1462 self.__setIdleMode() | |
1463 | |
1464 def __testDiscoveryAboutToBeStarted(self): | |
1465 """ | |
1466 Private slot to handle the 'testDiscoveryAboutToBeStarted' signal of the | |
1467 executor. | |
1468 """ | |
1469 self.discoveryList.clear() | |
1470 | |
1471 @pyqtSlot(QTreeWidgetItem, int) | |
1472 def on_discoveryList_itemChanged(self, item, column): | |
1473 """ | |
1474 Private slot handling the user checking or unchecking an item. | |
1475 | |
1476 @param item reference to the item | |
1477 @type QTreeWidgetItem | |
1478 @param column changed column | |
1479 @type int | |
1480 """ | |
1481 if column == 0: | |
1482 for index in range(item.childCount()): | |
1483 item.child(index).setCheckState(0, item.checkState(0)) | |
1484 | |
1485 @pyqtSlot(QTreeWidgetItem, int) | |
1486 def on_discoveryList_itemActivated(self, item, column): | |
1487 """ | |
1488 Private slot handling the user activating an item. | |
1489 | |
1490 @param item reference to the item | |
1491 @type QTreeWidgetItem | |
1492 @param column column of the double click | |
1493 @type int | |
1494 """ | |
1495 if item: | |
1496 filename = item.data(0, TestingWidget.TestCaseFileRole) | |
1497 if filename: | |
1498 self.__showSource( | |
1499 filename, item.data(0, TestingWidget.TestCaseLinenoRole) + 1 | |
1500 ) | |
1501 | |
1502 def __selectedTestCases(self, parent=None): | |
1503 """ | |
1504 Private method to assemble the list of selected test cases and suites. | |
1505 | |
1506 @param parent reference to the parent item | |
1507 @type QTreeWidgetItem | |
1508 @return list of selected test cases | |
1509 @rtype list of str | |
1510 """ | |
1511 selectedTests = [] | |
1512 itemsList = ( | |
1513 [ | |
1514 # top level | |
1515 self.discoveryList.topLevelItem(index) | |
1516 for index in range(self.discoveryList.topLevelItemCount()) | |
1517 ] | |
1518 if parent is None | |
1519 else [parent.child(index) for index in range(parent.childCount())] | |
1520 ) | |
1521 | |
1522 for itm in itemsList: | |
1523 if itm.checkState(0) == Qt.CheckState.Checked and itm.childCount() == 0: | |
1524 selectedTests.append(itm.data(0, TestingWidget.TestCaseIdRole)) | |
1525 if itm.childCount(): | |
1526 # recursively check children | |
1527 selectedTests.extend(self.__selectedTestCases(itm)) | |
1528 | |
1529 return selectedTests | |
1232 | 1530 |
1233 | 1531 |
1234 class TestingWindow(EricMainWindow): | 1532 class TestingWindow(EricMainWindow): |
1235 """ | 1533 """ |
1236 Main window class for the standalone dialog. | 1534 Main window class for the standalone dialog. |