tests/ide_tests/load_and_build_tests.pytest/test_application.py
branchwxPython4
changeset 3438 24fbd4d1fe80
parent 3328 01682a34a558
child 3581 5a0f7fcf9a8f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/ide_tests/load_and_build_tests.pytest/test_application.py	Fri Mar 11 14:43:37 2022 +0100
@@ -0,0 +1,232 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# This file is part of Beremiz, a Integrated Development Environment for
+# programming IEC 61131-3 automates supporting plcopen standard and CanFestival.
+#
+# Copyright (C) 2017: Andrey Skvortsov
+#
+# See COPYING file for copyrights details.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+
+from __future__ import absolute_import
+from __future__ import print_function
+import os
+import sys
+import unittest
+import time
+
+import six
+import pytest
+import wx
+import ddt
+
+import conftest
+import Beremiz
+import PLCOpenEditor
+
+
+class UserApplicationTest(unittest.TestCase):
+    def InstallExceptionHandler(self):
+        def handle_exception(e_type, e_value, e_traceback, exit=False):
+            # traceback.print_exception(e_type, e_value, e_traceback)
+            self.exc_info = [e_type, e_value, e_traceback]
+        self.exc_info = None
+        self.old_excepthook = sys.excepthook
+        sys.excepthook = handle_exception
+
+    def StartApp(self):
+        self.app = None
+
+    def FinishApp(self):
+        wx.CallAfter(self.app.frame.Close)
+        self.app.MainLoop()
+        self.app = None
+
+    def setUp(self):
+        self.app = None
+
+    def tearDown(self):
+        if self.app is not None and self.app.frame is not None:
+            self.FinishApp()
+
+    def RunUIActions(self, actions):
+        for act in actions:
+            wx.CallAfter(*act)
+            self.ProcessEvents()
+
+    def CheckForErrors(self):
+        if self.exc_info is not None:
+            # reraise catched previously exception
+            exc_type = self.exc_info[0]
+            exc_value = self.exc_info[1]
+            exc_traceback = self.exc_info[2]
+            six.reraise(exc_type, exc_value, exc_traceback)
+
+    def ProcessEvents(self):
+        for dummy in range(0, 30):
+            self.CheckForErrors()
+            wx.Yield()
+            time.sleep(0.01)
+
+
+@ddt.ddt
+class BeremizApplicationTest(UserApplicationTest):
+    """Test Beremiz as whole application"""
+
+    def StartApp(self):
+        self.app = Beremiz.BeremizIDELauncher()
+        # disable default exception handler in Beremiz
+        self.app.InstallExceptionHandler = lambda: None
+        self.InstallExceptionHandler()
+        self.app.handle_exception = sys.excepthook
+        self.app.PreStart()
+        self.ProcessEvents()
+        self.app.frame.Show()
+        self.ProcessEvents()
+        self.app.frame.ShowFullScreen(True)
+        self.ProcessEvents()
+
+    def FinishApp(self):
+        wx.CallAfter(self.app.frame.Close)
+        self.app.MainLoop()
+        time.sleep(1)
+        self.app = None
+
+    def GetSkippedProjectTreeItems(self):
+        """
+        Returns the list of skipped items in the project tree.
+
+        Beremiz test don't need to skip any elemnts in the project tree.
+        """
+        return []
+
+    def OpenAllProjectElements(self):
+        """Open editor for every object in the project tree"""
+        self.app.frame.ProjectTree.ExpandAll()
+        self.ProcessEvents()
+        item = self.app.frame.ProjectTree.GetRootItem()
+        skip = self.GetSkippedProjectTreeItems()
+        tree_id = self.app.frame.ProjectTree.GetId()
+        while item is not None:
+            self.app.frame.ProjectTree.SelectItem(item, True)
+            self.ProcessEvents()
+            if item not in skip:
+                event = wx.lib.agw.customtreectrl.TreeEvent(
+                    wx.lib.agw.customtreectrl.wxEVT_TREE_ITEM_ACTIVATED,
+                    tree_id, item)
+                self.app.frame.OnProjectTreeItemActivated(event)
+            self.ProcessEvents()
+            item = self.app.frame.ProjectTree.GetNextVisible(item)
+
+    def CheckTestProject(self, project):
+        sys.argv = ["", project]
+        self.StartApp()
+        self.OpenAllProjectElements()
+        user_actions = self.GetUserActions()
+        self.RunUIActions(user_actions)
+        self.FinishApp()
+
+    def GetProjectPath(self, project):
+        return os.path.abspath(os.path.join(os.path.dirname(__file__), "..","..","projects", project))
+
+    def GetUserActions(self):
+        """
+        Returns list of user actions that will be executed
+        on every test project by testCheckProject test.
+        """
+        user_actions = [
+            [self.app.frame.SwitchFullScrMode, None],
+            [self.app.frame.SwitchFullScrMode, None],
+            [self.app.frame.CTR._Clean],
+            [self.app.frame.CTR._Build],
+            [self.app.frame.CTR._Connect],
+            [self.app.frame.CTR._Transfer],
+            [self.app.frame.CTR._Run],
+            [self.app.frame.CTR._Stop],
+            [self.app.frame.CTR._Disconnect],
+            [self.app.frame.CTR._Clean],
+        ]
+        return user_actions
+
+    def testStartUp(self):
+        """Checks whether the app starts and finishes correctly"""
+        sys.argv = [""]
+        self.StartApp()
+        self.FinishApp()
+
+    # TODO: also use "exemples/*" projects
+    @ddt.data(
+        #"first_steps",
+        "logging",
+        #"traffic_lights",
+        #"wxGlade",
+        #"python",
+        #"wiimote",
+        # "wxHMI",
+    )
+    @pytest.mark.timeout(300)
+    def testCheckProject(self, name):
+        """
+        Checks that test PLC project can be open,
+        compiled and run on SoftPLC.
+        """
+        project = self.GetProjectPath(name)
+        print("Testing example " + name)
+        self.CheckTestProject(project)
+
+
+# class PLCOpenEditorApplicationTest(BeremizApplicationTest):
+#     """Test PLCOpenEditor as whole application"""
+# 
+#     def StartApp(self):
+#         self.app = PLCOpenEditor.PLCOpenEditorApp()
+#         # disable default exception handler in application
+#         self.app.InstallExceptionHandler = lambda: None
+#         self.InstallExceptionHandler()
+#         self.app.Show()
+#         self.ProcessEvents()
+#         self.app.frame.ShowFullScreen(True)
+#         self.ProcessEvents()
+# 
+#     def FinishApp(self):
+#         wx.CallAfter(self.app.frame.Close)
+#         self.app.MainLoop()
+#         time.sleep(1)
+#         self.app = None
+# 
+#     def GetSkippedProjectTreeItems(self):
+#         """
+#         Returns the list of skipped items in the project tree.
+# 
+#         Root item opens dialog window for project settings.
+#         To avoid code that handles closing dialog windows just skip this item.
+#         """
+#         return [self.app.frame.ProjectTree.GetRootItem()]
+# 
+#     def GetUserActions(self):
+#         return []
+# 
+#     def GetProjectPath(self, project):
+#         """Open PLC program in every Beremiz test project"""
+#         project_dir = BeremizApplicationTest.GetProjectPath(self, project)
+#         return os.path.join(project_dir, "plc.xml")
+# 
+
+if __name__ == '__main__':
+    conftest.init_environment()
+    unittest.main()