ya2 · news · projects · code · about

external testing process
[pmachines.git] / lib / tools / functional_test.py
diff --git a/lib/tools/functional_test.py b/lib/tools/functional_test.py
new file mode 100644 (file)
index 0000000..09dc608
--- /dev/null
@@ -0,0 +1,366 @@
+'''Create ref:
+* M-x fla-set-fun-test
+* rm options.ini
+* python main.py --functional-test 1 --functional-ref
+* python main.py --functional-test 2 --functional-ref
+* M-x fla-unset-fun-test'''
+from panda3d.core import load_prc_file_data
+load_prc_file_data('', 'window-type none')
+import datetime
+from time import sleep
+from os import getcwd, system
+from multiprocessing.connection import Client
+from logging import debug, info
+from pathlib import Path
+from shutil import rmtree
+from os import makedirs
+from os.path import join, exists
+from glob import glob
+from sys import exit, argv
+from panda3d.core import Filename
+from direct.showbase.ShowBase import ShowBase
+from direct.gui.OnscreenText import OnscreenText
+from lib.gameobject import GameObject
+from lib.build.build import _branch
+
+
+class FunctionalTest(GameObject):
+
+    screenshot_time = 1.2
+    evt_time = 1.0
+    drag_time = 1.0
+    start_time = 2
+
+    def __init__(self, idx):
+        super().__init__()
+        info('test idx: %s' % idx)
+        sleep(5)
+        address = ('localhost', 6000)
+        self._conn = Client(address)
+        self._curr_time = 0
+        self._tasks = []
+        self._prev_time = 0
+        taskMgr.add(self.on_frame_unpausable, 'on-frame-unpausable')
+        self._do_screenshots(idx)
+
+    def _do_screenshot(self, name):
+        time = datetime.datetime.now().strftime('%y%m%d%H%M%S')
+        name = name + '.png'
+        self._conn.send(['screenshot', name])
+        info('screenshot %s' % name)
+
+    def _screenshot(self, time, name):
+        self._tasks += [(
+            self._curr_time + time,
+            lambda: self._do_screenshot(name),
+            'screenshot: %s' % name)]
+        self._curr_time += time
+
+    def __mouse_click(self, pos, btn):
+        offset_x = int((1920 - 1360) / 2) + 1  # xfce decorations
+        offset_y = int((1080 - 768) / 2) + 24  # xfce decorations
+        btn = 3 if btn == 'right' else 1
+        system('xdotool mousemove %s %s' % (offset_x + pos[0], offset_y + pos[1]))
+        def click(task):
+            system('xdotool click %s' % btn)
+        taskMgr.do_method_later(.01, click, 'click')
+
+    def __mouse_drag(self, start, end, btn):
+        offset_x = int((1920 - 1360) / 2) + 1  # xfce decorations
+        offset_y = int((1080 - 768) / 2) + 24  # xfce decorations
+        btn = 3 if btn == 'right' else 1
+        system('xdotool mousemove %s %s' % (offset_x + start[0], offset_y + start[1]))
+        def mousedown(task):
+            system('xdotool mousedown %s' % btn)
+            def mousemove(task):
+                system('xdotool mousemove %s %s' % (offset_x + end[0], offset_y + end[1]))
+                def mouseup(task):
+                    system('xdotool mouseup %s' % btn)
+                taskMgr.do_method_later(.28, mouseup, 'mouseup')
+            taskMgr.do_method_later(.28, mousemove, 'mousemove')
+        taskMgr.do_method_later(.28, mousedown, 'mousedown')
+
+    def _event(self, time, evt, mouse_args=None):
+        if evt == 'mouseclick':
+            cback = lambda: self.__mouse_click(*mouse_args)
+        elif evt == 'mousedrag':
+            cback = lambda: self.__mouse_drag(*mouse_args)
+        self._tasks += [(
+            self._curr_time + time,
+            cback,
+            'event: %s' % evt)]
+        self._curr_time += time
+
+    def _enforce_res(self, time, res):
+        def cback():
+            self._conn.send(['enforce_res', res])
+            info('enforce_res %s' % res)
+        self._tasks += [(
+            self._curr_time + time,
+            cback,
+            'enforce res: %s' % res)]
+        self._curr_time += time
+
+    def _verify(self):
+        def __verify():
+            self._conn.send(['verify'])
+            info('verify')
+        self._tasks += [(
+            self._curr_time + 3,
+            lambda: __verify(),
+            'verify')]
+        self._curr_time += 3
+
+    def _exit(self):
+        def do_exit():
+            self._conn.close()
+            exit()
+        self._tasks += [(
+            self._curr_time + 3,
+            lambda: do_exit(),
+            'exit')]
+
+    def on_frame_unpausable(self, task):
+        for tsk in self._tasks:
+            #if self._prev_time <= tsk[0] < self.eng.event.unpaused_time:
+            if self._prev_time <= tsk[0] < globalClock.getFrameTime():
+                debug('%s %s' % (tsk[0], tsk[2]))
+                tsk[1]()
+        self._prev_time = globalClock.getFrameTime()  # self.eng.event.unpaused_time
+        return task.cont
+
+    def _do_screenshots_1(self):
+        info('_do_screenshots_1')
+        self._screenshot(FunctionalTest.start_time, 'main_menu')
+        self._do_screenshots_credits()
+        self._do_screenshots_options()
+        self._do_screenshots_exit()
+
+    def _do_screenshots_credits(self):
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(680, 450), 'left'])
+        self._screenshot(FunctionalTest.screenshot_time, 'credits_menu')
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(680, 680), 'left'])
+        self._screenshot(FunctionalTest.screenshot_time, 'main_menu_back_from_credits')
+
+    def _do_screenshots_options(self):
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(680, 300), 'left'])
+        self._screenshot(FunctionalTest.screenshot_time, 'options_menu')
+        # languages
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(680, 60), 'left'])
+        self._screenshot(FunctionalTest.screenshot_time, 'open_languages')
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(980, 120), 'left'])
+        self._screenshot(FunctionalTest.screenshot_time, 'options_menu_italian')
+        # volume
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(740, 163), 'left'])
+        self._screenshot(FunctionalTest.screenshot_time, 'options_menu_drag_1')
+        # antialiasing
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(680, 440), 'left'])
+        self._screenshot(FunctionalTest.screenshot_time, 'antialiasing_no')
+        # shadows
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(680, 540), 'left'])
+        self._screenshot(FunctionalTest.screenshot_time, 'shadows_no')
+        # test aa and shadows
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(680, 680), 'left'])  # back
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(680, 140), 'left'])  # play
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(230, 160), 'left'])  # domino
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(900, 490), 'left'])  # close instructions
+        self._screenshot(FunctionalTest.screenshot_time, 'aa_no_shadows_no')
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(25, 740), 'left'])  # home
+
+    def _do_screenshots_restore_options(self):
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(680, 300), 'left'])
+        self._screenshot(FunctionalTest.screenshot_time, 'options_menu_restored')
+        # languages
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(680, 60), 'left'])
+        self._screenshot(FunctionalTest.screenshot_time, 'open_languages_restored')
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(980, 20), 'left'])
+        self._screenshot(FunctionalTest.screenshot_time, 'options_menu_english')
+        # volume
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(719, 163), 'left'])
+        self._screenshot(FunctionalTest.screenshot_time, 'options_menu_drag_2')
+        # fullscreen
+        # the first one is because of the windowed mode in test
+        # self._event(FunctionalTest.evt_time, 'mouseclick', [(680, 250), 'left'])
+        # self._screenshot(FunctionalTest.screenshot_time, 'fullscreen')
+        # self._event(FunctionalTest.evt_time, 'mouseclick', [(680, 250), 'left'])
+        # self._screenshot(FunctionalTest.screenshot_time, 'fullscreen')
+        # self._event(8 + FunctionalTest.evt_time, 'mouseclick', [(680, 250), 'left'])
+        # self._screenshot(8 + FunctionalTest.screenshot_time, 'back_from_fullscreen')
+        # resolution
+        # self._event(FunctionalTest.evt_time, 'mouseclick', [(680, 340), 'left'])
+        # self._screenshot(FunctionalTest.screenshot_time, 'resolutions')
+        # self._event(FunctionalTest.evt_time, 'mouseclick', [(1020, 160), 'left'])
+        # self._screenshot(FunctionalTest.screenshot_time, '1440x900')
+        # self._event(FunctionalTest.evt_time, 'mouseclick', [(740, 400), 'left'])
+        # self._screenshot(FunctionalTest.screenshot_time, 'resolutions_2')
+        # self._event(FunctionalTest.evt_time, 'mouseclick', [(1110, 80), 'left'])
+        # self._screenshot(FunctionalTest.screenshot_time, '1360x768')
+        # antialiasing
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(680, 440), 'left'])
+        self._screenshot(FunctionalTest.screenshot_time, 'antialiasing_yes')
+        # shadows
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(680, 540), 'left'])
+        self._screenshot(FunctionalTest.screenshot_time, 'shadows_yes')
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(680, 680), 'left'])  # back
+
+    def _do_screenshots_play(self):
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(680, 140), 'left'])  # play
+        self._screenshot(FunctionalTest.screenshot_time, 'play_menu')
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(680, 680), 'left'])  # back
+        self._screenshot(FunctionalTest.screenshot_time, 'back_from_play')
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(680, 140), 'left'])  # play
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(230, 160), 'left'])  # domino scene
+        self._screenshot(FunctionalTest.screenshot_time, 'scene_domino_instructions')
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(850, 490), 'left'])  # close instructions
+        self._screenshot(FunctionalTest.screenshot_time, 'scene_domino')
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(25, 740), 'left'])  # home
+        self._screenshot(FunctionalTest.screenshot_time, 'home_back_from_scene')
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(680, 140), 'left'])  # play
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(230, 160), 'left'])  # domino
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(850, 490), 'left'])  # close instructions
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(70, 740), 'left'])  # info
+        self._screenshot(FunctionalTest.screenshot_time, 'info')
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(850, 490), 'left'])  # close instructions
+        self._event(FunctionalTest.drag_time, 'mousedrag', [(35, 60), (430, 280), 'left'])  # drag a piece
+        self._screenshot(FunctionalTest.screenshot_time, 'domino_dragged')
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(1220, 740), 'left'])  # rewind
+        self._screenshot(FunctionalTest.screenshot_time, 'rewind')
+        self._event(FunctionalTest.drag_time, 'mousedrag', [(35, 60), (550, 380), 'left'])  # drag a piece
+        # self._event(FunctionalTest.drag_time, 'mousedrag', [(35, 60), (715, 380), 'left'])  # drag a piece
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(1340, 740), 'left'])  # play
+        self._screenshot(16 + FunctionalTest.screenshot_time, 'fail_domino')
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(630, 450), 'left'])  # home
+        self._screenshot(FunctionalTest.screenshot_time, 'home_back_from_fail')
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(680, 140), 'left'])  # play
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(230, 160), 'left'])  # domino
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(850, 490), 'left'])  # close instructions
+        self._event(FunctionalTest.drag_time, 'mousedrag', [(35, 60), (550, 380), 'left'])  # drag a piece
+        self._event(FunctionalTest.drag_time, 'mousedrag', [(35, 60), (715, 380), 'left'])  # drag a piece
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(1340, 740), 'left'])  # play
+        self._screenshot(16 + FunctionalTest.screenshot_time, 'fail_domino_2')
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(680, 450), 'left'])  # replay
+        self._event(FunctionalTest.drag_time, 'mousedrag', [(35, 60), (570, 380), 'left'])  # drag a piece
+        self._event(FunctionalTest.drag_time, 'mousedrag', [(570, 355), (605, 355), 'right'])  # rotate the piece
+        self._event(FunctionalTest.drag_time, 'mousedrag', [(35, 60), (715, 380), 'left'])  # drag a piece
+        self._enforce_res(FunctionalTest.evt_time, 'win')
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(1340, 740), 'left'])  # play
+        self._screenshot(16 + FunctionalTest.screenshot_time, 'win_domino')
+        self._enforce_res(FunctionalTest.evt_time, '')
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(735, 450), 'left'])  # next
+        self._screenshot(FunctionalTest.screenshot_time, 'scene_box')
+        # scene 2
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(880, 490), 'left'])  # close instructions
+        self._event(FunctionalTest.drag_time, 'mousedrag', [(65, 60), (710, 620), 'left'])  # drag a box
+        self._event(FunctionalTest.drag_time, 'mousedrag', [(65, 60), (710, 540), 'left'])  # drag a box
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(1340, 740), 'left'])  # play
+        self._screenshot(16 + FunctionalTest.screenshot_time, 'fail_box')
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(680, 450), 'left'])  # replay
+        self._event(FunctionalTest.drag_time, 'mousedrag', [(65, 60), (710, 620), 'left'])  # drag a box
+        self._event(FunctionalTest.drag_time, 'mousedrag', [(65, 60), (710, 540), 'left'])  # drag a box
+        self._event(FunctionalTest.drag_time, 'mousedrag', [(65, 60), (705, 460), 'left'])  # drag a box
+        self._enforce_res(FunctionalTest.evt_time, 'win')
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(1340, 740), 'left'])  # play
+        self._screenshot(16 + FunctionalTest.screenshot_time, 'win_box')
+        self._enforce_res(FunctionalTest.evt_time, '')
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(735, 450), 'left'])  # next
+        self._screenshot(FunctionalTest.screenshot_time, 'scene_box_domino')
+        # scene 3
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(930, 485), 'left'])  # close instructions
+        self._event(FunctionalTest.drag_time, 'mousedrag', [(65, 60), (910, 440), 'left'])  # drag a box
+        self._event(FunctionalTest.drag_time, 'mousedrag', [(65, 60), (910, 360), 'left'])  # drag a box
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(1340, 740), 'left'])  # play
+        self._screenshot(16 + FunctionalTest.screenshot_time, 'fail_box_domino')
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(680, 450), 'left'])  # replay
+        self._event(FunctionalTest.drag_time, 'mousedrag', [(65, 60), (910, 440), 'left'])  # drag a box
+        self._event(FunctionalTest.drag_time, 'mousedrag', [(65, 60), (835, 250), 'left'])  # drag a box
+        self._enforce_res(FunctionalTest.evt_time, 'win')
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(1340, 740), 'left'])  # play
+        self._screenshot(16 + FunctionalTest.screenshot_time, 'win_box_domino')
+        self._enforce_res(FunctionalTest.evt_time, '')
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(735, 450), 'left'])  # next
+        self._screenshot(FunctionalTest.screenshot_time, 'scene_basketball')
+        # scene 4
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(870, 490), 'left'])  # close instructions
+        self._event(FunctionalTest.drag_time, 'mousedrag', [(55, 50), (650, 310), 'left'])  # drag a ball
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(1340, 740), 'left'])  # play
+        self._screenshot(16 + FunctionalTest.screenshot_time, 'fail_basketball')
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(680, 450), 'left'])  # replay
+        self._event(FunctionalTest.drag_time, 'mousedrag', [(55, 50), (380, 50), 'left'])  # drag a ball
+        self._enforce_res(FunctionalTest.evt_time, 'win')
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(1340, 740), 'left'])  # play
+        self._screenshot(16 + FunctionalTest.screenshot_time, 'win_basketball')
+        self._enforce_res(FunctionalTest.evt_time, '')
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(735, 450), 'left'])  # next
+        self._screenshot(FunctionalTest.screenshot_time, 'scene_domino_box_basketball')
+        # scene 5
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(865, 490), 'left'])  # close instructions
+        self._event(FunctionalTest.drag_time, 'mousedrag', [(65, 60), (580, 440), 'left'])  # drag a box
+        self._event(FunctionalTest.drag_time, 'mousedrag', [(30, 60), (590, 370), 'left'])  # drag a piece
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(1340, 740), 'left'])  # play
+        self._screenshot(16 + FunctionalTest.screenshot_time, 'fail_domino_box_basketball')
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(680, 450), 'left'])  # replay
+        self._event(FunctionalTest.drag_time, 'mousedrag', [(65, 60), (580, 440), 'left'])  # drag a box
+        self._event(FunctionalTest.drag_time, 'mousedrag', [(30, 60), (660, 440), 'left'])  # drag a piece
+        self._event(FunctionalTest.drag_time, 'mousedrag', [(660, 425), (625, 425), 'right'])  # rotate a piece
+        self._event(FunctionalTest.drag_time, 'mousedrag', [(660, 435), (650, 445), 'left'])  # drag a piece
+        self._enforce_res(FunctionalTest.evt_time, 'win')
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(1340, 740), 'left'])  # play
+        self._screenshot(16 + FunctionalTest.screenshot_time, 'win_domino_box_basketball')
+        self._enforce_res(FunctionalTest.evt_time, '')
+        # self._event(FunctionalTest.evt_time, 'mouseclick', [(735, 450), 'left'])  # next
+        # self._screenshot(FunctionalTest.screenshot_time, 'scene_teeter_tooter')
+        # # scene 6
+        # self._event(FunctionalTest.evt_time, 'mouseclick', [(820, 455), 'left'])  # close instructions
+        # self._event(FunctionalTest.drag_time, 'mousedrag', [(60, 60), (490, 300), 'left'])  # drag a box
+        # self._event(FunctionalTest.evt_time, 'mouseclick', [(1260, 695), 'left'])  # play
+        # self._screenshot(16 + FunctionalTest.screenshot_time, 'fail_teeter_tooter')
+        # self._event(FunctionalTest.evt_time, 'mouseclick', [(640, 420), 'left'])  # replay
+        # self._event(FunctionalTest.drag_time, 'mousedrag', [(60, 60), (490, 150), 'left'])  # drag a box
+        # self._event(FunctionalTest.drag_time, 'mousedrag', [(515, 115), (515, 122), 'right'])  # rotate a box
+        # self._event(FunctionalTest.evt_time, 'mouseclick', [(1260, 695), 'left'])  # play
+        # self._screenshot(16 + FunctionalTest.screenshot_time, 'win_teeter_tooter')
+        # self._event(FunctionalTest.evt_time, 'mouseclick', [(690, 420), 'left'])  # next
+        # self._screenshot(FunctionalTest.screenshot_time, 'scene_teeter_domino_box_basketball')
+        # # scene 7
+        # self._event(FunctionalTest.evt_time, 'mouseclick', [(880, 455), 'left'])  # close instructions
+        # self._event(FunctionalTest.drag_time, 'mousedrag', [(60, 60), (155, 180), 'left'])  # drag a box
+        # self._event(FunctionalTest.evt_time, 'mouseclick', [(1260, 695), 'left'])  # play
+        # self._screenshot(16 + FunctionalTest.screenshot_time, 'fail_teeter_domino_box_basketball')
+        # self._event(FunctionalTest.evt_time, 'mouseclick', [(640, 420), 'left'])  # replay
+        # self._event(FunctionalTest.drag_time, 'mousedrag', [(60, 60), (170, 80), 'left'])  # drag a box
+        # self._event(FunctionalTest.drag_time, 'mousedrag', [(195, 50), (195, 80), 'right'])  # rotate a box
+        # self._event(FunctionalTest.evt_time, 'mouseclick', [(1260, 695), 'left'])  # play
+        # self._screenshot(16 + FunctionalTest.screenshot_time, 'win_teeter_domino_box_basketball')
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(630, 450), 'left'])  # home
+        self._screenshot(FunctionalTest.screenshot_time, 'home_from_play')
+
+    def _exit(self):
+        self._tasks += [(
+            self._curr_time + 3,
+            lambda: exit(),
+            'exit')]
+
+    def _do_screenshots_exit(self):
+        self._verify()
+        self._event(FunctionalTest.evt_time, 'mouseclick', [(680, 600), 'left'])
+        self._exit()
+
+    def _do_screenshots_2(self):
+        info('_do_screenshots_2')
+        self._screenshot(FunctionalTest.start_time, 'main_menu_2')
+        self._do_screenshots_restore_options()
+        self._do_screenshots_play()
+        self._do_screenshots_exit()
+
+    def _do_screenshots(self, idx):
+        [self._do_screenshots_1, self._do_screenshots_2][int(idx) - 1]()
+
+
+class TestApp(ShowBase):
+
+    def __init__(self):
+        ShowBase.__init__(self)
+        fun_test = FunctionalTest(int(argv[1]))
+
+
+TestApp().run()