ソースを参照

Fix PM tests writing to manifest (#10168)

* Avoid creating unnecessary application

Application was just needed to show the Progress window

Signed-off-by: Alex Peterson <[email protected]>

* Avoid writing manifest when in project tests

Signed-off-by: Alex Peterson <[email protected]>

* Avoid modifying manifest in application tests

Also a speed boost from avoiding the PythonBindings calls

Signed-off-by: Alex Peterson <[email protected]>

* Simplify string output and update test

Removed warning when python finalize is not called, because that's a valid state if it was never initialzed, for example, when running unit tests.

Signed-off-by: Alex Peterson <[email protected]>

* Fix using pybind literals and simplify OnStdError

Signed-off-by: Alex Peterson <[email protected]>

* Clarify the clarification

Signed-off-by: Alex Peterson <[email protected]>

* Narrow scope of using namespace

Signed-off-by: Alex Peterson <[email protected]>
Alex Peterson 3 年 前
コミット
692cc4062d

+ 3 - 2
Code/Tools/ProjectManager/Source/Application.cpp

@@ -31,7 +31,7 @@ namespace O3DE::ProjectManager
         TearDown();
     }
 
-    bool Application::Init(bool interactive)
+    bool Application::Init(bool interactive, AZStd::unique_ptr<PythonBindings> pythonBindings)
     {
         constexpr const char* applicationName { "O3DE" };
 
@@ -73,7 +73,8 @@ namespace O3DE::ProjectManager
         // Set window icon after QGuiApplication is created otherwise QPixmap for the icon fails to intialize
         QApplication::setWindowIcon(QIcon(":/ProjectManager-Icon.ico"));
 
-        m_pythonBindings = AZStd::make_unique<PythonBindings>(GetEngineRoot());
+        // unit tests may provide custom python bindings 
+        m_pythonBindings = pythonBindings ? AZStd::move(pythonBindings) : AZStd::make_unique<PythonBindings>(GetEngineRoot());
 
         if (!m_pythonBindings->PythonStarted())
         {

+ 1 - 1
Code/Tools/ProjectManager/Source/Application.h

@@ -29,7 +29,7 @@ namespace O3DE::ProjectManager
         using AzFramework::Application::Application;
         virtual ~Application();
 
-        bool Init(bool interactive = true);
+        bool Init(bool interactive = true, AZStd::unique_ptr<PythonBindings> pythonBindings = nullptr);
         bool Run();
         void TearDown();
 

+ 40 - 26
Code/Tools/ProjectManager/Source/ProjectUtils.cpp

@@ -151,7 +151,7 @@ namespace O3DE::ProjectManager
 
             for (const QString& directory : original.entryList(QDir::Dirs | QDir::NoDotAndDotDot))
             {
-                if (progressDialog->wasCanceled())
+                if (progressDialog && progressDialog->wasCanceled())
                 {
                     return false;
                 }
@@ -173,10 +173,10 @@ namespace O3DE::ProjectManager
             }
 
             QLocale locale;
-            const float progressDialogRangeHalf = static_cast<float>(qFabs(progressDialog->maximum() - progressDialog->minimum()) * 0.5f);
+            const float progressDialogRangeHalf = progressDialog ? static_cast<float>(qFabs(progressDialog->maximum() - progressDialog->minimum()) * 0.5f) : 0.f;
             for (const QString& file : original.entryList(QDir::Files))
             {
-                if (progressDialog->wasCanceled())
+                if (progressDialog && progressDialog->wasCanceled())
                 {
                     return false;
                 }
@@ -189,6 +189,7 @@ namespace O3DE::ProjectManager
                 }
 
                 // Progress window update
+                if (progressDialog)
                 {
                     // Weight in the number of already copied files as well as the copied bytes to get a better progress indication
                     // for cases combining many small files and some really large files.
@@ -331,7 +332,7 @@ namespace O3DE::ProjectManager
             return copyResult;
         }
 
-        bool CopyProject(const QString& origPath, const QString& newPath, QWidget* parent, bool skipRegister)
+        bool CopyProject(const QString& origPath, const QString& newPath, QWidget* parent, bool skipRegister, bool showProgress)
         {
             // Disallow copying from or into subdirectory
             if (IsDirectoryDescedent(origPath, newPath) || IsDirectoryDescedent(newPath, origPath))
@@ -347,28 +348,35 @@ namespace O3DE::ProjectManager
                 ProjectCacheDirectoryName
             };
 
-            QProgressDialog* progressDialog = new QProgressDialog(parent);
-            progressDialog->setAutoClose(true);
-            progressDialog->setValue(0);
-            progressDialog->setRange(0, 1000);
-            progressDialog->setModal(true);
-            progressDialog->setWindowTitle(QObject::tr("Copying project ..."));
-            progressDialog->show();
+            QProgressDialog* progressDialog = nullptr;
+            if (showProgress)
+            {
+                progressDialog = new QProgressDialog(parent);
+                progressDialog->setAutoClose(true);
+                progressDialog->setValue(0);
+                progressDialog->setRange(0, 1000);
+                progressDialog->setModal(true);
+                progressDialog->setWindowTitle(QObject::tr("Copying project ..."));
+                progressDialog->show();
+            }
 
             QLocale locale;
             QStringList getFilesSkippedPaths(skippedPaths);
             RecursiveGetAllFiles(origPath, getFilesSkippedPaths, filesToCopyCount, totalSizeInBytes, [=](int fileCount, int sizeInBytes)
                 {
-                    // Create a human-readable version of the file size.
-                    const QString fileSizeString = locale.formattedDataSize(sizeInBytes);
-
-                    progressDialog->setLabelText(QString("%1 ... %2 %3, %4 %5.")
-                        .arg(QObject::tr("Indexing files"))
-                        .arg(QString::number(fileCount))
-                        .arg(QObject::tr("files found"))
-                        .arg(fileSizeString)
-                        .arg(QObject::tr("to copy")));
-                    qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
+                    if (progressDialog)
+                    {
+                        // Create a human-readable version of the file size.
+                        const QString fileSizeString = locale.formattedDataSize(sizeInBytes);
+
+                        progressDialog->setLabelText(QString("%1 ... %2 %3, %4 %5.")
+                            .arg(QObject::tr("Indexing files"))
+                            .arg(QString::number(fileCount))
+                            .arg(QObject::tr("files found"))
+                            .arg(fileSizeString)
+                            .arg(QObject::tr("to copy")));
+                        qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
+                    }
                 });
 
             int numFilesCopied = 0;
@@ -387,13 +395,19 @@ namespace O3DE::ProjectManager
 
             if (!success)
             {
-                progressDialog->setLabelText(QObject::tr("Duplicating project failed/cancelled, removing already copied files ..."));
-                qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
+                if (progressDialog)
+                {
+                    progressDialog->setLabelText(QObject::tr("Duplicating project failed/cancelled, removing already copied files ..."));
+                    qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
+                }
 
                 DeleteProjectFiles(newPath, true);
             }
 
-            progressDialog->deleteLater();
+            if (progressDialog)
+            {
+                progressDialog->deleteLater();
+            }
             return success;
         }
 
@@ -412,7 +426,7 @@ namespace O3DE::ProjectManager
             return false;
         }
 
