diff --git a/src/gui/EntryPreviewWidget.cpp b/src/gui/EntryPreviewWidget.cpp index 1dc05c3b..38afbcf2 100644 --- a/src/gui/EntryPreviewWidget.cpp +++ b/src/gui/EntryPreviewWidget.cpp @@ -303,6 +303,8 @@ void EntryPreviewWidget::updateEntryAdvancedTab() void EntryPreviewWidget::updateEntryAutotypeTab() { Q_ASSERT(m_currentEntry); + + m_ui->entrySequenceLabel->setText(m_currentEntry->effectiveAutoTypeSequence()); m_ui->entryAutotypeTree->clear(); QList items; const AutoTypeAssociations* autotypeAssociations = m_currentEntry->autoTypeAssociations(); @@ -314,7 +316,7 @@ void EntryPreviewWidget::updateEntryAutotypeTab() } m_ui->entryAutotypeTree->addTopLevelItems(items); - setTabEnabled(m_ui->entryTabWidget, m_ui->entryAutotypeTab, !items.isEmpty()); + setTabEnabled(m_ui->entryTabWidget, m_ui->entryAutotypeTab, m_currentEntry->autoTypeEnabled()); } void EntryPreviewWidget::updateGroupHeaderLine() diff --git a/src/gui/EntryPreviewWidget.ui b/src/gui/EntryPreviewWidget.ui index d78b04a4..961e7550 100644 --- a/src/gui/EntryPreviewWidget.ui +++ b/src/gui/EntryPreviewWidget.ui @@ -705,6 +705,62 @@ Autotype + + + + + 0 + + + 0 + + + 0 + + + 5 + + + + + + 0 + 0 + + + + + 75 + true + + + + Default Sequence + + + Qt::AlignRight|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + sequence + + + Qt::AlignLeft|Qt::AlignVCenter + + + + + + diff --git a/tests/gui/TestGui.cpp b/tests/gui/TestGui.cpp index 4ab29ce3..7c24b0fc 100644 --- a/tests/gui/TestGui.cpp +++ b/tests/gui/TestGui.cpp @@ -29,14 +29,18 @@ #include #include #include +#include #include #include #include +#include #include #include +#include #include #include #include +#include #include "config-keepassx-tests.h" #include "core/Bootstrap.h" @@ -142,6 +146,9 @@ void TestGui::init() fileDialog()->setNextFileName(m_dbFilePath); triggerAction("actionDatabaseOpen"); + QApplication::processEvents(); + + m_dbWidget = m_tabWidget->currentDatabaseWidget(); auto* databaseOpenWidget = m_tabWidget->currentDatabaseWidget()->findChild("databaseOpenWidget"); QVERIFY(databaseOpenWidget); auto* editPassword = databaseOpenWidget->findChild("editPassword"); @@ -151,8 +158,10 @@ void TestGui::init() QTest::keyClicks(editPassword, "a"); QTest::keyClick(editPassword, Qt::Key_Enter); - m_dbWidget = m_tabWidget->currentDatabaseWidget(); + QTRY_VERIFY(!m_dbWidget->isLocked()); m_db = m_dbWidget->database(); + + QApplication::processEvents(); } // Every test ends with closing the temp database without saving @@ -1484,6 +1493,163 @@ void TestGui::testTrayRestoreHide() trayIcon->activated(QSystemTrayIcon::DoubleClick); QTRY_VERIFY(!m_mainWindow->isVisible()); + + // Ensure window is visible at the end + trayIcon->activated(QSystemTrayIcon::DoubleClick); + QTRY_VERIFY(m_mainWindow->isVisible()); +} + +void TestGui::testAutoType() +{ + // Clear entries from root group to guarantee order + for (Entry* entry : m_db->rootGroup()->entries()) { + m_db->rootGroup()->removeEntry(entry); + } + Tools::wait(150); + + // 1. Create an entry with Auto-Type disabled + + // 1.a) Click the new entry button and set the title + auto* entryNewAction = m_mainWindow->findChild("actionEntryNew"); + QVERIFY(entryNewAction->isEnabled()); + + auto* toolBar = m_mainWindow->findChild("toolBar"); + QVERIFY(toolBar); + + QWidget* entryNewWidget = toolBar->widgetForAction(entryNewAction); + QVERIFY(entryNewWidget->isVisible()); + QVERIFY(entryNewWidget->isEnabled()); + + QTest::mouseClick(entryNewWidget, Qt::LeftButton); + QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::Mode::EditMode); + + auto* editEntryWidget = m_dbWidget->findChild("editEntryWidget"); + QVERIFY(editEntryWidget); + + auto* titleEdit = editEntryWidget->findChild("titleEdit"); + QVERIFY(titleEdit); + + QTest::keyClicks(titleEdit, "1. Entry With Disabled Auto-Type"); + + auto* usernameComboBox = editEntryWidget->findChild("usernameComboBox"); + QVERIFY(usernameComboBox); + + QTest::mouseClick(usernameComboBox, Qt::LeftButton); + QTest::keyClicks(usernameComboBox, "AutocompletionUsername"); + + // 1.b) Uncheck Auto-Type checkbox + editEntryWidget->setCurrentPage(3); + auto* enableAutoTypeButton = editEntryWidget->findChild("enableButton"); + QVERIFY(enableAutoTypeButton); + QVERIFY(enableAutoTypeButton->isVisible()); + QVERIFY(enableAutoTypeButton->isEnabled()); + + enableAutoTypeButton->click(); + QVERIFY(!enableAutoTypeButton->isChecked()); + + // 1.c) Save changes + editEntryWidget->setCurrentPage(0); + auto* editEntryWidgetButtonBox = editEntryWidget->findChild("buttonBox"); + QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton); + + // 2. Create an entry with default/inherited Auto-Type sequence + + // 2.a) Click the new entry button and set the title + QTest::mouseClick(entryNewWidget, Qt::LeftButton); + QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::Mode::EditMode); + QTest::keyClicks(titleEdit, "2. Entry With Default Auto-Type Sequence"); + QTest::mouseClick(usernameComboBox, Qt::LeftButton); + QTest::keyClicks(usernameComboBox, "AutocompletionUsername"); + + // 2.b) Confirm AutoType is enabled and default + editEntryWidget->setCurrentPage(3); + QVERIFY(enableAutoTypeButton->isChecked()); + auto* inheritSequenceButton = editEntryWidget->findChild("inheritSequenceButton"); + QVERIFY(inheritSequenceButton->isChecked()); + + // 2.c) Save changes + editEntryWidget->setCurrentPage(0); + QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton); + + // 3. Create an entry with custom Auto-Type sequence + + // 3.a) Click the new entry button and set the title + QTest::mouseClick(entryNewWidget, Qt::LeftButton); + QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::Mode::EditMode); + QTest::keyClicks(titleEdit, "3. Entry With Custom Auto-Type Sequence"); + QTest::mouseClick(usernameComboBox, Qt::LeftButton); + QTest::keyClicks(usernameComboBox, "AutocompletionUsername"); + + // 3.b) Confirm AutoType is enabled and set custom sequence + editEntryWidget->setCurrentPage(3); + QVERIFY(enableAutoTypeButton->isChecked()); + auto* customSequenceButton = editEntryWidget->findChild("customSequenceButton"); + QTest::mouseClick(customSequenceButton, Qt::LeftButton); + QVERIFY(customSequenceButton->isChecked()); + QVERIFY(!inheritSequenceButton->isChecked()); + auto* sequenceEdit = editEntryWidget->findChild("sequenceEdit"); + QVERIFY(sequenceEdit); + sequenceEdit->setFocus(); + QTRY_VERIFY(sequenceEdit->hasFocus()); + QTest::keyClicks(sequenceEdit, "{USERNAME}{TAB}{TAB}{PASSWORD}{ENTER}"); + + // 3.c) Save changes + editEntryWidget->setCurrentPage(0); + QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton); + QApplication::processEvents(); + + // Check total number of entries matches expected + auto* entryView = m_dbWidget->findChild("entryView"); + QVERIFY(entryView); + QTRY_COMPARE(entryView->model()->rowCount(), 3); + + // Sort entries by title + entryView->sortByColumn(1, Qt::AscendingOrder); + + // Select first entry + entryView->selectionModel()->clearSelection(); + QModelIndex entryIndex = entryView->model()->index(0, 0); + entryView->selectionModel()->select(entryIndex, QItemSelectionModel::Rows | QItemSelectionModel::Select); + + auto* entryPreviewWidget = m_dbWidget->findChild("previewWidget"); + QVERIFY(entryPreviewWidget->isVisible()); + + // Check that the Autotype tab in entry preview pane is disabled for entry with disabled Auto-Type + auto* entryAutotypeTab = entryPreviewWidget->findChild("entryAutotypeTab"); + QVERIFY(!entryAutotypeTab->isEnabled()); + + // Check that Auto-Type is disabled in the actual entry model as well + Entry* entry = entryView->entryFromIndex(entryIndex); + QVERIFY(!entry->autoTypeEnabled()); + + // Select second entry + entryView->selectionModel()->clearSelection(); + entryIndex = entryView->model()->index(1, 0); + entryView->selectionModel()->select(entryIndex, QItemSelectionModel::Rows | QItemSelectionModel::Select); + QVERIFY(entryPreviewWidget->isVisible()); + + // Check that the Autotype tab in entry preview pane is enabled for entry with default Auto-Type sequence; + QVERIFY(entryAutotypeTab->isEnabled()); + + // Check that Auto-Type is enabled in the actual entry model as well + entry = entryView->entryFromIndex(entryIndex); + QVERIFY(entry->autoTypeEnabled()); + + // Select third entry + entryView->selectionModel()->clearSelection(); + entryIndex = entryView->model()->index(2, 0); + entryView->selectionModel()->select(entryIndex, QItemSelectionModel::Rows | QItemSelectionModel::Select); + QVERIFY(entryPreviewWidget->isVisible()); + + // Check that the Autotype tab in entry preview pane is enabled for entry with custom Auto-Type sequence + QVERIFY(entryAutotypeTab->isEnabled()); + + // Check that Auto-Type is enabled in the actual entry model as well + entry = entryView->entryFromIndex(entryIndex); + QVERIFY(entry->autoTypeEnabled()); + + // De-select third entry + entryView->selectionModel()->clearSelection(); } int TestGui::addCannedEntries() diff --git a/tests/gui/TestGui.h b/tests/gui/TestGui.h index 8d82e021..5bfc0426 100644 --- a/tests/gui/TestGui.h +++ b/tests/gui/TestGui.h @@ -68,6 +68,7 @@ private slots: void testDatabaseLocking(); void testDragAndDropKdbxFiles(); void testSortGroups(); + void testAutoType(); void testTrayRestoreHide(); private: