From c288a48fdc591bf047e2d66f089bde557d948657 Mon Sep 17 00:00:00 2001 From: Felix Ernst Date: Thu, 7 Jul 2022 10:41:39 +0000 Subject: [PATCH] Add two autotests - The first test makes sure that the width of the places panel doesn't change no matter what other panels are shown or hidden. There used to be bugs about this. - The second test is kind of an integration test. It makes sure that the go actions work correctly. On two occasions we had the regression here that after going "Up" in the file system hierarchy the folder one emerged from didn't have keyboard focus which makes peeking into multiple folders tiresome. The test also makes sure that going back and forward works as expected and there are some sanity checks about which go actions are enabled, which items are selected and that using tabs doesn't interfere with any of that. --- src/dolphinmainwindow.h | 1 + src/tests/CMakeLists.txt | 2 +- src/tests/dolphinmainwindowtest.cpp | 155 +++++++++++++++++++++++++++- src/views/dolphinview.h | 1 + 4 files changed, 157 insertions(+), 2 deletions(-) diff --git a/src/dolphinmainwindow.h b/src/dolphinmainwindow.h index e26bf50dd4..b86b6b4f32 100644 --- a/src/dolphinmainwindow.h +++ b/src/dolphinmainwindow.h @@ -710,6 +710,7 @@ private: QMenu m_searchTools; KFileItemActions m_fileItemActions; + friend class DolphinMainWindowTest; }; inline DolphinViewContainer* DolphinMainWindow::activeViewContainer() const diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 64003850c5..d4a7457cb5 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -57,7 +57,7 @@ TEST_NAME viewpropertiestest LINK_LIBRARIES dolphinprivate dolphinstatic Qt${QT_MAJOR_VERSION}::Test) # DolphinMainWindowTest -ecm_add_test(dolphinmainwindowtest.cpp ${CMAKE_SOURCE_DIR}/src/dolphin.qrc +ecm_add_test(dolphinmainwindowtest.cpp testdir.cpp ${CMAKE_SOURCE_DIR}/src/dolphin.qrc TEST_NAME dolphinmainwindowtest LINK_LIBRARIES dolphinprivate dolphinstatic Qt${QT_MAJOR_VERSION}::Test) diff --git a/src/tests/dolphinmainwindowtest.cpp b/src/tests/dolphinmainwindowtest.cpp index b40d3dbbf7..448d5bd84b 100644 --- a/src/tests/dolphinmainwindowtest.cpp +++ b/src/tests/dolphinmainwindowtest.cpp @@ -9,9 +9,12 @@ #include "dolphintabpage.h" #include "dolphintabwidget.h" #include "dolphinviewcontainer.h" +#include "kitemviews/kitemlistcontainer.h" +#include "testdir.h" #include +#include #include #include #include @@ -33,7 +36,9 @@ private Q_SLOTS: void testNewFileMenuEnabled(); void testWindowTitle_data(); void testWindowTitle(); - + void testPlacesPanelWidthResistance(); + void testGoActions(); + void cleanupTestCase(); private: @@ -264,6 +269,154 @@ void DolphinMainWindowTest::testWindowTitle() QCOMPARE(m_mainWindow->windowTitle(), expectedWindowTitle); } +/** + * The places panel will resize itself if any of the other widgets requires too much horizontal space + * but a user never wants the size of the places panel to change unless they resized it themselves explicitly. + */ +void DolphinMainWindowTest::testPlacesPanelWidthResistance() +{ + m_mainWindow->openDirectories({ QUrl::fromLocalFile(QDir::homePath()) }, false); + m_mainWindow->show(); + QVERIFY(QTest::qWaitForWindowExposed(m_mainWindow.data())); + QVERIFY(m_mainWindow->isVisible()); + + QWidget *placesPanel = reinterpret_cast(m_mainWindow->m_placesPanel); + QVERIFY2(QTest::qWaitFor([&](){ return placesPanel && placesPanel->isVisible() && placesPanel->width() > 0; }, 5000), "The test couldn't be initialised properly. The places panel should be visible."); + QTest::qWait(100); + const int initialPlacesPanelWidth = placesPanel->width(); + + m_mainWindow->actionCollection()->action(QStringLiteral("split_view"))->trigger(); // enable split view (starts animation) + QTest::qWait(300); // wait for animation + QCOMPARE(placesPanel->width(), initialPlacesPanelWidth); + + m_mainWindow->actionCollection()->action(QStringLiteral("show_filter_bar"))->trigger(); + QCOMPARE(placesPanel->width(), initialPlacesPanelWidth); + + m_mainWindow->actionCollection()->action(KStandardAction::name(KStandardAction::Find))->trigger(); + QCOMPARE(placesPanel->width(), initialPlacesPanelWidth); + +#if HAVE_BALOO + m_mainWindow->actionCollection()->action(QStringLiteral("show_information_panel"))->setChecked(true); // toggle visible + QCOMPARE(placesPanel->width(), initialPlacesPanelWidth); +#endif + +#if HAVE_TERMINAL + m_mainWindow->actionCollection()->action(QStringLiteral("show_terminal_panel"))->setChecked(true); // toggle visible + QCOMPARE(placesPanel->width(), initialPlacesPanelWidth); +#endif + + m_mainWindow->actionCollection()->action(QStringLiteral("split_view"))->trigger(); // disable split view (starts animation) + QCOMPARE(placesPanel->width(), initialPlacesPanelWidth); + +#if HAVE_BALOO + m_mainWindow->actionCollection()->action(QStringLiteral("show_information_panel"))->trigger(); // toggle invisible + QCOMPARE(placesPanel->width(), initialPlacesPanelWidth); +#endif + +#if HAVE_TERMINAL + m_mainWindow->actionCollection()->action(QStringLiteral("show_terminal_panel"))->trigger(); // toggle invisible + QCOMPARE(placesPanel->width(), initialPlacesPanelWidth); +#endif + + m_mainWindow->showMaximized(); + QCOMPARE(placesPanel->width(), initialPlacesPanelWidth); + + QTest::qWait(300); // wait for split view closing animation + QCOMPARE(placesPanel->width(), initialPlacesPanelWidth); +} + +void DolphinMainWindowTest::testGoActions() +{ + QScopedPointer testDir{new TestDir()}; + testDir->createDir("a"); + testDir->createDir("b"); + testDir->createDir("c"); + QUrl childDirUrl(QDir::cleanPath(testDir->url().toString() + "/b")); + m_mainWindow->openDirectories({ childDirUrl }, false); // Open "b" dir + m_mainWindow->show(); + QVERIFY(QTest::qWaitForWindowExposed(m_mainWindow.data())); + QVERIFY(m_mainWindow->isVisible()); + QVERIFY(!m_mainWindow->actionCollection()->action(KStandardAction::name(KStandardAction::Forward))->isEnabled()); + + m_mainWindow->actionCollection()->action(KStandardAction::name(KStandardAction::Up))->trigger(); + /** + * Now, after going "up" in the file hierarchy (to "testDir"), the folder one has emerged from ("b") should have keyboard focus. + * This is especially important when a user wants to peek into multiple folders in quick succession. + */ + QSignalSpy spyDirectoryLoadingCompleted(m_mainWindow->m_activeViewContainer->view(), &DolphinView::directoryLoadingCompleted); + QVERIFY(spyDirectoryLoadingCompleted.wait()); + QVERIFY(QTest::qWaitFor([&](){ return !m_mainWindow->actionCollection()->action(QStringLiteral("stop"))->isEnabled(); })); // "Stop" command should be disabled because it finished loading + QTest::qWait(500); // Somehow the item we emerged from doesn't have keyboard focus yet if we don't wait a split second. + const QUrl parentDirUrl = m_mainWindow->activeViewContainer()->url(); + QVERIFY(parentDirUrl != childDirUrl); + + // The item we just emerged from should now have keyboard focus but this doesn't necessarily mean that it is selected. + // To test if it has keyboard focus, we press "Down" to select "c" below and then "Up" so the folder "b" we just emerged from is actually selected. + m_mainWindow->actionCollection()->action(QStringLiteral("compact"))->trigger(); + QTest::keyClick(m_mainWindow->activeViewContainer()->view()->m_container, Qt::Key::Key_Down, Qt::NoModifier); + QCOMPARE(m_mainWindow->m_activeViewContainer->view()->selectedItems().count(), 1); + QTest::keyClick(m_mainWindow->activeViewContainer()->view()->m_container, Qt::Key::Key_Up, Qt::NoModifier); + QCOMPARE(m_mainWindow->m_activeViewContainer->view()->selectedItems().count(), 1); + QTest::keyClick(m_mainWindow->activeViewContainer()->view()->m_container, Qt::Key::Key_Enter, Qt::NoModifier); + QVERIFY(spyDirectoryLoadingCompleted.wait()); + QCOMPARE(m_mainWindow->activeViewContainer()->url(), childDirUrl); + QVERIFY(m_mainWindow->isUrlOpen(childDirUrl.toString())); + + // Go back to the parent folder + m_mainWindow->actionCollection()->action(KStandardAction::name(KStandardAction::Back))->trigger(); + QVERIFY(spyDirectoryLoadingCompleted.wait()); + QTest::qWait(100); // Somehow the item we emerged from doesn't have keyboard focus yet if we don't wait a split second. + QCOMPARE(m_mainWindow->activeViewContainer()->url(), parentDirUrl); + QVERIFY(m_mainWindow->isUrlOpen(parentDirUrl.toString())); + + // Open a new tab for the "b" child dir and verify that this doesn't interfere with anything. + QTest::keyClick(m_mainWindow->activeViewContainer()->view()->m_container, Qt::Key::Key_Enter, Qt::ControlModifier); // Open new inactive tab + QVERIFY(m_mainWindow->m_tabWidget->count() == 2); + QCOMPARE(m_mainWindow->activeViewContainer()->url(), parentDirUrl); + QVERIFY(m_mainWindow->isUrlOpen(parentDirUrl.toString())); + QVERIFY(!m_mainWindow->actionCollection()->action(QStringLiteral("undo_close_tab"))->isEnabled()); + + // Go forward to the child folder. + m_mainWindow->actionCollection()->action(KStandardAction::name(KStandardAction::Forward))->trigger(); + QVERIFY(spyDirectoryLoadingCompleted.wait()); + QCOMPARE(m_mainWindow->activeViewContainer()->url(), childDirUrl); + QCOMPARE(m_mainWindow->m_activeViewContainer->view()->selectedItems().count(), 0); // There was no action in this view yet that would warrant a selection. + + // Go back to the parent folder. + m_mainWindow->actionCollection()->action(KStandardAction::name(KStandardAction::Back))->trigger(); + QVERIFY(spyDirectoryLoadingCompleted.wait()); + QTest::qWait(100); // Somehow the item we emerged from doesn't have keyboard focus yet if we don't wait a split second. + QCOMPARE(m_mainWindow->activeViewContainer()->url(), parentDirUrl); + QVERIFY(m_mainWindow->isUrlOpen(parentDirUrl.toString())); + + // Close current tab and see if the "go" actions are correctly disabled in the remaining tab that was never active until now and shows the "b" dir + m_mainWindow->actionCollection()->action(KStandardAction::name(KStandardAction::Close))->trigger(); // Close current tab + QVERIFY(m_mainWindow->m_tabWidget->count() == 1); + QCOMPARE(m_mainWindow->activeViewContainer()->url(), childDirUrl); + QCOMPARE(m_mainWindow->m_activeViewContainer->view()->selectedItems().count(), 0); // There was no action in this tab yet that would warrant a selection. + QVERIFY(!m_mainWindow->actionCollection()->action(KStandardAction::name(KStandardAction::Back))->isEnabled()); + QVERIFY(!m_mainWindow->actionCollection()->action(KStandardAction::name(KStandardAction::Forward))->isEnabled()); + QVERIFY(m_mainWindow->actionCollection()->action(QStringLiteral("undo_close_tab"))->isEnabled()); +} + +void DolphinMainWindowTest::cleanupTestCase() +{ + m_mainWindow->showNormal(); + m_mainWindow->actionCollection()->action(QStringLiteral("split_view"))->setChecked(false); // disable split view (starts animation) + +#if HAVE_BALOO + m_mainWindow->actionCollection()->action(QStringLiteral("show_information_panel"))->setChecked(false); // hide panel +#endif + +#if HAVE_TERMINAL + m_mainWindow->actionCollection()->action(QStringLiteral("show_terminal_panel"))->setChecked(false); // hide panel +#endif + + // Quit Dolphin to save the hiding of panels and make sure that normal Quit doesn't crash. + m_mainWindow->actionCollection()->action(KStandardAction::name(KStandardAction::Quit))->trigger(); +} + + QTEST_MAIN(DolphinMainWindowTest) #include "dolphinmainwindowtest.moc" diff --git a/src/views/dolphinview.h b/src/views/dolphinview.h index f3ba9445f2..d1ecf74ba7 100644 --- a/src/views/dolphinview.h +++ b/src/views/dolphinview.h @@ -919,6 +919,7 @@ private: // For unit tests friend class TestBase; friend class DolphinDetailsViewTest; + friend class DolphinMainWindowTest; friend class DolphinPart; // Accesses m_model };