-        bool MoveProject(QString origPath, QString newPath, QWidget* parent, bool skipRegister)
+        bool MoveProject(QString origPath, QString newPath, QWidget* parent, bool skipRegister, bool showProgress)
         {
             origPath = QDir::toNativeSeparators(origPath);
             newPath = QDir::toNativeSeparators(newPath);
@@ -430,7 +444,7 @@ namespace O3DE::ProjectManager
             if (!newDirectory.rename(origPath, newPath))
             {
                 // Likely failed because trying to move to another partition, try copying
-                if (!CopyProject(origPath, newPath, parent))
+                if (!CopyProject(origPath, newPath, parent, skipRegister, showProgress))
                 {
                     return false;
                 }

+ 2 - 2
Code/Tools/ProjectManager/Source/ProjectUtils.h

@@ -25,9 +25,9 @@ namespace O3DE::ProjectManager
         bool RegisterProject(const QString& path);
         bool UnregisterProject(const QString& path);
         bool CopyProjectDialog(const QString& origPath, ProjectInfo& newProjectInfo, QWidget* parent = nullptr);
-        bool CopyProject(const QString& origPath, const QString& newPath, QWidget* parent, bool skipRegister = false);
+        bool CopyProject(const QString& origPath, const QString& newPath, QWidget* parent, bool skipRegister = false, bool showProgress = true);
         bool DeleteProjectFiles(const QString& path, bool force = false);
-        bool MoveProject(QString origPath, QString newPath, QWidget* parent, bool skipRegister = false);
+        bool MoveProject(QString origPath, QString newPath, QWidget* parent, bool skipRegister = false, bool showProgress = true);
 
         bool ReplaceProjectFile(const QString& origFile, const QString& newFile, QWidget* parent = nullptr, bool interactive = true);
 

+ 16 - 21
Code/Tools/ProjectManager/Source/PythonBindings.cpp

@@ -224,7 +224,6 @@ namespace RedirectOutput
 
 namespace O3DE::ProjectManager
 {
-
     PythonBindings::PythonBindings(const AZ::IO::PathView& enginePath)
         : m_enginePath(enginePath)
     {
@@ -238,25 +237,21 @@ namespace O3DE::ProjectManager
 
     void PythonBindings::OnStdOut(const char* msg)
     {
-        AZStd::string message{ msg };
-        // escape % characters by using %% in the format string to avoid crashing
-        AZ::StringFunc::Replace(message, "%", "%%", true /* case sensitive since it is faster */);
-        AZ_TracePrintf("Python", message.c_str());
+        AZ::Debug::Trace::Output("Python", msg);
     }
 
     void PythonBindings::OnStdError(const char* msg)
     {
-        AZStd::string lastPythonError = msg;
-        constexpr const char* pythonErrorPrefix = "ERROR:root:";
-        constexpr size_t lengthOfErrorPrefix = AZStd::char_traits<char>::length(pythonErrorPrefix);
-        auto errorPrefix = lastPythonError.find(pythonErrorPrefix);
-        if (errorPrefix != AZStd::string::npos)
+        AZStd::string_view lastPythonError{ msg };
+        if (constexpr AZStd::string_view pythonErrorPrefix = "ERROR:root:";
+            lastPythonError.starts_with(pythonErrorPrefix))
         {
-            lastPythonError.erase(errorPrefix, lengthOfErrorPrefix);
+            lastPythonError = lastPythonError.substr(pythonErrorPrefix.size());
         }
-        O3DE::ProjectManager::PythonBindingsInterface::Get()->AddErrorString(lastPythonError);
 
-        OnStdOut(msg);
+        PythonBindingsInterface::Get()->AddErrorString(lastPythonError);
+
+        AZ::Debug::Trace::Output("Python", msg);
     }
 
     bool PythonBindings::PythonStarted()
@@ -346,10 +341,7 @@ namespace O3DE::ProjectManager
             RedirectOutput::Shutdown();
             pybind11::finalize_interpreter();
         }
-        else
-        {
-            AZ_Warning("ProjectManagerWindow", false, "Did not finalize since Py_IsInitialized() was false");
-        }
+
         return !PyErr_Occurred();
     }
 
@@ -733,16 +725,19 @@ namespace O3DE::ProjectManager
         return result && registrationResult;
     }
 
-    AZ::Outcome<ProjectInfo> PythonBindings::CreateProject(const QString& projectTemplatePath, const ProjectInfo& projectInfo)
+    AZ::Outcome<ProjectInfo> PythonBindings::CreateProject(const QString& projectTemplatePath, const ProjectInfo& projectInfo, bool registerProject)
     {
+        using namespace pybind11::literals;
+
         ProjectInfo createdProjectInfo;
         bool result = ExecuteWithLock([&] {
             auto projectPath = QString_To_Py_Path(projectInfo.m_path);
 
             auto createProjectResult = m_engineTemplate.attr("create_project")(
-                projectPath,
-                QString_To_Py_String(projectInfo.m_projectName), // project_path
-                QString_To_Py_Path(projectTemplatePath)          // template_path
+                "project_path"_a = projectPath,
+                "project_name"_a = QString_To_Py_String(projectInfo.m_projectName),
+                "template_path"_a = QString_To_Py_Path(projectTemplatePath),
+                "no_register"_a = !registerProject
             );
             if (createProjectResult.cast<int>() == 0)
             {

+ 1 - 1
Code/Tools/ProjectManager/Source/PythonBindings.h

@@ -47,7 +47,7 @@ namespace O3DE::ProjectManager
         AZ::Outcome<void, AZStd::string> UnregisterGem(const QString& gemPath, const QString& projectPath = {}) override;
 
         // Project
-        AZ::Outcome<ProjectInfo> CreateProject(const QString& projectTemplatePath, const ProjectInfo& projectInfo) override;
+        AZ::Outcome<ProjectInfo> CreateProject(const QString& projectTemplatePath, const ProjectInfo& projectInfo, bool registerProject = true) override;
         AZ::Outcome<ProjectInfo> GetProject(const QString& path) override;
         AZ::Outcome<QVector<ProjectInfo>> GetProjects() override;
         bool AddProject(const QString& path) override;

+ 2 - 1
Code/Tools/ProjectManager/Source/PythonBindingsInterface.h

@@ -126,9 +126,10 @@ namespace O3DE::ProjectManager
          * Create a project 
          * @param projectTemplatePath the path to the project template to use 
          * @param projectInfo the project info to use 
+         * @param registerProject whether to register the project or not
          * @return an outcome with ProjectInfo on success 
          */
-        virtual AZ::Outcome<ProjectInfo> CreateProject(const QString& projectTemplatePath, const ProjectInfo& projectInfo) = 0;
+        virtual AZ::Outcome<ProjectInfo> CreateProject(const QString& projectTemplatePath, const ProjectInfo& projectInfo, bool registerProject = true) = 0;
         
         /**
          * Get info about a project 

+ 1 - 0
Code/Tools/ProjectManager/project_manager_tests_files.cmake

@@ -13,6 +13,7 @@ set(FILES
     tests/GemCatalogTests.cpp
     tests/SettingsTests.cpp
     tests/PythonBindingsTests.cpp
+    tests/MockPythonBindings.h
     tests/main.cpp
     tests/UtilsTests.cpp
     tests/TextOverflowTests.cpp

+ 21 - 4
Code/Tools/ProjectManager/tests/ApplicationTests.cpp

@@ -10,6 +10,7 @@
 #include <AzCore/std/smart_ptr/make_shared.h>
 #include <Application.h>
 #include <ProjectManager_Test_Traits_Platform.h>
+#include "MockPythonBindings.h"
 
 namespace O3DE::ProjectManager
 {
@@ -17,13 +18,12 @@ namespace O3DE::ProjectManager
         : public ::UnitTest::ScopedAllocatorSetupFixture
     {
     public:
-
-        ProjectManagerApplicationTests()
+        void SetUp() override
         {
             m_application = AZStd::make_unique<ProjectManager::Application>();
         }
 
-        ~ProjectManagerApplicationTests()
+        void TearDown() override
         {
             m_application.reset();
         }
@@ -37,7 +37,24 @@ namespace O3DE::ProjectManager
     TEST_F(ProjectManagerApplicationTests, Application_Init_Succeeds)
 #endif // !AZ_TRAIT_DISABLE_FAILED_PROJECT_MANAGER_TESTS
     {
+        using ::testing::NiceMock;
+        using ::testing::Return;
+
+        // mock python bindings because those have separate tests and we want
+        // to avoid modifying the manifest that other tests may be trying to read
+        auto pythonBindings = AZStd::make_unique<NiceMock<MockPythonBindings>>();
+
+        EngineInfo engineInfo;
+        engineInfo.m_registered = true;
+        ON_CALL(*pythonBindings, GetEngineInfo()).WillByDefault(Return(AZ::Success(AZStd::move(engineInfo))));
+        ON_CALL(*pythonBindings, PythonStarted()).WillByDefault(Return(true));
+        ON_CALL(*pythonBindings, StopPython()).WillByDefault(Return(true));
+
+        // gem repos currently pop up a messagebox if no gem repos are found
+        // so we must return an empty list
+        ON_CALL(*pythonBindings, GetAllGemRepoInfos()).WillByDefault(Return(AZ::Success(QVector<GemRepoInfo>())));
+
         // we don't want to interact with actual GUI or display it
-        EXPECT_TRUE(m_application->Init(/*interactive=*/false));
+        EXPECT_TRUE(m_application->Init(/*interactive=*/false, AZStd::move(pythonBindings)));
     }
 }

+ 65 - 0
Code/Tools/ProjectManager/tests/MockPythonBindings.h

@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+#pragma once
+
+#include <PythonBindings.h>
+#include <gmock/gmock.h>
+
+namespace O3DE::ProjectManager
+{
+    class MockPythonBindings : public PythonBindings
+    {
+    public:
+        // Python
+        MOCK_METHOD0(PythonStarted, bool());
+        MOCK_METHOD0(StopPython, bool());
+
+        // Engine
+        MOCK_METHOD0(GetEngineInfo, AZ::Outcome<EngineInfo>());
+        MOCK_METHOD1(GetEngineInfo, AZ::Outcome<EngineInfo>(const QString&));
+        MOCK_METHOD2(SetEngineInfo, DetailedOutcome(const EngineInfo&, bool force));
+
+        // Gem
+        MOCK_METHOD2(GetGemInfo, AZ::Outcome<GemInfo>(const QString&, const QString&));
+        MOCK_METHOD0(GetEngineGemInfos, AZ::Outcome<QVector<GemInfo>, AZStd::string>());
+        MOCK_METHOD1(GetAllGemInfos, AZ::Outcome<QVector<GemInfo>, AZStd::string>(const QString&));
+        MOCK_METHOD1(GetEnabledGemNames, AZ::Outcome<QVector<AZStd::string>, AZStd::string>(const QString&));
+        MOCK_METHOD2(RegisterGem, AZ::Outcome<void, AZStd::string>(const QString&, const QString&));
+        MOCK_METHOD2(UnregisterGem, AZ::Outcome<void, AZStd::string>(const QString&, const QString&));
+
+        // Project
+        MOCK_METHOD3(CreateProject, AZ::Outcome<ProjectInfo>(const QString&, const ProjectInfo&, bool));
+        MOCK_METHOD1(GetProject, AZ::Outcome<ProjectInfo>(const QString&));
+        MOCK_METHOD0(GetProjects, AZ::Outcome<QVector<ProjectInfo>>());
+        MOCK_METHOD1(AddProject, bool(const QString&));
+        MOCK_METHOD1(RemoveProject, bool(const QString&));
+        MOCK_METHOD1(UpdateProject, AZ::Outcome<void, AZStd::string>(const ProjectInfo&));
+        MOCK_METHOD2(AddGemToProject, AZ::Outcome<void, AZStd::string>(const QString&, const QString&));
+        MOCK_METHOD2(RemoveGemFromProject, AZ::Outcome<void, AZStd::string>(const QString&, const QString&));
+        MOCK_METHOD0(RemoveInvalidProjects, bool());
+
+        // ProjectTemplate
+        MOCK_METHOD1(GetProjectTemplates, AZ::Outcome<QVector<ProjectTemplateInfo>>(const QString&));
+
+        // Gem Repos
+        MOCK_METHOD1(RefreshGemRepo, AZ::Outcome<void, AZStd::string>(const QString&));
+        MOCK_METHOD0(RefreshAllGemRepos, bool());
+        MOCK_METHOD1(AddGemRepo, DetailedOutcome(const QString&));
+        MOCK_METHOD1(RemoveGemRepo, bool(const QString&));
+        MOCK_METHOD0(GetAllGemRepoInfos, AZ::Outcome<QVector<GemRepoInfo>, AZStd::string>());
+        MOCK_METHOD1(GetGemInfosForRepo, AZ::Outcome<QVector<GemInfo>, AZStd::string>(const QString&));
+        MOCK_METHOD0(GetGemInfosForAllRepos, AZ::Outcome<QVector<GemInfo>, AZStd::string>());
+        MOCK_METHOD3(DownloadGem, DetailedOutcome(const QString&, std::function<void(int, int)>, bool));
+        MOCK_METHOD0(CancelDownload, void());
+        MOCK_METHOD2(IsGemUpdateAvaliable, bool(const QString&, const QString&));
+
+        // Errors
+        MOCK_METHOD1(AddErrorString, void(AZStd::string));
+        MOCK_METHOD0(ClearErrorStrings, void());
+    };
+} // namespace UnitTest

+ 12 - 5
Code/Tools/ProjectManager/tests/PythonBindingsTests.cpp

@@ -35,6 +35,14 @@ namespace O3DE::ProjectManager
         {
             PythonBindings::OnStdError(msg);
         }
+
+        //! override with an implementation that won't do anything
+        //! so we avoid modifying the manifest 
+        bool RemoveInvalidProjects() override
+        {
+            constexpr bool removalResult = true;
+            return removalResult;
+        }
     };
 
     class PythonBindingsTests 
