OSDN Git Service

GUITests: Add InsallerTest.cpp
authorTakashi Sawanaka <sdottaka@users.sourceforge.net>
Sat, 8 Aug 2020 09:53:46 +0000 (18:53 +0900)
committerTakashi Sawanaka <sdottaka@users.sourceforge.net>
Sat, 8 Aug 2020 09:53:46 +0000 (18:53 +0900)
Testing/GoogleTest/GUITests/GUITestUtils.cpp
Testing/GoogleTest/GUITests/GUITestUtils.h
Testing/GoogleTest/GUITests/GUITests.vs2017.vcxproj
Testing/GoogleTest/GUITests/GUITests.vs2017.vcxproj.filters
Testing/GoogleTest/GUITests/GUITests.vs2019.vcxproj
Testing/GoogleTest/GUITests/GUITests.vs2019.vcxproj.filters
Testing/GoogleTest/GUITests/InstallerTest.cpp [new file with mode: 0644]

index bd1e9d1..2ed65d4 100644 (file)
@@ -101,6 +101,20 @@ void typeKey(unsigned char vk)
        keybd_event(vk, 0, KEYEVENTF_KEYUP, 0);\r
 }\r
 \r
+void nextControl()\r
+{\r
+       keybd_event(VK_TAB, 0, 0, 0);\r
+       keybd_event(VK_TAB, 0, KEYEVENTF_KEYUP, 0);\r
+}\r
+\r
+void prevControl()\r
+{\r
+       keybd_event(VK_SHIFT, 0, 0, 0);\r
+       keybd_event(VK_TAB, 0, 0, 0);\r
+       keybd_event(VK_TAB, 0, KEYEVENTF_KEYUP, 0);\r
+       keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0);\r
+}\r
+\r
 std::filesystem::path getModuleFileName()\r
 {\r
        wchar_t szPath[256];\r
@@ -147,6 +161,20 @@ std::filesystem::path getExecutablePath()
        return "C:\\Program Files\\WinMerge\\WinMergeU.exe";\r
 }\r
 \r
+std::filesystem::path getInstallerPath()\r
+{\r
+       int argc;\r
+       wchar_t** argv = CommandLineToArgvW(GetCommandLineW(), &argc);\r
+       for (int arg = 0; arg < argc; ++arg)\r
+       {\r
+               auto argstr = std::wstring(argv[arg]);\r
+               size_t pos = argstr.find(_T("--installerpath="), 0);\r
+               if (pos != std::wstring::npos)\r
+                       return argstr.substr(pos + std::size("--installerpath=") - 1);\r
+       }\r
+       return "../../../Build/WinMerge-2.16.7.0-x64-PerUser-Setup.exe";\r
+}\r
+\r
 HWND execWinMerge(const std::string& args)\r
 {\r
        HWND hwndWinMerge = nullptr;\r
@@ -165,6 +193,25 @@ HWND execWinMerge(const std::string& args)
        return hwndWinMerge;\r
 }\r
 \r
+HWND execInstaller(const std::string& args)\r
+{\r
+       HWND hwndInstaller = nullptr;\r
+       auto command = "start \"\" \"" + getInstallerPath().string() + "\" " + args;\r
+       system(command.c_str());\r
+       Sleep(3000);\r
+       for (int i = 0; i < 50 && !hwndInstaller; ++i)\r
+       {\r
+               hwndInstaller = FindWindow(L"TWizardForm", nullptr);\r
+               Sleep(100);\r
+       }\r
+       if (hwndInstaller)\r
+       {\r
+               SwitchToThisWindow(hwndInstaller, TRUE);\r
+               waitForInputIdleByHWND(hwndInstaller);\r
+       }\r
+       return hwndInstaller;\r
+}\r
+\r
 const std::set<int> languages()\r
 {\r
        if (wcsstr(GetCommandLineW(), L"--all-languages") == nullptr)\r
@@ -208,5 +255,50 @@ MAKELANGID(LANG_UKRAINIAN, SUBLANG_DEFAULT),
        };\r
 }\r
 \r