@@ -55,7 +63,7 @@ namespace O3DE::ProjectManager
         }
 
         //! AZ::Debug::TraceMessageBus
-        bool OnPrintf(const char*, const char* message) override
+        bool OnOutput(const char*, const char* message) override
         {
             m_gatheredMessages.emplace_back(message);
             return true;
@@ -89,7 +97,8 @@ namespace O3DE::ProjectManager
         projectInfo.m_path = QDir::toNativeSeparators(QString(tempDir.GetDirectory()) + "/" + "TestProject");
         projectInfo.m_projectName = "TestProjectName";
 
-        auto result = m_pythonBindings->CreateProject(templatePath, projectInfo);
+        constexpr bool registerProject = false;
+        auto result = m_pythonBindings->CreateProject(templatePath, projectInfo, registerProject);
         EXPECT_TRUE(result.IsSuccess());
 
         ProjectInfo resultProjectInfo = result.GetValue();
@@ -102,7 +111,7 @@ namespace O3DE::ProjectManager
         bool testMessageFound = false;
         bool testErrorFound = false;
         const char* testMessage = "PythonTestMessage%";
-        const char* testError = "PythonTestError%";
+        const char* testError = "ERROR:root:PythonTestError%";
 
         AZ::Debug::TraceMessageBus::Handler::BusConnect();
 
@@ -111,8 +120,6 @@ namespace O3DE::ProjectManager
 
         AZ::Debug::TraceMessageBus::Handler::BusDisconnect();
 
-        // currently, PythonBindings sends errors to AZ_TracePrintf instead of AZ_Error
-        // if this changes, we'll need to handle OnError() and check that instead
         for (const auto& message : m_gatheredMessages)
         {
             if (message.contains(testMessage))

+ 8 - 15
Code/Tools/ProjectManager/tests/UtilsTests.cpp

@@ -35,9 +35,6 @@ namespace O3DE::ProjectManager
 
             ProjectManagerUtilsTests()
             {
-                m_application = AZStd::make_unique<ProjectManager::Application>();
-                m_application->Init(false);
-
                 m_projectAPath = "ProjectA";
 
                 // Replaces first 'A' with 'B'
@@ -87,12 +84,8 @@ namespace O3DE::ProjectManager
 
                 QDir dirB(m_projectBPath);
                 dirB.removeRecursively();
-
-                m_application.reset();
             }
 
-            AZStd::unique_ptr<ProjectManager::Application> m_application;
-
             QString m_projectAPath;
             QString m_projectAOrigFilePath;
             QString m_projectAReplaceFilePath;
@@ -114,8 +107,8 @@ namespace O3DE::ProjectManager
         {
             EXPECT_TRUE(MoveProject(
                 QDir::currentPath() + QDir::separator() + m_projectAPath,
-                QDir::currentPath() + QDir::separator() + m_projectBPath,
-                nullptr, true));
+                QDir::currentPath() + QDir::separator() + m_projectBPath, nullptr,
+                true, /*displayProgress=*/ false));
 
             QFileInfo origFile(m_projectAOrigFilePath);
             EXPECT_FALSE(origFile.exists());
@@ -138,8 +131,8 @@ namespace O3DE::ProjectManager
         {
             EXPECT_TRUE(MoveProject(
                 QDir::currentPath() + QDir::separator() + m_projectAPath,
-                QDir::currentPath() + QDir::separator() + m_projectBPath,
-                nullptr, true));
+                QDir::currentPath() + QDir::separator() + m_projectBPath, nullptr,
+                true, /*displayProgress=*/ false));
 
             QFileInfo origFile(m_projectAOrigFilePath);
             EXPECT_FALSE(origFile.exists());
@@ -159,8 +152,8 @@ namespace O3DE::ProjectManager
         {
             EXPECT_TRUE(CopyProject(
                 QDir::currentPath() + QDir::separator() + m_projectAPath,
-                QDir::currentPath() + QDir::separator() + m_projectBPath,
-                nullptr, true));
+                QDir::currentPath() + QDir::separator() + m_projectBPath, nullptr,
+                true, /*displayProgress=*/ false));
 
             QFileInfo origFile(m_projectAOrigFilePath);
             EXPECT_TRUE(origFile.exists());
@@ -183,8 +176,8 @@ namespace O3DE::ProjectManager
         {
             EXPECT_TRUE(CopyProject(
                 QDir::currentPath() + QDir::separator() + m_projectAPath,
-                QDir::currentPath() + QDir::separator() + m_projectBPath,
-                nullptr, true));
+                QDir::currentPath() + QDir::separator() + m_projectBPath, nullptr,
+                true, /*displayProgress=*/ false));
 
             QFileInfo origFile(m_projectAOrigFilePath);
             EXPECT_TRUE(origFile.exists());