+const char* languageIdToName(int id)\r
+{\r
+       static const std::map<int, const char*> map {\r
+{MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),"ENGLISH"},\r
+{MAKELANGID(LANG_ARABIC, SUBLANG_ARABIC_SAUDI_ARABIA),"ARABIC"},\r
+{MAKELANGID(LANG_BULGARIAN, SUBLANG_DEFAULT),"BULGARIAN"},\r
+{MAKELANGID(LANG_CATALAN, SUBLANG_DEFAULT),"CATALAN"},\r
+{MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),"CHINESE_SIMPLIFIED"},\r
+{MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL),"CHINESE_TRADITIONAL"},\r
+{MAKELANGID(LANG_CROATIAN, SUBLANG_DEFAULT),"CROATIAN"},\r
+{MAKELANGID(LANG_CZECH, SUBLANG_DEFAULT),"CZECH"},\r
+{MAKELANGID(LANG_DANISH, SUBLANG_DEFAULT),"DANISH"},\r
+{MAKELANGID(LANG_DUTCH, SUBLANG_DUTCH),"DUTCH"},\r
+{MAKELANGID(LANG_FARSI, SUBLANG_DEFAULT),"PERSIAN"},\r
+{MAKELANGID(LANG_FINNISH, SUBLANG_FINNISH_FINLAND),"FINNISH"},\r
+{MAKELANGID(LANG_FRENCH, SUBLANG_FRENCH),"FRENCH"},\r
+{MAKELANGID(LANG_GALICIAN, SUBLANG_DEFAULT),"GALICIAN"},\r
+{MAKELANGID(LANG_GERMAN, SUBLANG_GERMAN),"GERMAN"},\r
+{MAKELANGID(LANG_GREEK, SUBLANG_DEFAULT),"GREEK"},\r
+{MAKELANGID(LANG_HUNGARIAN, SUBLANG_DEFAULT),"HUNGARIAN"},\r
+{MAKELANGID(LANG_ITALIAN, SUBLANG_ITALIAN),"ITALIAN"},\r
+{MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT),"JAPANESE"},\r
+{MAKELANGID(LANG_KOREAN, SUBLANG_DEFAULT),"KOREAN"},\r
+{MAKELANGID(LANG_LITHUANIAN, SUBLANG_DEFAULT),"LITHUANIAN"},\r
+{MAKELANGID(LANG_NORWEGIAN, SUBLANG_DEFAULT),"NORWEGIAN"},\r
+{MAKELANGID(LANG_POLISH, SUBLANG_DEFAULT),"POLISH"},\r
+{MAKELANGID(LANG_PORTUGUESE, SUBLANG_PORTUGUESE),"PORTUGUESE"},\r
+{MAKELANGID(LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN),"PORTUGUESEBRAZILIAN"},\r
+{MAKELANGID(LANG_ROMANIAN, SUBLANG_DEFAULT),"ROMANIAN"},\r
+{MAKELANGID(LANG_RUSSIAN, SUBLANG_DEFAULT),"RUSSIAN"},\r
+{MAKELANGID(LANG_SERBIAN, SUBLANG_SERBIAN_CYRILLIC),"SERBIAN"},\r
+{MAKELANGID(LANG_SINHALESE, SUBLANG_DEFAULT),"SINHALA"},\r
+{MAKELANGID(LANG_SLOVAK, SUBLANG_DEFAULT),"SLOVAK"},\r
+{MAKELANGID(LANG_SLOVENIAN, SUBLANG_SLOVENIAN_SLOVENIA),"SLOVENIAN"},\r
+{MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_MODERN),"SPANISH"},\r
+{MAKELANGID(LANG_SWEDISH, SUBLANG_DEFAULT),"SWEDISH"},\r
+{MAKELANGID(LANG_TURKISH, SUBLANG_DEFAULT),"TURKISH"},\r
+{MAKELANGID(LANG_UKRAINIAN, SUBLANG_DEFAULT),"UKRAINIAN"},\r
+       };\r
+\r
+       if (map.find(id) != map.end())\r
+               return map.find(id)->second;\r
+       return "";\r
+}\r
+\r
 }\r
 \r
index be7c1dd..9e86345 100644 (file)
@@ -11,6 +11,8 @@ namespace GUITestUtils
        void typeText(const wchar_t *text);\r
        void typeAltPlusKey(char key);\r
        void typeKey(unsigned char vk);\r
+       void nextControl();\r
+       void prevControl();\r
        std::filesystem::path getModuleFileName();\r
        std::filesystem::path getModuleFolder();\r
        bool isMenuItemChecked(HWND hwnd, int id);\r
@@ -20,7 +22,9 @@ namespace GUITestUtils
        void selectMenu(HWND hwnd, unsigned id, bool async = false);\r
        inline void selectMenuAsync(HWND hwnd, unsigned id) { selectMenu(hwnd, id, true); };\r
        HWND execWinMerge(const std::string& args = "/noprefs /maxmize");\r
+       HWND execInstaller(const std::string& args = "");\r
        const std::set<int> languages();\r
+       const char * languageIdToName(int id);\r
 }\r
 \r
 #define selectMenuAndSaveWindowImage(id) selectMenuAndSaveWindowImageHelper(id, #id)\r
@@ -72,7 +76,7 @@ public:
                time_t t = GUITestUtils::getStartTime();\r
                localtime_s(&tm, &t);\r
                strftime(buf, sizeof buf, "%FT%H%M%S", &tm);\r
-               screenshotFolder = GUITestUtils::getModuleFolder() / L"..\\..\\..\\Build\\GUITests\\Screenshots" / buf / std::to_wstring(GetParam());\r
+               screenshotFolder = GUITestUtils::getModuleFolder() / "..\\..\\..\\Build\\GUITests\\Screenshots" / buf / GUITestUtils::languageIdToName(GetParam());\r
                std::error_code ec;\r
                std::filesystem::create_directories(screenshotFolder, ec);\r
                return screenshotFolder;\r
@@ -80,7 +84,9 @@ public:
 \r
        std::filesystem::path getScreenshotFilePath(const char *id = nullptr)\r
        {\r
-               std::string basename = ::testing::UnitTest::GetInstance()->current_test_info()->test_case_name();\r
+               std::string basename = GUITestUtils::languageIdToName(GetParam());\r
+               basename.append(".");\r
+               basename.append(::testing::UnitTest::GetInstance()->current_test_info()->test_case_name());\r
                basename.append(".");\r
                basename.append(::testing::UnitTest::GetInstance()->current_test_info()->name());\r
                if (id && id[0])\r
index d295900..09d68a7 100644 (file)
     </ClCompile>\r
     <ClCompile Include="DirFrameTest.cpp" />\r
     <ClCompile Include="GUITestUtils.cpp" />\r
+    <ClCompile Include="InstallerTest.cpp" />\r
     <ClCompile Include="MainFrameTest.cpp" />\r
     <ClCompile Include="OptionsDialogTest.cpp" />\r
     <ClCompile Include="pch.cpp">\r
index 934e5fe..b8e1a7a 100644 (file)
@@ -69,6 +69,9 @@
     <ClCompile Include="OptionsDialogTest.cpp">\r
       <Filter>Source Files</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="InstallerTest.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ClInclude Include="..\..\..\Externals\gtest\include\gtest\internal\gtest-string.h">\r
index 135a139..1431aa1 100644 (file)
     </ClCompile>\r
     <ClCompile Include="DirFrameTest.cpp" />\r
     <ClCompile Include="GUITestUtils.cpp" />\r
+    <ClCompile Include="InstallerTest.cpp" />\r
     <ClCompile Include="MainFrameTest.cpp" />\r
     <ClCompile Include="OptionsDialogTest.cpp" />\r
     <ClCompile Include="pch.cpp">\r
index 934e5fe..b8e1a7a 100644 (file)
@@ -69,6 +69,9 @@
     <ClCompile Include="OptionsDialogTest.cpp">\r
       <Filter>Source Files</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="InstallerTest.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ClInclude Include="..\..\..\Externals\gtest\include\gtest\internal\gtest-string.h">\r
diff --git a/Testing/GoogleTest/GUITests/InstallerTest.cpp b/Testing/GoogleTest/GUITests/InstallerTest.cpp
new file mode 100644 (file)
index 0000000..d097123
--- /dev/null
@@ -0,0 +1,90 @@
+/** 
+ * @file  InstallerTest.cpp
+ *
+ * @brief Implementation for Installer testcase.
+ */
+
+#include "pch.h"
+#include "Resource.h"
+
+namespace
+{
+
+using namespace GUITestUtils;
+
+class InstallerTest : public CommonTest
+{
+public:
+       InstallerTest()
+       {
+               std::string lang = languageIdToName(GetParam());
+               m_hwndWinMerge = execInstaller(("/LANG=" + lang).c_str());
+       }
+
+       virtual ~InstallerTest()
+       {
+               // You can do clean-up work     that doesn't throw exceptions here.
+               PostMessage(m_hwndWinMerge, WM_CLOSE, 0, 0);
+               waitUntilProcessExit(m_hwndWinMerge);
+       }
+
+       static void SetUpTestCase()
+       {
+               // You can do set-up work for each test here.
+       }
+
+       static void TearDownTestCase()
+       {
+       }
+
+       // If   the     constructor     and     destructor are not enough for setting up
+       // and cleaning up each test, you can define the following methods:
+       virtual void SetUp()
+       {
+               // Code here will be called     immediately     after the constructor (right
+               // before each test).
+       }
+
+       virtual void TearDown()
+       {
+               // Code here will be called     immediately     after each test (right
+               // before the destructor).
+       }
+
+       // Objects declared here can be used by all tests in the test case for Foo.
+};
+
+TEST_P(InstallerTest, Pages)
+{
+       saveImage("LicenseAgreement");
+       typeKey(VK_RETURN); Sleep(200);
+       saveImage("SelectComponents");
+       typeKey(VK_RETURN); Sleep(200);
+       saveImage("SelectAdditionalTasks");
+       typeKey(VK_RETURN); Sleep(200);
+       saveImage("3-WayMerge");
+       typeKey(VK_RETURN); Sleep(200);
+       saveImage("ReadyToInstall");
+       typeKey(VK_RETURN); Sleep(200);
+       Sleep(15000);
+       saveImage("Information");
+       typeKey(VK_RETURN); Sleep(200);
+       saveImage("CompletingTheWinMergeSetupWizard");
+       typeKey(VK_RETURN); Sleep(1000);
+       
+       for (;;)
+       {
+               HWND hwndWinMerge = FindWindow(L"WinMergeWindowClassW", nullptr);
+               if (!hwndWinMerge)
+                       break;
+               PostMessage(hwndWinMerge, WM_CLOSE, 0, 0);
+               Sleep(100);
+       }
+}
+
+}
+
+INSTANTIATE_TEST_CASE_P(InstallerTestInstance,
+       InstallerTest,
+       testing::ValuesIn(GUITestUtils::languages()));
+