diff --git a/AutomatedTesting/Gem/PythonTests/automatedtesting_shared/base.py b/AutomatedTesting/Gem/PythonTests/automatedtesting_shared/base.py index e6c28be2a5..f5cd66cbbe 100755 --- a/AutomatedTesting/Gem/PythonTests/automatedtesting_shared/base.py +++ b/AutomatedTesting/Gem/PythonTests/automatedtesting_shared/base.py @@ -51,8 +51,8 @@ class TestAutomationBase: cls.asset_processor.teardown() cls._kill_ly_processes() - - def _run_test(self, request, workspace, editor, testcase_module, extra_cmdline_args=[], use_null_renderer=True): + def _run_test(self, request, workspace, editor, testcase_module, extra_cmdline_args=[], batch_mode=True, + autotest_mode=True, use_null_renderer=True): test_starttime = time.time() self.logger = logging.getLogger(__name__) errors = [] @@ -90,9 +90,13 @@ class TestAutomationBase: editor_starttime = time.time() self.logger.debug("Running automated test") testcase_module_filepath = self._get_testcase_module_filepath(testcase_module) - pycmd = ["--runpythontest", testcase_module_filepath, "-BatchMode", "-autotest_mode", f"-pythontestcase={request.node.originalname}"] + pycmd = ["--runpythontest", testcase_module_filepath, f"-pythontestcase={request.node.originalname}"] if use_null_renderer: pycmd += ["-rhi=null"] + if batch_mode: + pycmd += ["-BatchMode"] + if autotest_mode: + pycmd += ["-autotest_mode"] pycmd += extra_cmdline_args editor.args.extend(pycmd) # args are added to the WinLauncher start command editor.start(backupFiles = False, launch_ap = False) diff --git a/AutomatedTesting/Gem/PythonTests/editor/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/editor/CMakeLists.txt index fa35bb25c6..bf42579970 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/editor/CMakeLists.txt @@ -11,8 +11,23 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ NAME AutomatedTesting::EditorTests_Main TEST_SUITE main TEST_SERIAL - PATH ${CMAKE_CURRENT_LIST_DIR} - PYTEST_MARKS "SUITE_main and not REQUIRES_gpu" + PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main.py + PYTEST_MARKS "not REQUIRES_gpu" + RUNTIME_DEPENDENCIES + Legacy::Editor + AZ::AssetProcessor + AutomatedTesting.Assets + COMPONENT + Editor + ) + + ly_add_pytest( + NAME AutomatedTesting::EditorTests_Main_GPU + TEST_SUITE main + TEST_SERIAL + TEST_REQUIRES gpu + PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main.py + PYTEST_MARKS "REQUIRES_gpu" RUNTIME_DEPENDENCIES Legacy::Editor AZ::AssetProcessor @@ -25,8 +40,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ NAME AutomatedTesting::EditorTests_Periodic TEST_SUITE periodic TEST_SERIAL - PATH ${CMAKE_CURRENT_LIST_DIR} - PYTEST_MARKS "SUITE_periodic and not REQUIRES_gpu" + PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Periodic.py RUNTIME_DEPENDENCIES Legacy::Editor AZ::AssetProcessor @@ -36,12 +50,39 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ ) ly_add_pytest( - NAME AutomatedTesting::EditorTests_Main_GPU + NAME AutomatedTesting::EditorTests_Sandbox + TEST_SUITE sandbox + TEST_SERIAL + PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Sandbox.py + RUNTIME_DEPENDENCIES + Legacy::Editor + AZ::AssetProcessor + AutomatedTesting.Assets + COMPONENT + Editor + ) + + ly_add_pytest( + NAME AutomatedTesting::EditorTests_Main_Optimized + TEST_SUITE main + TEST_SERIAL + PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main_Optimized.py + PYTEST_MARKS "not REQUIRES_gpu" + RUNTIME_DEPENDENCIES + Legacy::Editor + AZ::AssetProcessor + AutomatedTesting.Assets + COMPONENT + Editor + ) + + ly_add_pytest( + NAME AutomatedTesting::EditorTests_Main_GPU_Optimized TEST_SUITE main TEST_SERIAL TEST_REQUIRES gpu - PATH ${CMAKE_CURRENT_LIST_DIR} - PYTEST_MARKS "SUITE_main and REQUIRES_gpu" + PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main_Optimized.py + PYTEST_MARKS "REQUIRES_gpu" RUNTIME_DEPENDENCIES Legacy::Editor AZ::AssetProcessor @@ -51,11 +92,10 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ ) ly_add_pytest( - NAME AutomatedTesting::EditorTests_Sandbox + NAME AutomatedTesting::EditorTests_Sandbox_Optimized TEST_SUITE sandbox TEST_SERIAL - PATH ${CMAKE_CURRENT_LIST_DIR} - PYTEST_MARKS "SUITE_sandbox" + PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Sandbox_Optimized.py RUNTIME_DEPENDENCIES Legacy::Editor AZ::AssetProcessor @@ -63,4 +103,5 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ COMPONENT Editor ) + endif() diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetBrowser_SearchFiltering.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetBrowser_SearchFiltering.py index 60c8926eb2..33c48c7a77 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetBrowser_SearchFiltering.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetBrowser_SearchFiltering.py @@ -5,30 +5,24 @@ For complete copyright and license terms please see the LICENSE at the root of t SPDX-License-Identifier: Apache-2.0 OR MIT """ -""" -C13660194 : Asset Browser - Filtering -""" - -import os -import sys -from PySide2 import QtWidgets, QtTest, QtCore -from PySide2.QtCore import Qt -import azlmbr.legacy.general as general -import azlmbr.paths +class Tests: + asset_filtered = ( + "Asset was filtered to in the Asset Browser", + "Failed to filter to the expected asset" + ) + asset_type_filtered = ( + "Expected asset type was filtered to in the Asset Browser", + "Failed to filter to the expected asset type" + ) -sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests')) -import editor_python_test_tools.hydra_editor_utils as hydra -import editor_python_test_tools.pyside_utils as pyside_utils -from editor_python_test_tools.editor_test_helper import EditorTestHelper +def AssetBrowser_SearchFiltering(): -class AssetBrowserSearchFilteringTest(EditorTestHelper): - def __init__(self): - EditorTestHelper.__init__(self, log_prefix="AssetBrowser_SearchFiltering", args=["level"]) + import editor_python_test_tools.pyside_utils as pyside_utils @pyside_utils.wrap_async - async def run_test(self): + async def run_test(): """ Summary: Asset Browser - Filtering @@ -60,7 +54,13 @@ class AssetBrowserSearchFilteringTest(EditorTestHelper): :return: None """ - self.incorrect_file_found = False + from PySide2 import QtWidgets, QtTest, QtCore + from PySide2.QtCore import Qt + + import azlmbr.legacy.general as general + + from editor_python_test_tools.utils import Report + from editor_python_test_tools.utils import TestHelper as helper def verify_files_appeared(model, allowed_asset_extentions, parent_index=QtCore.QModelIndex()): indexes = [parent_index] @@ -74,25 +74,24 @@ class AssetBrowserSearchFilteringTest(EditorTestHelper): and (cur_data.lower().split(".")[-1] not in allowed_asset_extentions) and not cur_data[-1] == ")" ): - print(f"Incorrect file found: {cur_data}") - self.incorrect_file_found = True - indexes = list() - break + Report.info(f"Incorrect file found: {cur_data}") + return False indexes.append(cur_index) + return True + # 1) Open an existing simple level + helper.init_idle() + helper.open_level("Physics", "Base") - # 1) Open level - self.test_success = self.create_level( - self.args["level"], - heightmap_resolution=1024, - heightmap_meters_per_pixel=1, - terrain_texture_resolution=4096, - use_terrain=False, - ) - - # 2) Open Asset Browser - general.close_pane("Asset Browser") - general.open_pane("Asset Browser") + # 2) Open Asset Browser (if not opened already) + editor_window = pyside_utils.get_editor_main_window() + asset_browser_open = general.is_pane_visible("Asset Browser") + if not asset_browser_open: + Report.info("Opening Asset Browser") + action = pyside_utils.get_action_for_menu_path(editor_window, "Tools", "Asset Browser") + action.trigger() + else: + Report.info("Asset Browser is already open") editor_window = pyside_utils.get_editor_main_window() app = QtWidgets.QApplication.instance() @@ -103,10 +102,9 @@ class AssetBrowserSearchFilteringTest(EditorTestHelper): asset_browser_tree = asset_browser.findChild(QtWidgets.QTreeView, "m_assetBrowserTreeViewWidget") model_index = pyside_utils.find_child_by_pattern(asset_browser_tree, "cedar.fbx") pyside_utils.item_view_index_mouse_click(asset_browser_tree, model_index) - is_filtered = pyside_utils.wait_for_condition( + is_filtered = await pyside_utils.wait_for_condition( lambda: asset_browser_tree.indexBelow(asset_browser_tree.currentIndex()) == QtCore.QModelIndex(), 5.0) - if is_filtered: - print("cedar.fbx asset is filtered in Asset Browser") + Report.result(Tests.asset_filtered, is_filtered) # 4) Click the "X" in the search bar. clear_search = asset_browser.findChild(QtWidgets.QToolButton, "ClearToolButton") @@ -122,40 +120,47 @@ class AssetBrowserSearchFilteringTest(EditorTestHelper): tree.model().setData(animation_model_index, 2, Qt.CheckStateRole) general.idle_wait(1.0) # check asset types after clicking on Animation filter - verify_files_appeared(asset_browser_tree.model(), ["i_caf", "fbx", "xml", "animgraph", "motionset"]) - print(f"Animation file type(s) is present in the file tree: {not self.incorrect_file_found}") + asset_type_filter = verify_files_appeared(asset_browser_tree.model(), ["i_caf", "fbx", "xml", "animgraph", "motionset"]) + Report.result(Tests.asset_type_filtered, asset_type_filter) # 6) Add additional filter(FileTag) from the filter menu - self.incorrect_file_found = False line_edit.setText("FileTag") filetag_model_index = await pyside_utils.wait_for_child_by_pattern(tree, "FileTag") tree.model().setData(filetag_model_index, 2, Qt.CheckStateRole) general.idle_wait(1.0) # check asset types after clicking on FileTag filter - verify_files_appeared( + more_types_filtered = verify_files_appeared( asset_browser_tree.model(), ["i_caf", "fbx", "xml", "animgraph", "motionset", "filetag"] ) - print(f"FileTag file type(s) and Animation file type(s) is present in the file tree: {not self.incorrect_file_found}") + Report.result(Tests.asset_type_filtered, more_types_filtered) # 7) Remove one of the filtered asset types from the list of applied filters - self.incorrect_file_found = False filter_layout = asset_browser.findChild(QtWidgets.QFrame, "filteredLayout") animation_close_button = filter_layout.children()[1] first_close_button = animation_close_button.findChild(QtWidgets.QPushButton, "closeTag") first_close_button.click() general.idle_wait(1.0) # check asset types after removing Animation filter - verify_files_appeared(asset_browser_tree.model(), ["filetag"]) - print(f"FileTag file type(s) is present in the file tree after removing Animation filter: {not self.incorrect_file_found}") + remove_filtered = verify_files_appeared(asset_browser_tree.model(), ["filetag"]) + Report.result(Tests.asset_type_filtered, remove_filtered) # 8) Remove all of the filter asset types from the list of filters filetag_close_button = filter_layout.children()[1] second_close_button = filetag_close_button.findChild(QtWidgets.QPushButton, "closeTag") second_close_button.click() - # 9) Close the asset browser - asset_browser.close() + # Click off of the Asset Browser filter window to close it + QtTest.QTest.mouseClick(tree, Qt.LeftButton, Qt.NoModifier) + + # 9) Restore Asset Browser tool state and + if not asset_browser_open: + Report.info("Closing Asset Browser") + general.close_pane("Asset Browser") + + run_test() + +if __name__ == "__main__": -test = AssetBrowserSearchFilteringTest() -test.run() + from editor_python_test_tools.utils import Report + Report.start_test(AssetBrowser_SearchFiltering) diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetBrowser_TreeNavigation.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetBrowser_TreeNavigation.py index d57d9cda5e..b4f0dc7f6c 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetBrowser_TreeNavigation.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetBrowser_TreeNavigation.py @@ -5,124 +5,119 @@ For complete copyright and license terms please see the LICENSE at the root of t SPDX-License-Identifier: Apache-2.0 OR MIT """ -""" -C13660195: Asset Browser - File Tree Navigation -""" -import os -import sys -from PySide2 import QtWidgets, QtTest, QtCore - -import azlmbr.legacy.general as general -import azlmbr.paths - -sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests')) -from editor_python_test_tools.editor_test_helper import EditorTestHelper -import editor_python_test_tools.pyside_utils as pyside_utils - - -class AssetBrowserTreeNavigationTest(EditorTestHelper): - def __init__(self): - EditorTestHelper.__init__(self, log_prefix="AssetBrowser_TreeNavigation", args=["level"]) - - def run_test(self): - """ - Summary: - Verify if we are able to expand a file hierarchy in the Asset Browser and ScrollBar appears - appropriately. - - Expected Behavior: - The folder list is expanded to display the children of the selected folder. - A scroll bar appears to allow scrolling up and down through the asset browser. - Assets are present in the Asset Browser. - - Test Steps: - 1) Open a new level - 2) Open Asset Browser - 3) Collapse all files initially - 4) Get all Model Indexes - 5) Expand each of the folder and verify if it is opened - 6) Verify if the ScrollBar appears after expanding the tree - - Note: - - This test file must be called from the Open 3D Engine Editor command terminal - - Any passed and failed tests are written to the Editor.log file. - Parsing the file or running a log_monitor are required to observe the test results. - - :return: None - """ - - def collapse_expand_and_verify(model_index, hierarchy_level): - tree.collapse(model_index) - collapse_success = not tree.isExpanded(model_index) - self.log(f"Level {hierarchy_level} collapsed: {collapse_success}") - tree.expand(model_index) - expand_success = tree.isExpanded(model_index) - self.log(f"Level {hierarchy_level} expanded: {expand_success}") - return collapse_success and expand_success - - # This is the hierarchy we are expanding (4 steps inside) - self.file_path = ("AutomatedTesting", "Assets", "ImageGradients", "image_grad_test_gsi.png") - - # 1) Open a new level - self.test_success = self.create_level( - self.args["level"], - heightmap_resolution=1024, - heightmap_meters_per_pixel=1, - terrain_texture_resolution=4096, - use_terrain=False, - ) - - # 2) Open Asset Browser (if not opened already) - editor_window = pyside_utils.get_editor_main_window() - asset_browser_open = general.is_pane_visible("Asset Browser") - if not asset_browser_open: - self.log("Opening Asset Browser") - action = pyside_utils.get_action_for_menu_path(editor_window, "Tools", "Asset Browser") - action.trigger() - else: - self.log("Asset Browser is already open") - - # 3) Collapse all files initially - main_window = editor_window.findChild(QtWidgets.QMainWindow) - asset_browser = pyside_utils.find_child_by_hierarchy(main_window, ..., "Asset Browser") - tree = pyside_utils.find_child_by_hierarchy(asset_browser, ..., "m_assetBrowserTreeViewWidget") - scroll_area = tree.findChild(QtWidgets.QWidget, "qt_scrollarea_vcontainer") - scroll_bar = scroll_area.findChild(QtWidgets.QScrollBar) - tree.collapseAll() - - # 4) Get all Model Indexes - model_index_1 = pyside_utils.find_child_by_hierarchy(tree, self.file_path[0]) - model_index_2 = pyside_utils.find_child_by_hierarchy(model_index_1, self.file_path[1]) - model_index_3 = pyside_utils.find_child_by_hierarchy(model_index_2, self.file_path[2]) - model_index_4 = pyside_utils.find_child_by_hierarchy(model_index_3, self.file_path[3]) - - # 5) Verify each level of the hierarchy to the file can be collapsed/expanded - self.test_success = collapse_expand_and_verify(model_index_1, 1) and self.test_success - self.test_success = collapse_expand_and_verify(model_index_2, 2) and self.test_success - self.test_success = collapse_expand_and_verify(model_index_3, 3) and self.test_success - self.log(f"Collapse/Expand tests: {self.test_success}") - - # Select the asset - tree.scrollTo(model_index_4) - pyside_utils.item_view_index_mouse_click(tree, model_index_4) - - # Verify if the currently selected item model index is same as the Asset Model index - # to prove that it is visible - asset_visible = tree.currentIndex() == model_index_4 - self.test_success = asset_visible and self.test_success - self.log(f"Asset visibility test: {asset_visible}") - - # 6) Verify if the ScrollBar appears after expanding the tree - scrollbar_visible = scroll_bar.isVisible() - self.test_success = scrollbar_visible and self.test_success - self.log(f"Scrollbar visibility test: {scrollbar_visible}") - - # 7) Restore Asset Browser tool state - if not asset_browser_open: - self.log("Closing Asset Browser") - general.close_pane("Asset Browser") - - -test = AssetBrowserTreeNavigationTest() -test.run() +class Tests: + collapse_expand = ( + "Asset Browser hierarchy successfully collapsed/expanded", + "Failed to collapse/expand Asset Browser hierarchy" + ) + asset_visible = ( + "Expected asset is visible in the Asset Browser hierarchy", + "Failed to find expected asset in the Asset Browser hierarchy" + ) + scrollbar_visible = ( + "Scrollbar is visible", + "Scrollbar was not found" + ) + + +def AssetBrowser_TreeNavigation(): + """ + Summary: + Verify if we are able to expand a file hierarchy in the Asset Browser and ScrollBar appears + appropriately. + + Expected Behavior: + The folder list is expanded to display the children of the selected folder. + A scroll bar appears to allow scrolling up and down through the asset browser. + Assets are present in the Asset Browser. + + Test Steps: + 1) Open a simple level + 2) Open Asset Browser + 3) Collapse all files initially + 4) Get all Model Indexes + 5) Expand each of the folder and verify if it is opened + 6) Verify if the ScrollBar appears after expanding the tree + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + + from PySide2 import QtWidgets, QtTest, QtCore + + import azlmbr.legacy.general as general + + import editor_python_test_tools.pyside_utils as pyside_utils + from editor_python_test_tools.utils import Report + from editor_python_test_tools.utils import TestHelper as helper + + def collapse_expand_and_verify(model_index, hierarchy_level): + tree.collapse(model_index) + collapse_success = not tree.isExpanded(model_index) + Report.info(f"Level {hierarchy_level} collapsed: {collapse_success}") + tree.expand(model_index) + expand_success = tree.isExpanded(model_index) + Report.info(f"Level {hierarchy_level} expanded: {expand_success}") + return collapse_success and expand_success + + # This is the hierarchy we are expanding (4 steps inside) + file_path = ("AutomatedTesting", "Assets", "ImageGradients", "image_grad_test_gsi.png") + + # 1) Open an existing simple level + helper.init_idle() + helper.open_level("Physics", "Base") + + # 2) Open Asset Browser (if not opened already) + editor_window = pyside_utils.get_editor_main_window() + asset_browser_open = general.is_pane_visible("Asset Browser") + if not asset_browser_open: + Report.info("Opening Asset Browser") + action = pyside_utils.get_action_for_menu_path(editor_window, "Tools", "Asset Browser") + action.trigger() + else: + Report.info("Asset Browser is already open") + + # 3) Collapse all files initially + main_window = editor_window.findChild(QtWidgets.QMainWindow) + asset_browser = pyside_utils.find_child_by_hierarchy(main_window, ..., "Asset Browser") + tree = pyside_utils.find_child_by_hierarchy(asset_browser, ..., "m_assetBrowserTreeViewWidget") + scroll_area = tree.findChild(QtWidgets.QWidget, "qt_scrollarea_vcontainer") + scroll_bar = scroll_area.findChild(QtWidgets.QScrollBar) + tree.collapseAll() + + # 4) Get all Model Indexes + model_index_1 = pyside_utils.find_child_by_hierarchy(tree, file_path[0]) + model_index_2 = pyside_utils.find_child_by_hierarchy(model_index_1, file_path[1]) + model_index_3 = pyside_utils.find_child_by_hierarchy(model_index_2, file_path[2]) + model_index_4 = pyside_utils.find_child_by_hierarchy(model_index_3, file_path[3]) + + # 5) Verify each level of the hierarchy to the file can be collapsed/expanded + Report.result(Tests.collapse_expand, collapse_expand_and_verify(model_index_1, 1) and + collapse_expand_and_verify(model_index_2, 2) and collapse_expand_and_verify(model_index_3, 3)) + + # Select the asset + tree.scrollTo(model_index_4) + pyside_utils.item_view_index_mouse_click(tree, model_index_4) + + # Verify if the currently selected item model index is same as the Asset Model index + # to prove that it is visible + Report.result(Tests.asset_visible, tree.currentIndex() == model_index_4) + + # 6) Verify if the ScrollBar appears after expanding the tree + Report.result(Tests.scrollbar_visible, scroll_bar.isVisible()) + + # 7) Restore Asset Browser tool state + if not asset_browser_open: + Report.info("Closing Asset Browser") + general.close_pane("Asset Browser") + + +if __name__ == "__main__": + + from editor_python_test_tools.utils import Report + Report.start_test(AssetBrowser_TreeNavigation) diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetPicker_UI_UX.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetPicker_UI_UX.py index 068f25fb1e..59a78c9e5d 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetPicker_UI_UX.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetPicker_UI_UX.py @@ -5,33 +5,13 @@ For complete copyright and license terms please see the LICENSE at the root of t SPDX-License-Identifier: Apache-2.0 OR MIT """ -""" -C13751579: Asset Picker UI/UX -""" - -import os -import sys -from PySide2 import QtWidgets, QtTest, QtCore -from PySide2.QtCore import Qt -import azlmbr.asset as asset -import azlmbr.bus as bus -import azlmbr.legacy.general as general -import azlmbr.paths -import azlmbr.math as math +def AssetPicker_UI_UX(): -sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests')) -import editor_python_test_tools.hydra_editor_utils as hydra -import editor_python_test_tools.pyside_utils as pyside_utils -from editor_python_test_tools.editor_test_helper import EditorTestHelper - - -class AssetPickerUIUXTest(EditorTestHelper): - def __init__(self): - EditorTestHelper.__init__(self, log_prefix="AssetPicker_UI_UX", args=["level"]) + import editor_python_test_tools.pyside_utils as pyside_utils @pyside_utils.wrap_async - async def run_test(self): + async def run_test(): """ Summary: Verify the functionality of Asset Picker and UI/UX properties @@ -45,7 +25,7 @@ class AssetPickerUIUXTest(EditorTestHelper): The asset picker is closed and the selected asset is assigned to the mesh component. Test Steps: - 1) Open a new level + 1) Open a simple level 2) Create entity and add Mesh component 3) Access Entity Inspector 4) Click Asset Picker (Mesh Asset) @@ -68,10 +48,20 @@ class AssetPickerUIUXTest(EditorTestHelper): :return: None """ - self.file_path = ["AutomatedTesting", "Assets", "Objects", "Foliage"] - self.incorrect_file_found = False - self.mesh_asset = "cedar.azmodel" - self.prefix = "" + import os + from PySide2 import QtWidgets, QtTest, QtCore + from PySide2.QtCore import Qt + + import azlmbr.asset as asset + import azlmbr.bus as bus + import azlmbr.legacy.general as general + import azlmbr.math as math + + import editor_python_test_tools.hydra_editor_utils as hydra + from editor_python_test_tools.utils import Report + from editor_python_test_tools.utils import TestHelper as helper + + file_path = ["AutomatedTesting", "Assets", "Objects", "Foliage"] def is_asset_assigned(component, interaction_option): path = os.path.join("assets", "objects", "foliage", "cedar.azmodel") @@ -80,7 +70,7 @@ class AssetPickerUIUXTest(EditorTestHelper): result = hydra.get_component_property_value(component, "Controller|Configuration|Mesh Asset") expected_asset_str = expected_asset_id.invoke("ToString") result_str = result.invoke("ToString") - print(f"Asset assigned for {interaction_option} option: {expected_asset_str == result_str}") + Report.info(f"Asset assigned for {interaction_option} option: {expected_asset_str == result_str}") return expected_asset_str == result_str def move_and_resize_widget(widget): @@ -89,9 +79,11 @@ class AssetPickerUIUXTest(EditorTestHelper): x, y = initial_position.x() + 5, initial_position.y() + 5 widget.move(x, y) curr_position = widget.pos() - move_success = curr_position.x() == x and curr_position.y() == y - self.test_success = move_success and self.test_success - self.log(f"Widget Move Test: {move_success}") + asset_picker_moved = ( + "Asset Picker widget moved successfully", + "Failed to move Asset Picker widget" + ) + Report.result(asset_picker_moved, curr_position.x() == x and curr_position.y() == y) # Resize the widget and verify size width, height = ( @@ -99,9 +91,36 @@ class AssetPickerUIUXTest(EditorTestHelper): widget.geometry().height() + 10, ) widget.resize(width, height) - resize_success = widget.geometry().width() == width and widget.geometry().height() == height - self.test_success = resize_success and self.test_success - self.log(f"Widget Resize Test: {resize_success}") + asset_picker_resized = ( + "Resized Asset Picker widget successfully", + "Failed to resize Asset Picker widget" + ) + Report.result(asset_picker_resized, widget.geometry().width() == width and widget.geometry().height() == + height) + + def verify_expand(model_index, tree): + initially_collapsed = ( + "Folder initially collapsed", + "Folder unexpectedly expanded" + ) + expanded = ( + "Folder expanded successfully", + "Failed to expand folder" + ) + # Check initial collapse + Report.result(initially_collapsed, not tree.isExpanded(model_index)) + # Expand at the specified index + tree.expand(model_index) + # Verify expansion + Report.result(expanded, tree.isExpanded(model_index)) + + def verify_collapse(model_index, tree): + collapsed = ( + "Folder hierarchy collapsed successfully", + "Failed to collapse folder hierarchy" + ) + tree.collapse(model_index) + Report.result(collapsed, not tree.isExpanded(model_index)) def verify_files_appeared(model, allowed_asset_extensions, parent_index=QtCore.QModelIndex()): indices = [parent_index] @@ -115,22 +134,20 @@ class AssetPickerUIUXTest(EditorTestHelper): and (cur_data.lower().split(".")[-1] not in allowed_asset_extensions) and not cur_data[-1] == ")" ): - print(f"Incorrect file found: {cur_data}") - self.incorrect_file_found = True - indices = list() - break + Report.info(f"Incorrect file found: {cur_data}") + return False indices.append(cur_index) - self.test_success = not self.incorrect_file_found and self.test_success - - def print_message_prefix(message): - print(f"{self.prefix}: {message}") + return True - async def asset_picker(prefix, allowed_asset_extensions, asset, interaction_option): + async def asset_picker(allowed_asset_extensions, asset, interaction_option): active_modal_widget = await pyside_utils.wait_for_modal_widget() - if active_modal_widget and self.prefix == "": - self.prefix = prefix + if active_modal_widget: dialog = active_modal_widget.findChildren(QtWidgets.QDialog, "AssetPickerDialogClass")[0] - print_message_prefix(f"Asset Picker title for Mesh: {dialog.windowTitle()}") + asset_picker_title = ( + "Asset Picker window is titled as expected", + "Asset Picker window has an unexpected title" + ) + Report.result(asset_picker_title, dialog.windowTitle() == "Pick ModelAsset") tree = dialog.findChildren(QtWidgets.QTreeView, "m_assetBrowserTreeViewWidget")[0] scroll_area = tree.findChild(QtWidgets.QWidget, "qt_scrollarea_vcontainer") scroll_bar = scroll_area.findChild(QtWidgets.QScrollBar) @@ -138,39 +155,42 @@ class AssetPickerUIUXTest(EditorTestHelper): # a) Collapse all the files initially and verify if scroll bar is not visible tree.collapseAll() await pyside_utils.wait_for_condition(lambda: not scroll_bar.isVisible(), 0.5) - print_message_prefix( - f"Scroll Bar is not visible before expanding the tree: {not scroll_bar.isVisible()}" + scroll_bar_hidden = ( + "Scroll Bar is not visible before tree expansion", + "Scroll Bar is visible before tree expansion" ) + Report.result(scroll_bar_hidden, not scroll_bar.isVisible()) # Get Model Index of the file paths - model_index_1 = pyside_utils.find_child_by_pattern(tree, self.file_path[0]) - print(model_index_1.model()) - model_index_2 = pyside_utils.find_child_by_pattern(model_index_1, self.file_path[1]) + model_index_1 = pyside_utils.find_child_by_pattern(tree, file_path[0]) + model_index_2 = pyside_utils.find_child_by_pattern(model_index_1, file_path[1]) # b) Expand/Verify Top folder of file path - print_message_prefix(f"Top level folder initially collapsed: {not tree.isExpanded(model_index_1)}") - tree.expand(model_index_1) - print_message_prefix(f"Top level folder expanded: {tree.isExpanded(model_index_1)}") + verify_expand(model_index_1, tree) # c) Expand/Verify Nested folder of file path - print_message_prefix(f"Nested folder initially collapsed: {not tree.isExpanded(model_index_2)}") - tree.expand(model_index_2) - print_message_prefix(f"Nested folder expanded: {tree.isExpanded(model_index_2)}") + verify_expand(model_index_2, tree) # d) Verify if the ScrollBar appears after expanding folders tree.expandAll() await pyside_utils.wait_for_condition(lambda: scroll_bar.isVisible(), 0.5) - print_message_prefix(f"Scroll Bar appeared after expanding tree: {scroll_bar.isVisible()}") + scroll_bar_visible = ( + "Scroll Bar is visible after tree expansion", + "Scroll Bar is not visible after tree expansion" + ) + Report.result(scroll_bar_visible, scroll_bar.isVisible()) # e) Collapse Nested and Top Level folders and verify if collapsed - tree.collapse(model_index_2) - print_message_prefix(f"Nested folder collapsed: {not tree.isExpanded(model_index_2)}") - tree.collapse(model_index_1) - print_message_prefix(f"Top level folder collapsed: {not tree.isExpanded(model_index_1)}") + verify_collapse(model_index_2, tree) + verify_collapse(model_index_1, tree) # f) Verify if the correct files are appearing in the Asset Picker - verify_files_appeared(tree.model(), allowed_asset_extensions) - print_message_prefix(f"Expected Assets populated in the file picker: {not self.incorrect_file_found}") + asset_picker_correct_files_appear = ( + "Expected assets populated in the file picker", + "Found unexpected assets in the file picker" + ) + Report.result(asset_picker_correct_files_appear, verify_files_appeared(tree.model(), + allowed_asset_extensions)) # While we are here we can also check if we can resize and move the widget move_and_resize_widget(active_modal_widget) @@ -193,16 +213,10 @@ class AssetPickerUIUXTest(EditorTestHelper): await pyside_utils.click_button_async(ok_button) elif interaction_option == "enter": QtTest.QTest.keyClick(tree, Qt.Key_Enter, Qt.NoModifier) - self.prefix = "" - - # 1) Open a new level - self.test_success = self.create_level( - self.args["level"], - heightmap_resolution=1024, - heightmap_meters_per_pixel=1, - terrain_texture_resolution=4096, - use_terrain=False, - ) + + # 1) Open an existing simple level + helper.init_idle() + helper.open_level("Physics", "Base") # 2) Create entity and add Mesh component entity_position = math.Vector3(125.0, 136.0, 32.0) @@ -222,7 +236,7 @@ class AssetPickerUIUXTest(EditorTestHelper): # Assign Mesh Asset via OK button pyside_utils.click_button_async(attached_button) - await asset_picker("Mesh Asset", ["azmodel", "fbx"], "cedar (ModelAsset)", "ok") + await asset_picker(["azmodel", "fbx"], "cedar (ModelAsset)", "ok") # 5) Verify if Mesh Asset is assigned try: @@ -231,7 +245,11 @@ class AssetPickerUIUXTest(EditorTestHelper): except pyside_utils.EventLoopTimeoutException as err: print(err) mesh_success = False - self.test_success = mesh_success and self.test_success + mesh_asset_assigned_ok = ( + "Successfully assigned Mesh asset via OK button", + "Failed to assign Mesh asset via OK button" + ) + Report.result(mesh_asset_assigned_ok, mesh_success) # Clear Mesh Asset hydra.get_set_test(entity, 0, "Controller|Configuration|Mesh Asset", None) @@ -242,7 +260,7 @@ class AssetPickerUIUXTest(EditorTestHelper): # Assign Mesh Asset via Enter pyside_utils.click_button_async(attached_button) - await asset_picker("Mesh Asset", ["azmodel", "fbx"], "cedar (ModelAsset)", "enter") + await asset_picker(["azmodel", "fbx"], "cedar (ModelAsset)", "enter") # 5) Verify if Mesh Asset is assigned try: @@ -251,8 +269,16 @@ class AssetPickerUIUXTest(EditorTestHelper): except pyside_utils.EventLoopTimeoutException as err: print(err) mesh_success = False - self.test_success = mesh_success and self.test_success + mesh_asset_assigned_enter = ( + "Successfully assigned Mesh asset via Enter button", + "Failed to assign Mesh asset via Enter button" + ) + Report.result(mesh_asset_assigned_enter, mesh_success) + + run_test() + +if __name__ == "__main__": -test = AssetPickerUIUXTest() -test.run() + from editor_python_test_tools.utils import Report + Report.start_test(AssetPicker_UI_UX) diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/BasicEditorWorkflows_LevelEntityComponentCRUD.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/BasicEditorWorkflows_LevelEntityComponentCRUD.py index 994fc661ed..9c5880ab1e 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/BasicEditorWorkflows_LevelEntityComponentCRUD.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/BasicEditorWorkflows_LevelEntityComponentCRUD.py @@ -5,36 +5,44 @@ For complete copyright and license terms please see the LICENSE at the root of t SPDX-License-Identifier: Apache-2.0 OR MIT """ -""" -C6351273: Create a new level -C6384955: Basic Workflow: Entity Manipulation in the Outliner -C16929880: Add Delete Components -C15167490: Save a level -C15167491: Export a level -""" - -import os -import sys -from PySide2 import QtWidgets - -import azlmbr.bus as bus -import azlmbr.editor as editor -import azlmbr.entity as entity -import azlmbr.math as math -import azlmbr.paths - -sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests')) -from editor_python_test_tools.editor_test_helper import EditorTestHelper -import editor_python_test_tools.pyside_utils as pyside_utils -import editor_python_test_tools.hydra_editor_utils as hydra - -class TestBasicEditorWorkflows(EditorTestHelper): - def __init__(self): - EditorTestHelper.__init__(self, log_prefix="BasicEditorWorkflows_LevelEntityComponent", args=["level"]) +class Tests: + level_created = ( + "New level created successfully", + "Failed to create new level" + ) + new_entity_created = ( + "New entity created successfully", + "Failed to create a new entity" + ) + child_entity_created = ( + "New child entity created successfully", + "Failed to create new child entity" + ) + component_added = ( + "Component added to entity successfully", + "Failed to add component to entity" + ) + component_updated = ( + "Component property updated successfully", + "Failed to update component property" + ) + component_removed = ( + "Component removed from entity successfully", + "Failed to remove component from entity" + ) + level_saved_and_exported = ( + "Level saved and exported successfully", + "Failed to save/export level" + ) + + +def BasicEditorWorkflows_LevelEntityComponentCRUD(): + + import editor_python_test_tools.pyside_utils as pyside_utils @pyside_utils.wrap_async - async def run_test(self): + async def run_test(): """ Summary: Open O3DE editor and check if basic Editor workflows are completable. @@ -55,6 +63,18 @@ class TestBasicEditorWorkflows(EditorTestHelper): :return: None """ + import os + from PySide2 import QtWidgets + + import azlmbr.bus as bus + import azlmbr.editor as editor + import azlmbr.entity as entity + import azlmbr.math as math + import azlmbr.paths + + import editor_python_test_tools.hydra_editor_utils as hydra + from editor_python_test_tools.utils import Report + def find_entity_by_name(entity_name): search_filter = entity.SearchFilter() search_filter.names = [entity_name] @@ -64,6 +84,7 @@ class TestBasicEditorWorkflows(EditorTestHelper): return None # 1) Create a new level + level = "tmp_level" editor_window = pyside_utils.get_editor_main_window() new_level_action = pyside_utils.get_action_for_menu_path(editor_window, "File", "New Level") pyside_utils.trigger_action_async(new_level_action) @@ -71,21 +92,17 @@ class TestBasicEditorWorkflows(EditorTestHelper): new_level_dlg = active_modal_widget.findChild(QtWidgets.QWidget, "CNewLevelDialog") if new_level_dlg: if new_level_dlg.windowTitle() == "New Level": - self.log("New Level dialog opened") + Report.info("New Level dialog opened") grp_box = new_level_dlg.findChild(QtWidgets.QGroupBox, "STATIC_GROUP1") level_name = grp_box.findChild(QtWidgets.QLineEdit, "LEVEL") - level_name.setText(self.args["level"]) + level_name.setText(level) button_box = new_level_dlg.findChild(QtWidgets.QDialogButtonBox, "buttonBox") button_box.button(QtWidgets.QDialogButtonBox.Ok).click() # Verify new level was created successfully level_create_success = await pyside_utils.wait_for_condition(lambda: editor.EditorToolsApplicationRequestBus( - bus.Broadcast, "GetCurrentLevelName") == self.args["level"], 5.0) - self.test_success = level_create_success - self.log(f"Create and load new level: {level_create_success}") - - # Execute EditorTestHelper setup since level was created outside of EditorTestHelper's methods - self.test_success = self.test_success and self.after_level_load() + bus.Broadcast, "GetCurrentLevelName") == level, 5.0) + Report.critical_result(Tests.level_created, level_create_success) # 2) Delete existing entities, and create and manipulate new entities via Entity Inspector search_filter = azlmbr.entity.SearchFilter() @@ -99,8 +116,7 @@ class TestBasicEditorWorkflows(EditorTestHelper): # Find the new entity parent_entity_id = find_entity_by_name("Entity1") parent_entity_success = await pyside_utils.wait_for_condition(lambda: parent_entity_id is not None, 5.0) - self.test_success = self.test_success and parent_entity_success - self.log(f"New entity creation: {parent_entity_success}") + Report.critical_result(Tests.new_entity_created, parent_entity_success) # TODO: Replace Hydra call to creates child entity and add components with context menu triggering - LYN-3951 # Create a new child entity @@ -111,29 +127,27 @@ class TestBasicEditorWorkflows(EditorTestHelper): # Verify entity hierarchy child_entity.get_parent_info() - self.test_success = self.test_success and child_entity.parent_id == parent_entity_id - self.log(f"Create entity hierarchy: {child_entity.parent_id == parent_entity_id}") + Report.result(Tests.child_entity_created, child_entity.parent_id == parent_entity_id) # 3) Add/configure a component on an entity # Add component and verify success child_entity.add_component("Box Shape") - component_add_success = self.wait_for_condition(lambda: hydra.has_components(child_entity.id, ["Box Shape"]), 5.0) - self.test_success = self.test_success and component_add_success - self.log(f"Add component: {component_add_success}") + component_add_success = await pyside_utils.wait_for_condition(lambda: hydra.has_components(child_entity.id, + ["Box Shape"]), 5.0) + Report.result(Tests.component_added, component_add_success) # Update the component dimensions_to_set = math.Vector3(16.0, 16.0, 16.0) child_entity.get_set_test(0, "Box Shape|Box Configuration|Dimensions", dimensions_to_set) - box_shape_dimensions = hydra.get_component_property_value(child_entity.components[0], "Box Shape|Box Configuration|Dimensions") - self.test_success = self.test_success and box_shape_dimensions == dimensions_to_set - self.log(f"Component update: {box_shape_dimensions == dimensions_to_set}") + box_shape_dimensions = hydra.get_component_property_value(child_entity.components[0], + "Box Shape|Box Configuration|Dimensions") + Report.result(Tests.component_updated, box_shape_dimensions == dimensions_to_set) # Remove the component child_entity.remove_component("Box Shape") - component_rem_success = self.wait_for_condition(lambda: not hydra.has_components(child_entity.id, ["Box Shape"]), - 5.0) - self.test_success = self.test_success and component_rem_success - self.log(f"Remove component: {component_rem_success}") + component_rem_success = await pyside_utils.wait_for_condition(lambda: not hydra.has_components(child_entity.id, + ["Box Shape"]), 5.0) + Report.result(Tests.component_removed, component_rem_success) # 4) Save the level save_level_action = pyside_utils.get_action_for_menu_path(editor_window, "File", "Save") @@ -143,12 +157,15 @@ class TestBasicEditorWorkflows(EditorTestHelper): export_action = pyside_utils.get_action_for_menu_path(editor_window, "Game", "Export to Engine") pyside_utils.trigger_action_async(export_action) level_pak_file = os.path.join( - "AutomatedTesting", "Levels", self.args["level"], "level.pak" + "AutomatedTesting", "Levels", level, "level.pak" ) - export_success = self.wait_for_condition(lambda: os.path.exists(level_pak_file), 5.0) - self.test_success = self.test_success and export_success - self.log(f"Save and Export: {export_success}") + export_success = await pyside_utils.wait_for_condition(lambda: os.path.exists(level_pak_file), 5.0) + Report.result(Tests.level_saved_and_exported, export_success) + + run_test() + +if __name__ == "__main__": -test = TestBasicEditorWorkflows() -test.run() + from editor_python_test_tools.utils import Report + Report.start_test(BasicEditorWorkflows_LevelEntityComponentCRUD) diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/ComponentCRUD_Add_Delete_Components.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/ComponentCRUD_Add_Delete_Components.py index 8f2264c9d1..779f1ef953 100755 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/ComponentCRUD_Add_Delete_Components.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/ComponentCRUD_Add_Delete_Components.py @@ -5,37 +5,39 @@ For complete copyright and license terms please see the LICENSE at the root of t SPDX-License-Identifier: Apache-2.0 OR MIT """ -""" -C16929880: Add Delete Components -""" - -import os -import sys -from PySide2 import QtWidgets, QtTest, QtCore -from PySide2.QtCore import Qt - -import azlmbr.legacy.general as general -import azlmbr.bus as bus -import azlmbr.editor as editor -import azlmbr.entity as entity -import azlmbr.math as math -import azlmbr.paths - -sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests')) -import editor_python_test_tools.hydra_editor_utils as hydra -import editor_python_test_tools.pyside_utils as pyside_utils -from editor_python_test_tools.editor_test_helper import EditorTestHelper - -class AddDeleteComponentsTest(EditorTestHelper): - def __init__(self): - EditorTestHelper.__init__(self, log_prefix="ComponentCRUD_Add_Delete_Components", args=["level"]) +class Tests: + entity_created = ( + "Entity created successfully", + "Failed to create entity" + ) + box_component_added = ( + "Box Shape component added to entity", + "Failed to add Box Shape component to entity" + ) + mesh_component_added = ( + "Mesh component added to entity", + "Failed to add Mesh component to entity" + ) + mesh_component_deleted = ( + "Mesh component removed from entity", + "Failed to remove Mesh component from entity" + ) + mesh_component_delete_undo = ( + "Mesh component removal was successfully undone", + "Failed to undo Mesh component removal" + ) + + +def ComponentCRUD_Add_Delete_Components(): + + import editor_python_test_tools.pyside_utils as pyside_utils @pyside_utils.wrap_async - async def run_test(self): + async def run_test(): """ Summary: - Add/Delete Components to an entity. + Add/Delete Components to/from an entity. Expected Behavior: 1) Components can be added to an entity. @@ -61,36 +63,43 @@ class AddDeleteComponentsTest(EditorTestHelper): :return: None """ + from PySide2 import QtWidgets, QtTest, QtCore + from PySide2.QtCore import Qt + + import azlmbr.legacy.general as general + import azlmbr.bus as bus + import azlmbr.editor as editor + import azlmbr.entity as entity + import azlmbr.math as math + + import editor_python_test_tools.hydra_editor_utils as hydra + from editor_python_test_tools.utils import Report + from editor_python_test_tools.utils import TestHelper as helper + async def add_component(component_name): pyside_utils.click_button_async(add_comp_btn) popup = await pyside_utils.wait_for_popup_widget() tree = popup.findChild(QtWidgets.QTreeView, "Tree") component_index = pyside_utils.find_child_by_pattern(tree, component_name) if component_index.isValid(): - print(f"{component_name} found") + Report.info(f"{component_name} found") tree.expand(component_index) tree.setCurrentIndex(component_index) QtTest.QTest.keyClick(tree, Qt.Key_Enter, Qt.NoModifier) - # 1) Open level - self.test_success = self.create_level( - self.args["level"], - heightmap_resolution=1024, - heightmap_meters_per_pixel=1, - terrain_texture_resolution=4096, - use_terrain=False, - ) + # 1) Open an existing simple level + helper.init_idle() + helper.open_level("Physics", "Base") # 2) Create entity entity_position = math.Vector3(125.0, 136.0, 32.0) entity_id = editor.ToolsApplicationRequestBus( bus.Broadcast, "CreateNewEntityAtPosition", entity_position, entity.EntityId() ) - if entity_id.IsValid(): - print("Entity Created") + Report.critical_result(Tests.entity_created, entity_id.IsValid()) # 3) Select the newly created entity - general.select_object("Entity2") + general.select_object("Entity1") # Give the Entity Inspector time to fully create its contents general.idle_wait(0.5) @@ -100,11 +109,11 @@ class AddDeleteComponentsTest(EditorTestHelper): entity_inspector = editor_window.findChild(QtWidgets.QDockWidget, "Entity Inspector") add_comp_btn = entity_inspector.findChild(QtWidgets.QPushButton, "m_addComponentButton") await add_component("Box Shape") - print(f"Box Shape Component added: {hydra.has_components(entity_id, ['Box Shape'])}") + Report.result(Tests.box_component_added, hydra.has_components(entity_id, ['Box Shape'])) # 5) Add/verify Mesh component await add_component("Mesh") - print(f"Mesh Component added: {hydra.has_components(entity_id, ['Mesh'])}") + Report.result(Tests.mesh_component_added, hydra.has_components(entity_id, ['Mesh'])) # 6) Delete Mesh Component general.idle_wait(0.5) @@ -116,15 +125,17 @@ class AddDeleteComponentsTest(EditorTestHelper): QtTest.QTest.mouseClick(mesh_frame, Qt.LeftButton, Qt.NoModifier) QtTest.QTest.keyClick(mesh_frame, Qt.Key_Delete, Qt.NoModifier) success = await pyside_utils.wait_for_condition(lambda: not hydra.has_components(entity_id, ['Mesh']), 5.0) - if success: - print(f"Mesh Component deleted: {not hydra.has_components(entity_id, ['Mesh'])}") + Report.result(Tests.mesh_component_deleted, success) # 7) Undo deletion of component QtTest.QTest.keyPress(entity_inspector, Qt.Key_Z, Qt.ControlModifier) success = await pyside_utils.wait_for_condition(lambda: hydra.has_components(entity_id, ['Mesh']), 5.0) - if success: - print(f"Mesh Component deletion undone: {hydra.has_components(entity_id, ['Mesh'])}") + Report.result(Tests.mesh_component_delete_undo, success) + + run_test() + +if __name__ == "__main__": -test = AddDeleteComponentsTest() -test.run() + from editor_python_test_tools.utils import Report + Report.start_test(ComponentCRUD_Add_Delete_Components) diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Docking_BasicDockedTools.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Docking_BasicDockedTools.py index cc8ab24bed..2a91e7a374 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Docking_BasicDockedTools.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Docking_BasicDockedTools.py @@ -7,27 +7,32 @@ SPDX-License-Identifier: Apache-2.0 OR MIT C6376081: Basic Function: Docked/Undocked Tools """ -import os -import sys -from PySide2 import QtWidgets, QtTest, QtCore -import azlmbr.legacy.general as general -import azlmbr.bus as bus -import azlmbr.editor as editor -import azlmbr.entity as entity -import azlmbr.paths - -sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests')) -from editor_python_test_tools.editor_test_helper import EditorTestHelper -import editor_python_test_tools.pyside_utils as pyside_utils - - -class TestDockingBasicDockedTools(EditorTestHelper): - def __init__(self): - EditorTestHelper.__init__(self, log_prefix="Docking_BasicDockedTools", args=["level"]) +class Tests: + all_tools_docked = ( + "The tools are all docked together in a tabbed widget", + "Failed to dock all tools together" + ) + docked_outliner_works = ( + "Entity Outliner works when docked, can select an Entity", + "Failed to select an Entity in the Outliner while docked" + ) + docked_inspector_works = ( + "Entity Inspector works when docked, Entity name changed", + "Failed to change Entity name in the Inspector while docked" + ) + docked_console_works = ( + "Console works when docked, sent a Console Command", + "Failed to send Console Command in the Console while docked" + ) + + +def Docking_BasicDockedTools(): + + import editor_python_test_tools.pyside_utils as pyside_utils @pyside_utils.wrap_async - async def run_test(self): + async def run_test(): """ Summary: Test that tools still work as expected when docked together. @@ -50,14 +55,19 @@ class TestDockingBasicDockedTools(EditorTestHelper): :return: None """ - # Create a level since we are going to be dealing with an Entity. - self.create_level( - self.args["level"], - heightmap_resolution=1024, - heightmap_meters_per_pixel=1, - terrain_texture_resolution=4096, - use_terrain=False, - ) + from PySide2 import QtWidgets, QtTest, QtCore + + import azlmbr.legacy.general as general + import azlmbr.bus as bus + import azlmbr.editor as editor + import azlmbr.entity as entity + + from editor_python_test_tools.utils import Report + from editor_python_test_tools.utils import TestHelper as helper + + # Open an existing simple level + helper.init_idle() + helper.open_level("Physics", "Base") # Make sure the Entity Outliner, Entity Inspector and Console tools are open general.open_pane("Entity Outliner (PREVIEW)") @@ -101,12 +111,14 @@ class TestDockingBasicDockedTools(EditorTestHelper): entity_inspector_parent = entity_inspector.parentWidget() entity_outliner_parent = entity_outliner.parentWidget() console_parent = console.parentWidget() - print(f"Entity Inspector parent = {entity_inspector_parent}, Entity Outliner parent = {entity_outliner_parent}, Console parent = {console_parent}") - return isinstance(entity_inspector_parent, QtWidgets.QStackedWidget) and (entity_inspector_parent == entity_outliner_parent) and (entity_outliner_parent == console_parent) + Report.info(f"Entity Inspector parent = {entity_inspector_parent}, Entity Outliner parent = " + f"{entity_outliner_parent}, Console parent = {console_parent}") + return isinstance(entity_inspector_parent, QtWidgets.QStackedWidget) and \ + (entity_inspector_parent == entity_outliner_parent) and \ + (entity_outliner_parent == console_parent) success = await pyside_utils.wait_for(check_all_panes_tabbed, timeout=3.0) - if success: - print("The tools are all docked together in a tabbed widget") + Report.result(Tests.all_tools_docked, success) # 2.1,2) Select an Entity in the Entity Outliner. entity_inspector = editor_window.findChild(QtWidgets.QDockWidget, "Entity Inspector") @@ -116,8 +128,7 @@ class TestDockingBasicDockedTools(EditorTestHelper): test_entity_index = pyside_utils.find_child_by_pattern(object_tree, entity_original_name) object_tree.clearSelection() object_tree.setCurrentIndex(test_entity_index) - if object_tree.currentIndex(): - print("Entity Outliner works when docked, can select an Entity") + Report.result(Tests.docked_outliner_works, object_tree.currentIndex() == test_entity_index) # 2.3,4) Change the name of the selected Entity via the Entity Inspector. entity_inspector_name_field = entity_inspector.findChild(QtWidgets.QLineEdit, "m_entityNameEditor") @@ -125,14 +136,23 @@ class TestDockingBasicDockedTools(EditorTestHelper): entity_inspector_name_field.setText(expected_new_name) QtTest.QTest.keyClick(entity_inspector_name_field, QtCore.Qt.Key_Enter) entity_new_name = editor.EditorEntityInfoRequestBus(bus.Event, "GetName", entity_id) - if entity_new_name == expected_new_name: - print(f"Entity Inspector works when docked, Entity name changed to {entity_new_name}") + Report.result(Tests.docked_inspector_works, entity_new_name == expected_new_name) # 2.5,6) Send a console command. console_line_edit = console.findChild(QtWidgets.QLineEdit, "lineEdit") - console_line_edit.setText("Hello, world!") + console_line_edit.setText("t_Scale 2") + QtTest.QTest.keyClick(console_line_edit, QtCore.Qt.Key_Enter) + general.get_cvar("t_Scale") + Report.result(Tests.docked_console_works, general.get_cvar("t_Scale") == "2") + + # Reset the altered cvar + console_line_edit.setText("t_Scale 1") QtTest.QTest.keyClick(console_line_edit, QtCore.Qt.Key_Enter) + run_test() + + +if __name__ == "__main__": -test = TestDockingBasicDockedTools() -test.run() + from editor_python_test_tools.utils import Report + Report.start_test(Docking_BasicDockedTools) diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/InputBindings_Add_Remove_Input_Events.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/InputBindings_Add_Remove_Input_Events.py index 4693f20155..f4769dab4d 100755 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/InputBindings_Add_Remove_Input_Events.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/InputBindings_Add_Remove_Input_Events.py @@ -5,32 +5,36 @@ For complete copyright and license terms please see the LICENSE at the root of t SPDX-License-Identifier: Apache-2.0 OR MIT """ -""" -C1506881: Adding/Removing Event Groups -""" - -import os -import sys -from PySide2 import QtWidgets - -import azlmbr.legacy.general as general -import azlmbr.bus as bus -import azlmbr.editor as editor -import azlmbr.entity as entity -import azlmbr.math as math -import azlmbr.paths - -sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests')) -import editor_python_test_tools.hydra_editor_utils as hydra -import editor_python_test_tools.pyside_utils as pyside_utils -from editor_python_test_tools.editor_test_helper import EditorTestHelper -class AddRemoveInputEventsTest(EditorTestHelper): - def __init__(self): - EditorTestHelper.__init__(self, log_prefix="InputBindings_Add_Remove_Input_Events", args=["level"]) +class Tests: + asset_editor_opened = ( + "Successfully opened the Asset Editor", + "Failed to open the Asset Editor" + ) + event_groups_added = ( + "Successfully added event groups via +", + "Failed to add event groups" + ) + single_event_group_deleted = ( + "Successfully deleted an event group", + "Failed to delete event group" + ) + all_event_groups_deleted = ( + "Successfully deleted all event groups", + "Failed to delete all event groups" + ) + asset_editor_closed = ( + "Successfully closed the Asset Editor", + "Failed to close the Asset Editor" + ) + + +def InputBindings_Add_Remove_Input_Events(): + + import editor_python_test_tools.pyside_utils as pyside_utils @pyside_utils.wrap_async - async def run_test(self): + async def run_test(): """ Summary: Verify if we are able add/remove input events in inputbindings file. @@ -42,7 +46,7 @@ class AddRemoveInputEventsTest(EditorTestHelper): Test Steps: - 1) Open a new level + 1) Open an existing level 2) Open Asset Editor 3) Access Asset Editor 4) Create a new .inputbindings file and add event groups @@ -61,6 +65,13 @@ class AddRemoveInputEventsTest(EditorTestHelper): :return: None """ + from PySide2 import QtWidgets + + import azlmbr.legacy.general as general + + from editor_python_test_tools.utils import Report + from editor_python_test_tools.utils import TestHelper as helper + def open_asset_editor(): general.open_pane("Asset Editor") return general.is_pane_visible("Asset Editor") @@ -69,17 +80,12 @@ class AddRemoveInputEventsTest(EditorTestHelper): general.close_pane("Asset Editor") return not general.is_pane_visible("Asset Editor") - # 1) Open a new level - self.test_success = self.create_level( - self.args["level"], - heightmap_resolution=1024, - heightmap_meters_per_pixel=1, - terrain_texture_resolution=4096, - use_terrain=False, - ) + # 1) Open an existing simple level + helper.init_idle() + helper.open_level("Physics", "Base") # 2) Open Asset Editor - print(f"Asset Editor opened: {open_asset_editor()}") + Report.result(Tests.asset_editor_opened, open_asset_editor()) # 3) Access Asset Editor editor_window = pyside_utils.get_editor_main_window() @@ -103,8 +109,7 @@ class AddRemoveInputEventsTest(EditorTestHelper): # 5) Verify if there are 3 elements in the Input Event Groups label no_of_elements_label = input_event_groups.findChild(QtWidgets.QLabel, "DefaultLabel") success = await pyside_utils.wait_for_condition(lambda: "3 elements" in no_of_elements_label.text(), 2.0) - if success: - print("New Event Groups added when + is clicked") + Report.result(Tests.event_groups_added, success) # 6) Delete one event group event = asset_editor_widget.findChildren(QtWidgets.QFrame, "")[0] @@ -121,11 +126,11 @@ class AddRemoveInputEventsTest(EditorTestHelper): input_event_group = input_event_groups[1] no_of_elements_label = input_event_group.findChild(QtWidgets.QLabel, "DefaultLabel") return no_of_elements_label.text() + return "" - return ""; - success = await pyside_utils.wait_for_condition(lambda: "2 elements" in get_elements_label_text(asset_editor_widget), 2.0) - if success: - print("Event Group deleted when the Delete button is clicked on an Event Group") + success = await pyside_utils.wait_for_condition(lambda: "2 elements" in + get_elements_label_text(asset_editor_widget), 2.0) + Report.result(Tests.single_event_group_deleted, success) # 8) Click on Delete button to delete all the Event Groups # First QToolButton child of active input_event_groups is +, Second QToolButton is Delete @@ -141,13 +146,17 @@ class AddRemoveInputEventsTest(EditorTestHelper): yes_button.click() # 9) Verify if all the elements are deleted - success = await pyside_utils.wait_for_condition(lambda: "0 elements" in get_elements_label_text(asset_editor_widget), 2.0) - if success: - print("All event groups deleted on clicking the Delete button") + success = await pyside_utils.wait_for_condition(lambda: "0 elements" in + get_elements_label_text(asset_editor_widget), 2.0) + Report.result(Tests.all_event_groups_deleted, success) # 10) Close Asset Editor - print(f"Asset Editor closed: {close_asset_editor()}") + Report.result(Tests.asset_editor_closed, close_asset_editor()) + + run_test() + +if __name__ == "__main__": -test = AddRemoveInputEventsTest() -test.run() + from editor_python_test_tools.utils import Report + Report.start_test(InputBindings_Add_Remove_Input_Events) diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_EditMenuOptions.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_EditMenuOptions.py index 53a8da4116..c7088a54c5 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_EditMenuOptions.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_EditMenuOptions.py @@ -5,93 +5,78 @@ For complete copyright and license terms please see the LICENSE at the root of t SPDX-License-Identifier: Apache-2.0 OR MIT """ -""" -C24064529: Base Edit Menu Options -""" - -import os -import sys - -import azlmbr.paths - -sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests')) -from editor_python_test_tools.editor_test_helper import EditorTestHelper -import editor_python_test_tools.pyside_utils as pyside_utils - - -class TestEditMenuOptions(EditorTestHelper): - def __init__(self): - EditorTestHelper.__init__(self, log_prefix="Menus_EditMenuOptions", args=["level"]) - - def run_test(self): - """ - Summary: - Interact with Edit Menu options and verify if all the options are working. - - Expected Behavior: - The Edit menu functions normally. - Test Steps: - 1) Create a temp level - 2) Interact with Edit Menu options - - Note: - - This test file must be called from the O3DE Editor command terminal - - Any passed and failed tests are written to the Editor.log file. - Parsing the file or running a log_monitor are required to observe the test results. - - :return: None - """ - edit_menu_options = [ - ("Undo",), - ("Redo",), - ("Duplicate",), - ("Delete",), - ("Select All",), - ("Invert Selection",), - ("Toggle Pivot Location",), - ("Reset Entity Transform",), - ("Reset Manipulator",), - ("Reset Transform (Local)",), - ("Reset Transform (World)",), - ("Hide Selection",), - ("Show All",), - ("Modify", "Snap", "Snap angle"), - ("Modify", "Transform Mode", "Move"), - ("Modify", "Transform Mode", "Rotate"), - ("Modify", "Transform Mode", "Scale"), - ("Editor Settings", "Global Preferences"), - ("Editor Settings", "Editor Settings Manager"), - ("Editor Settings", "Keyboard Customization", "Customize Keyboard"), - ("Editor Settings", "Keyboard Customization", "Export Keyboard Settings"), - ("Editor Settings", "Keyboard Customization", "Import Keyboard Settings"), - ] - - # 1) Create and open the temp level - self.test_success = self.create_level( - self.args["level"], - heightmap_resolution=1024, - heightmap_meters_per_pixel=1, - terrain_texture_resolution=4096, - use_terrain=False, - ) - - def on_action_triggered(action_name): - print(f"{action_name} Action triggered") - - # 2) Interact with Edit Menu options +def Menus_EditMenuOptions_Work(): + """ + Summary: + Interact with Edit Menu options and verify if all the options are working. + + Expected Behavior: + The Edit menu functions normally. + + Test Steps: + 1) Open an existing level + 2) Interact with Edit Menu options + + Note: + - This test file must be called from the O3DE Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + + import editor_python_test_tools.pyside_utils as pyside_utils + from editor_python_test_tools.utils import Report + from editor_python_test_tools.utils import TestHelper as helper + + edit_menu_options = [ + ("Undo",), + ("Redo",), + ("Duplicate",), + ("Delete",), + ("Select All",), + ("Invert Selection",), + ("Toggle Pivot Location",), + ("Reset Entity Transform",), + ("Reset Manipulator",), + ("Reset Transform (Local)",), + ("Reset Transform (World)",), + ("Hide Selection",), + ("Show All",), + ("Modify", "Snap", "Snap angle"), + ("Modify", "Transform Mode", "Move"), + ("Modify", "Transform Mode", "Rotate"), + ("Modify", "Transform Mode", "Scale"), + ("Editor Settings", "Global Preferences"), + ("Editor Settings", "Editor Settings Manager"), + ("Editor Settings", "Keyboard Customization", "Customize Keyboard"), + ("Editor Settings", "Keyboard Customization", "Export Keyboard Settings"), + ("Editor Settings", "Keyboard Customization", "Import Keyboard Settings"), + ] + + # 1) Open an existing simple level + helper.init_idle() + helper.open_level("Physics", "Base") + + # 2) Interact with Edit Menu options + editor_window = pyside_utils.get_editor_main_window() + for option in edit_menu_options: try: - editor_window = pyside_utils.get_editor_main_window() - for option in edit_menu_options: - action = pyside_utils.get_action_for_menu_path(editor_window, "Edit", *option) - trig_func = lambda: on_action_triggered(action.iconText()) - action.triggered.connect(trig_func) - action.trigger() - action.triggered.disconnect(trig_func) + action = pyside_utils.get_action_for_menu_path(editor_window, "Edit", *option) + action.trigger() + action_triggered = True except Exception as e: - self.test_success = False + action_triggered = False print(e) + menu_action_triggered = ( + f"{action.iconText()} action triggered successfully", + f"Failed to trigger {action.iconText()} action" + ) + Report.result(menu_action_triggered, action_triggered) + +if __name__ == "__main__": -test = TestEditMenuOptions() -test.run() + from editor_python_test_tools.utils import Report + Report.start_test(Menus_EditMenuOptions_Work) diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_FileMenuOptions.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_FileMenuOptions.py index 77ee9ac61d..a3e7611b5e 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_FileMenuOptions.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_FileMenuOptions.py @@ -5,80 +5,69 @@ For complete copyright and license terms please see the LICENSE at the root of t SPDX-License-Identifier: Apache-2.0 OR MIT """ -import os -import sys -import azlmbr.paths - -sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests')) -from editor_python_test_tools.editor_test_helper import EditorTestHelper -import editor_python_test_tools.pyside_utils as pyside_utils - - -class TestFileMenuOptions(EditorTestHelper): - def __init__(self): - EditorTestHelper.__init__(self, log_prefix="file_menu_options: ", args=["level"]) - - def run_test(self): - """ - Summary: - Interact with File Menu options and verify if all the options are working. - - Expected Behavior: - The File menu functions normally. - - Test Steps: - 1) Open level - 2) Interact with File Menu options - - Note: - - This test file must be called from the O3DE Editor command terminal - - Any passed and failed tests are written to the Editor.log file. - Parsing the file or running a log_monitor are required to observe the test results. - - :return: None - """ - file_menu_options = [ - ("New Level",), - ("Open Level",), - ("Import",), - ("Save",), - ("Save As",), - ("Save Level Statistics",), - ("Edit Project Settings",), - ("Edit Platform Settings",), - ("New Project",), - ("Open Project",), - ("Show Log File",), - ("Resave All Slices",), - ("Exit",), - ] - - # 1) Open level - self.test_success = self.create_level( - self.args["level"], - heightmap_resolution=1024, - heightmap_meters_per_pixel=1, - terrain_texture_resolution=4096, - use_terrain=False, - ) - - def on_action_triggered(action_name): - print(f"{action_name} Action triggered") - - # 2) Interact with File Menu options +def Menus_FileMenuOptions_Work(): + """ + Summary: + Interact with File Menu options and verify if all the options are working. + + Expected Behavior: + The File menu functions normally. + + Test Steps: + 1) Open level + 2) Interact with File Menu options + + Note: + - This test file must be called from the O3DE Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + + import editor_python_test_tools.pyside_utils as pyside_utils + from editor_python_test_tools.utils import Report + from editor_python_test_tools.utils import TestHelper as helper + + file_menu_options = [ + ("New Level",), + ("Open Level",), + ("Import",), + ("Save",), + ("Save As",), + ("Save Level Statistics",), + ("Edit Project Settings",), + ("Edit Platform Settings",), + ("New Project",), + ("Open Project",), + ("Show Log File",), + ("Resave All Slices",), + ("Exit",), + ] + + # 1) Open an existing simple level + helper.init_idle() + helper.open_level("Physics", "Base") + + # 2) Interact with File Menu options + editor_window = pyside_utils.get_editor_main_window() + for option in file_menu_options: try: - editor_window = pyside_utils.get_editor_main_window() - for option in file_menu_options: - action = pyside_utils.get_action_for_menu_path(editor_window, "File", *option) - trig_func = lambda: on_action_triggered(action.iconText()) - action.triggered.connect(trig_func) - action.trigger() - action.triggered.disconnect(trig_func) + action = pyside_utils.get_action_for_menu_path(editor_window, "File", *option) + action.trigger() + action_triggered = True except Exception as e: - self.test_success = False + action_triggered = False print(e) + menu_action_triggered = ( + f"{action.iconText()} action triggered successfully", + f"Failed to trigger {action.iconText()} action" + ) + Report.result(menu_action_triggered, action_triggered) + +if __name__ == "__main__": -test = TestFileMenuOptions() -test.run() + from editor_python_test_tools.utils import Report + Report.start_test(Menus_FileMenuOptions_Work) diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_ViewMenuOptions.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_ViewMenuOptions.py index d2db4210ce..f1b9e5d4d8 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_ViewMenuOptions.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_ViewMenuOptions.py @@ -5,81 +5,66 @@ For complete copyright and license terms please see the LICENSE at the root of t SPDX-License-Identifier: Apache-2.0 OR MIT """ -""" -C24064534: The View menu options function normally -""" - -import os -import sys - -import azlmbr.paths - -sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests')) -from editor_python_test_tools.editor_test_helper import EditorTestHelper -import editor_python_test_tools.pyside_utils as pyside_utils - - -class TestViewMenuOptions(EditorTestHelper): - def __init__(self): - EditorTestHelper.__init__(self, log_prefix="Menus_EditMenuOptions", args=["level"]) - - def run_test(self): - """ - Summary: - Interact with View Menu options and verify if all the options are working. - - Expected Behavior: - The View menu functions normally. - Test Steps: - 1) Create a temp level - 2) Interact with View Menu options - - Note: - - This test file must be called from the O3DE Editor command terminal - - Any passed and failed tests are written to the Editor.log file. - Parsing the file or running a log_monitor are required to observe the test results. - - :return: None - """ - view_menu_options = [ - ("Center on Selection",), - ("Show Quick Access Bar",), - ("Viewport", "Configure Layout"), - ("Viewport", "Go to Position"), - ("Viewport", "Center on Selection"), - ("Viewport", "Go to Location"), - ("Viewport", "Remember Location"), - ("Viewport", "Switch Camera"), - ("Viewport", "Show/Hide Helpers"), - ("Refresh Style",), - ] - - # 1) Create and open the temp level - self.test_success = self.create_level( - self.args["level"], - heightmap_resolution=1024, - heightmap_meters_per_pixel=1, - terrain_texture_resolution=4096, - use_terrain=False, - ) - - def on_action_triggered(action_name): - print(f"{action_name} Action triggered") - - # 2) Interact with View Menu options +def Menus_ViewMenuOptions_Work(): + """ + Summary: + Interact with View Menu options and verify if all the options are working. + + Expected Behavior: + The View menu functions normally. + + Test Steps: + 1) Open an existing level + 2) Interact with View Menu options + + Note: + - This test file must be called from the O3DE Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + + import editor_python_test_tools.pyside_utils as pyside_utils + from editor_python_test_tools.utils import Report + from editor_python_test_tools.utils import TestHelper as helper + + view_menu_options = [ + ("Center on Selection",), + ("Show Quick Access Bar",), + ("Viewport", "Configure Layout"), + ("Viewport", "Go to Position"), + ("Viewport", "Center on Selection"), + ("Viewport", "Go to Location"), + ("Viewport", "Remember Location"), + ("Viewport", "Switch Camera"), + ("Viewport", "Show/Hide Helpers"), + ("Refresh Style",), + ] + + # 1) Open an existing simple level + helper.init_idle() + helper.open_level("Physics", "Base") + + # 2) Interact with View Menu options + editor_window = pyside_utils.get_editor_main_window() + for option in view_menu_options: try: - editor_window = pyside_utils.get_editor_main_window() - for option in view_menu_options: - action = pyside_utils.get_action_for_menu_path(editor_window, "View", *option) - trig_func = lambda: on_action_triggered(action.iconText()) - action.triggered.connect(trig_func) - action.trigger() - action.triggered.disconnect(trig_func) + action = pyside_utils.get_action_for_menu_path(editor_window, "View", *option) + action.trigger() + action_triggered = True except Exception as e: - self.test_success = False + action_triggered = False print(e) + menu_action_triggered = ( + f"{action.iconText()} action triggered successfully", + f"Failed to trigger {action.iconText()} action" + ) + Report.result(menu_action_triggered, action_triggered) + +if __name__ == "__main__": -test = TestViewMenuOptions() -test.run() + from editor_python_test_tools.utils import Report + Report.start_test(Menus_ViewMenuOptions_Work) diff --git a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main.py b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main.py new file mode 100644 index 0000000000..26b254ae71 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main.py @@ -0,0 +1,43 @@ +""" +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 +""" + +import os +import pytest +import sys + +import ly_test_tools.environment.file_system as file_system + +sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../automatedtesting_shared') +from base import TestAutomationBase + + +@pytest.fixture +def remove_test_level(request, workspace, project): + file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", "tmp_level")], True, True) + + def teardown(): + file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", "tmp_level")], True, True) + + request.addfinalizer(teardown) + + +@pytest.mark.SUITE_main +@pytest.mark.parametrize("launcher_platform", ['windows_editor']) +@pytest.mark.parametrize("project", ["AutomatedTesting"]) +class TestAutomation(TestAutomationBase): + + def test_BasicEditorWorkflows_LevelEntityComponentCRUD(self, request, workspace, editor, launcher_platform, + remove_test_level): + from .EditorScripts import BasicEditorWorkflows_LevelEntityComponentCRUD as test_module + self._run_test(request, workspace, editor, test_module, batch_mode=False, autotest_mode=False) + + @pytest.mark.REQUIRES_gpu + def test_BasicEditorWorkflows_GPU_LevelEntityComponentCRUD(self, request, workspace, editor, launcher_platform, + remove_test_level): + from .EditorScripts import BasicEditorWorkflows_LevelEntityComponentCRUD as test_module + self._run_test(request, workspace, editor, test_module, batch_mode=False, autotest_mode=False, + use_null_renderer=False) diff --git a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py new file mode 100644 index 0000000000..9c0b99daff --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py @@ -0,0 +1,75 @@ +""" +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 +""" + +import os +import pytest + +import ly_test_tools.environment.file_system as file_system +from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite + + +@pytest.mark.xfail(reason="Optimized tests are experimental, we will enable xfail and monitor them temporarily.") +@pytest.mark.SUITE_main +@pytest.mark.parametrize("launcher_platform", ['windows_editor']) +@pytest.mark.parametrize("project", ["AutomatedTesting"]) +class TestAutomationNoAutoTestMode(EditorTestSuite): + + # Disable -autotest_mode and -BatchMode. Tests cannot run in -BatchMode due to UI interactions, and these tests + # interact with modal dialogs + global_extra_cmdline_args = [] + + class test_BasicEditorWorkflows_LevelEntityComponentCRUD(EditorSingleTest): + # Custom teardown to remove slice asset created during test + def teardown(self, request, workspace, editor, editor_test_results, launcher_platform): + file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "Levels", "tmp_level")], + True, True) + from .EditorScripts import BasicEditorWorkflows_LevelEntityComponentCRUD as test_module + + @pytest.mark.REQUIRES_gpu + class test_BasicEditorWorkflows_GPU_LevelEntityComponentCRUD(EditorSingleTest): + # Disable null renderer + use_null_renderer = False + + # Custom teardown to remove slice asset created during test + def teardown(self, request, workspace, editor, editor_test_results, launcher_platform): + file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "Levels", "tmp_level")], + True, True) + from .EditorScripts import BasicEditorWorkflows_LevelEntityComponentCRUD as test_module + + class test_InputBindings_Add_Remove_Input_Events(EditorSharedTest): + from .EditorScripts import InputBindings_Add_Remove_Input_Events as test_module + + @pytest.mark.skip(reason="Crashes Editor: ATOM-15493") + class test_AssetPicker_UI_UX(EditorSharedTest): + from .EditorScripts import AssetPicker_UI_UX as test_module + + +@pytest.mark.xfail(reason="Optimized tests are experimental, we will enable xfail and monitor them temporarily.") +@pytest.mark.SUITE_main +@pytest.mark.parametrize("launcher_platform", ['windows_editor']) +@pytest.mark.parametrize("project", ["AutomatedTesting"]) +class TestAutomationAutoTestMode(EditorTestSuite): + + # Enable only -autotest_mode for these tests. Tests cannot run in -BatchMode due to UI interactions + global_extra_cmdline_args = ["-autotest_mode"] + + class test_AssetBrowser_TreeNavigation(EditorSharedTest): + from .EditorScripts import AssetBrowser_TreeNavigation as test_module + + @pytest.mark.skip(reason="Crashes Editor: ATOM-15493") + class test_AssetBrowser_SearchFiltering(EditorSharedTest): + from .EditorScripts import AssetBrowser_SearchFiltering as test_module + + class test_ComponentCRUD_Add_Delete_Components(EditorSharedTest): + from .EditorScripts import ComponentCRUD_Add_Delete_Components as test_module + + class test_Menus_ViewMenuOptions_Work(EditorSharedTest): + from .EditorScripts import Menus_ViewMenuOptions as test_module + + @pytest.mark.skip(reason="Times out due to dialogs failing to dismiss: LYN-4208") + class test_Menus_FileMenuOptions_Work(EditorSharedTest): + from .EditorScripts import Menus_FileMenuOptions as test_module diff --git a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Periodic.py b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Periodic.py new file mode 100644 index 0000000000..398b64bc87 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Periodic.py @@ -0,0 +1,62 @@ +""" +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 +""" + +import os +import pytest +import sys + +import ly_test_tools.environment.file_system as file_system + +sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../automatedtesting_shared') +from base import TestAutomationBase + + +@pytest.fixture +def remove_test_level(request, workspace, project): + file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", "tmp_level")], True, True) + + def teardown(): + file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", "tmp_level")], True, True) + + request.addfinalizer(teardown) + + +@pytest.mark.SUITE_periodic +@pytest.mark.parametrize("launcher_platform", ['windows_editor']) +@pytest.mark.parametrize("project", ["AutomatedTesting"]) +class TestAutomation(TestAutomationBase): + + def test_AssetBrowser_TreeNavigation(self, request, workspace, editor, launcher_platform): + from .EditorScripts import AssetBrowser_TreeNavigation as test_module + self._run_test(request, workspace, editor, test_module, batch_mode=False) + + @pytest.mark.skip(reason="Crashes Editor: ATOM-15493") + def test_AssetBrowser_SearchFiltering(self, request, workspace, editor, launcher_platform): + from .EditorScripts import AssetBrowser_SearchFiltering as test_module + self._run_test(request, workspace, editor, test_module, batch_mode=False) + + @pytest.mark.skip(reason="Crashes Editor: ATOM-15493") + def test_AssetPicker_UI_UX(self, request, workspace, editor, launcher_platform): + from .EditorScripts import AssetPicker_UI_UX as test_module + self._run_test(request, workspace, editor, test_module, autotest_mode=False, batch_mode=False) + + def test_ComponentCRUD_Add_Delete_Components(self, request, workspace, editor, launcher_platform): + from .EditorScripts import ComponentCRUD_Add_Delete_Components as test_module + self._run_test(request, workspace, editor, test_module, batch_mode=False) + + def test_InputBindings_Add_Remove_Input_Events(self, request, workspace, editor, launcher_platform): + from .EditorScripts import InputBindings_Add_Remove_Input_Events as test_module + self._run_test(request, workspace, editor, test_module, batch_mode=False, autotest_mode=False) + + def test_Menus_ViewMenuOptions_Work(self, request, workspace, editor, launcher_platform): + from .EditorScripts import Menus_ViewMenuOptions as test_module + self._run_test(request, workspace, editor, test_module, batch_mode=False) + + @pytest.mark.skip(reason="Times out due to dialogs failing to dismiss: LYN-4208") + def test_Menus_FileMenuOptions_Work(self, request, workspace, editor, launcher_platform): + from .EditorScripts import Menus_FileMenuOptions as test_module + self._run_test(request, workspace, editor, test_module, batch_mode=False) diff --git a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Sandbox.py b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Sandbox.py new file mode 100644 index 0000000000..98a6620d9c --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Sandbox.py @@ -0,0 +1,27 @@ +""" +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 +""" + +import os +import pytest +import sys + +sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../automatedtesting_shared') +from base import TestAutomationBase + + +@pytest.mark.SUITE_sandbox +@pytest.mark.parametrize("launcher_platform", ['windows_editor']) +@pytest.mark.parametrize("project", ["AutomatedTesting"]) +class TestAutomation(TestAutomationBase): + + def test_Menus_EditMenuOptions_Work(self, request, workspace, editor, launcher_platform): + from .EditorScripts import Menus_EditMenuOptions as test_module + self._run_test(request, workspace, editor, test_module, batch_mode=False) + + def test_Docking_BasicDockedTools(self, request, workspace, editor, launcher_platform): + from .EditorScripts import Docking_BasicDockedTools as test_module + self._run_test(request, workspace, editor, test_module, batch_mode=False) diff --git a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Sandbox_Optimized.py b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Sandbox_Optimized.py new file mode 100644 index 0000000000..d49e9e1c9b --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Sandbox_Optimized.py @@ -0,0 +1,27 @@ +""" +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 +""" + +import os +import pytest + +from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite + + +@pytest.mark.xfail(reason="Optimized tests are experimental, we will enable xfail and monitor them temporarily.") +@pytest.mark.SUITE_sandbox +@pytest.mark.parametrize("launcher_platform", ['windows_editor']) +@pytest.mark.parametrize("project", ["AutomatedTesting"]) +class TestAutomationAutoTestMode(EditorTestSuite): + + # Enable only -autotest_mode for these tests. Tests cannot run in -BatchMode due to UI interactions + global_extra_cmdline_args = ["-autotest_mode"] + + class test_Docking_BasicDockedTools(EditorSharedTest): + from .EditorScripts import Docking_BasicDockedTools as test_module + + class test_Menus_EditMenuOptions_Work(EditorSharedTest): + from .EditorScripts import Menus_EditMenuOptions as test_module diff --git a/AutomatedTesting/Gem/PythonTests/editor/test_AssetBrowser.py b/AutomatedTesting/Gem/PythonTests/editor/test_AssetBrowser.py deleted file mode 100644 index 6067ffd1c0..0000000000 --- a/AutomatedTesting/Gem/PythonTests/editor/test_AssetBrowser.py +++ /dev/null @@ -1,89 +0,0 @@ -""" -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 -""" - -""" -C13660195: Asset Browser - File Tree Navigation -""" - -import os -import pytest - -# Bail on the test if ly_test_tools doesn't exist. -pytest.importorskip('ly_test_tools') -import ly_test_tools.environment.file_system as file_system -import editor_python_test_tools.hydra_test_utils as hydra - -test_directory = os.path.join(os.path.dirname(__file__), "EditorScripts") -log_monitor_timeout = 180 - - -@pytest.mark.parametrize('project', ['AutomatedTesting']) -@pytest.mark.parametrize('level', ['tmp_level']) -@pytest.mark.usefixtures("automatic_process_killer") -@pytest.mark.parametrize("launcher_platform", ['windows_editor']) -class TestAssetBrowser(object): - - @pytest.fixture(autouse=True) - def setup_teardown(self, request, workspace, project, level): - def teardown(): - file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True) - - request.addfinalizer(teardown) - - file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True) - - @pytest.mark.test_case_id("C13660195") - @pytest.mark.SUITE_periodic - def test_AssetBrowser_TreeNavigation(self, request, editor, level, launcher_platform): - expected_lines = [ - "Collapse/Expand tests: True", - "Asset visibility test: True", - "Scrollbar visibility test: True", - "AssetBrowser_TreeNavigation: result=SUCCESS" - - ] - - hydra.launch_and_validate_results( - request, - test_directory, - editor, - "AssetBrowser_TreeNavigation.py", - expected_lines, - run_python="--runpython", - cfg_args=[level], - timeout=log_monitor_timeout - ) - - @pytest.mark.test_case_id("C13660194") - @pytest.mark.SUITE_periodic - def test_AssetBrowser_SearchFiltering(self, request, editor, level, launcher_platform): - expected_lines = [ - "cedar.fbx asset is filtered in Asset Browser", - "Animation file type(s) is present in the file tree: True", - "FileTag file type(s) and Animation file type(s) is present in the file tree: True", - "FileTag file type(s) is present in the file tree after removing Animation filter: True", - ] - - unexpected_lines = [ - "Asset Browser opened: False", - "Animation file type(s) is present in the file tree: False", - "FileTag file type(s) and Animation file type(s) is present in the file tree: False", - "FileTag file type(s) is present in the file tree after removing Animation filter: False", - ] - - hydra.launch_and_validate_results( - request, - test_directory, - editor, - "AssetBrowser_SearchFiltering.py", - expected_lines, - unexpected_lines=unexpected_lines, - cfg_args=[level], - auto_test_mode=False, - run_python="--runpython", - timeout=log_monitor_timeout, - ) diff --git a/AutomatedTesting/Gem/PythonTests/editor/test_AssetPicker.py b/AutomatedTesting/Gem/PythonTests/editor/test_AssetPicker.py deleted file mode 100644 index 9fc5582e0b..0000000000 --- a/AutomatedTesting/Gem/PythonTests/editor/test_AssetPicker.py +++ /dev/null @@ -1,74 +0,0 @@ -""" -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 -""" - -""" -C13751579: Asset Picker UI/UX -""" - -import os -import pytest - -# Bail on the test if ly_test_tools doesn't exist. -pytest.importorskip('ly_test_tools') -import ly_test_tools.environment.file_system as file_system -import editor_python_test_tools.hydra_test_utils as hydra - -test_directory = os.path.join(os.path.dirname(__file__), "EditorScripts") -log_monitor_timeout = 90 - - -@pytest.mark.parametrize('project', ['AutomatedTesting']) -@pytest.mark.parametrize('level', ['tmp_level']) -@pytest.mark.usefixtures("automatic_process_killer") -@pytest.mark.parametrize("launcher_platform", ['windows_editor']) -class TestAssetPicker(object): - - @pytest.fixture(autouse=True) - def setup_teardown(self, request, workspace, project, level): - def teardown(): - file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True) - - request.addfinalizer(teardown) - - file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True) - - @pytest.mark.test_case_id("C13751579", "C1508814") - @pytest.mark.SUITE_periodic - @pytest.mark.xfail # ATOM-15493 - def test_AssetPicker_UI_UX(self, request, editor, level, launcher_platform): - expected_lines = [ - "TestEntity Entity successfully created", - "Mesh component was added to entity", - "Entity has a Mesh component", - "Mesh Asset: Asset Picker title for Mesh: Pick ModelAsset", - "Mesh Asset: Scroll Bar is not visible before expanding the tree: True", - "Mesh Asset: Top level folder initially collapsed: True", - "Mesh Asset: Top level folder expanded: True", - "Mesh Asset: Nested folder initially collapsed: True", - "Mesh Asset: Nested folder expanded: True", - "Mesh Asset: Scroll Bar appeared after expanding tree: True", - "Mesh Asset: Nested folder collapsed: True", - "Mesh Asset: Top level folder collapsed: True", - "Mesh Asset: Expected Assets populated in the file picker: True", - "Widget Move Test: True", - "Widget Resize Test: True", - "Asset assigned for ok option: True", - "Asset assigned for enter option: True", - "AssetPicker_UI_UX: result=SUCCESS" - ] - - hydra.launch_and_validate_results( - request, - test_directory, - editor, - "AssetPicker_UI_UX.py", - expected_lines, - cfg_args=[level], - run_python="--runpython", - auto_test_mode=False, - timeout=log_monitor_timeout, - ) diff --git a/AutomatedTesting/Gem/PythonTests/editor/test_BasicEditorWorkflows.py b/AutomatedTesting/Gem/PythonTests/editor/test_BasicEditorWorkflows.py deleted file mode 100644 index 49860c8387..0000000000 --- a/AutomatedTesting/Gem/PythonTests/editor/test_BasicEditorWorkflows.py +++ /dev/null @@ -1,96 +0,0 @@ -""" -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 -""" - -import os -import pytest - -# Bail on the test if ly_test_tools doesn't exist. -pytest.importorskip('ly_test_tools') -import ly_test_tools.environment.file_system as file_system -import ly_test_tools._internal.pytest_plugin as internal_plugin -import editor_python_test_tools.hydra_test_utils as hydra - -test_directory = os.path.join(os.path.dirname(__file__), "EditorScripts") -log_monitor_timeout = 180 - - -@pytest.mark.parametrize('project', ['AutomatedTesting']) -@pytest.mark.parametrize('level', ['tmp_level']) -@pytest.mark.usefixtures("automatic_process_killer") -@pytest.mark.parametrize("launcher_platform", ['windows_editor']) -class TestBasicEditorWorkflows(object): - - @pytest.fixture(autouse=True) - def setup_teardown(self, request, workspace, project, level): - def teardown(): - file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True) - - request.addfinalizer(teardown) - - file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True) - - @pytest.mark.test_case_id("C6351273", "C6384955", "C16929880", "C15167490", "C15167491") - @pytest.mark.SUITE_main - def test_BasicEditorWorkflows_LevelEntityComponentCRUD(self, request, editor, level, launcher_platform): - - # Skip test if running against Debug build - if "debug" in internal_plugin.build_directory: - pytest.skip("Does not execute against debug builds.") - - expected_lines = [ - "Create and load new level: True", - "New entity creation: True", - "Create entity hierarchy: True", - "Add component: True", - "Component update: True", - "Remove component: True", - "Save and Export: True", - "BasicEditorWorkflows_LevelEntityComponent: result=SUCCESS", - ] - - hydra.launch_and_validate_results( - request, - test_directory, - editor, - "BasicEditorWorkflows_LevelEntityComponentCRUD.py", - expected_lines, - cfg_args=[level], - timeout=log_monitor_timeout, - auto_test_mode=False - ) - - @pytest.mark.test_case_id("C6351273", "C6384955", "C16929880", "C15167490", "C15167491") - @pytest.mark.SUITE_main - @pytest.mark.REQUIRES_gpu - def test_BasicEditorWorkflows_GPU_LevelEntityComponentCRUD(self, request, editor, level, launcher_platform): - - # Skip test if running against Debug build - if "debug" in internal_plugin.build_directory: - pytest.skip("Does not execute against debug builds.") - - expected_lines = [ - "Create and load new level: True", - "New entity creation: True", - "Create entity hierarchy: True", - "Add component: True", - "Component update: True", - "Remove component: True", - "Save and Export: True", - "BasicEditorWorkflows_LevelEntityComponent: result=SUCCESS", - ] - - hydra.launch_and_validate_results( - request, - test_directory, - editor, - "BasicEditorWorkflows_LevelEntityComponentCRUD.py", - expected_lines, - cfg_args=[level], - timeout=log_monitor_timeout, - auto_test_mode=False, - null_renderer=False - ) diff --git a/AutomatedTesting/Gem/PythonTests/editor/test_ComponentCRUD.py b/AutomatedTesting/Gem/PythonTests/editor/test_ComponentCRUD.py deleted file mode 100755 index de09cf9ab7..0000000000 --- a/AutomatedTesting/Gem/PythonTests/editor/test_ComponentCRUD.py +++ /dev/null @@ -1,62 +0,0 @@ -""" -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 -""" - -""" -C16929880: Add Delete Components -""" - -import os -import pytest - -# Bail on the test if ly_test_tools doesn't exist. -pytest.importorskip('ly_test_tools') -import ly_test_tools.environment.file_system as file_system -import editor_python_test_tools.hydra_test_utils as hydra - -test_directory = os.path.join(os.path.dirname(__file__), "EditorScripts") -log_monitor_timeout = 180 - - -@pytest.mark.parametrize('project', ['AutomatedTesting']) -@pytest.mark.parametrize('level', ['tmp_level']) -@pytest.mark.usefixtures("automatic_process_killer") -@pytest.mark.parametrize("launcher_platform", ['windows_editor']) -class TestComponentCRUD(object): - - @pytest.fixture(autouse=True) - def setup_teardown(self, request, workspace, project, level): - def teardown(): - file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True) - - request.addfinalizer(teardown) - - file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True) - - @pytest.mark.test_case_id("C16929880", "C16877220") - @pytest.mark.SUITE_periodic - @pytest.mark.BAT - def test_ComponentCRUD_Add_Delete_Components(self, request, editor, level, launcher_platform): - expected_lines = [ - "Entity Created", - "Box Shape found", - "Box Shape Component added: True", - "Mesh found", - "Mesh Component added: True", - "Mesh Component deleted: True", - "Mesh Component deletion undone: True", - ] - - hydra.launch_and_validate_results( - request, - test_directory, - editor, - "ComponentCRUD_Add_Delete_Components.py", - expected_lines, - cfg_args=[level], - auto_test_mode=False, - timeout=log_monitor_timeout - ) diff --git a/AutomatedTesting/Gem/PythonTests/editor/test_Docking.py b/AutomatedTesting/Gem/PythonTests/editor/test_Docking.py deleted file mode 100644 index 7d97f31710..0000000000 --- a/AutomatedTesting/Gem/PythonTests/editor/test_Docking.py +++ /dev/null @@ -1,55 +0,0 @@ -""" -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 - -C6376081: Basic Function: Docked/Undocked Tools -""" - -import os -import pytest - -# Bail on the test if ly_test_tools doesn't exist. -pytest.importorskip('ly_test_tools') -import ly_test_tools.environment.file_system as file_system -import editor_python_test_tools.hydra_test_utils as hydra - -test_directory = os.path.join(os.path.dirname(__file__), "EditorScripts") -log_monitor_timeout = 180 - - -@pytest.mark.parametrize('project', ['AutomatedTesting']) -@pytest.mark.parametrize('level', ['tmp_level']) -@pytest.mark.usefixtures("automatic_process_killer") -@pytest.mark.parametrize("launcher_platform", ['windows_editor']) -class TestDocking(object): - - @pytest.fixture(autouse=True) - def setup_teardown(self, request, workspace, project, level): - def teardown(): - file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True) - - request.addfinalizer(teardown) - - file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True) - - @pytest.mark.test_case_id("C6376081") - @pytest.mark.SUITE_sandbox - def test_Docking_BasicDockedTools(self, request, editor, level, launcher_platform): - expected_lines = [ - "The tools are all docked together in a tabbed widget", - "Entity Outliner works when docked, can select an Entity", - "Entity Inspector works when docked, Entity name changed to DifferentName", - "Hello, world!" # This line verifies the Console is working while docked - ] - - hydra.launch_and_validate_results( - request, - test_directory, - editor, - "Docking_BasicDockedTools.py", - expected_lines, - cfg_args=[level], - timeout=log_monitor_timeout, - ) diff --git a/AutomatedTesting/Gem/PythonTests/editor/test_InputBindings.py b/AutomatedTesting/Gem/PythonTests/editor/test_InputBindings.py deleted file mode 100755 index 214fac2af4..0000000000 --- a/AutomatedTesting/Gem/PythonTests/editor/test_InputBindings.py +++ /dev/null @@ -1,66 +0,0 @@ -""" -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 -""" - -""" -C1506881: Adding/Removing Event Groups -""" - -import os -import pytest - -# Bail on the test if ly_test_tools doesn't exist. -pytest.importorskip('ly_test_tools') -import ly_test_tools.environment.file_system as file_system -import editor_python_test_tools.hydra_test_utils as hydra - -test_directory = os.path.join(os.path.dirname(__file__), "EditorScripts") -log_monitor_timeout = 180 - - -@pytest.mark.parametrize('project', ['AutomatedTesting']) -@pytest.mark.parametrize('level', ['tmp_level']) -@pytest.mark.usefixtures("automatic_process_killer") -@pytest.mark.parametrize("launcher_platform", ['windows_editor']) -class TestInputBindings(object): - - @pytest.fixture(autouse=True) - def setup_teardown(self, request, workspace, project, level): - def teardown(): - file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True) - - request.addfinalizer(teardown) - - file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True) - - @pytest.mark.test_case_id("C1506881") - @pytest.mark.SUITE_periodic - def test_InputBindings_Add_Remove_Input_Events(self, request, editor, level, launcher_platform): - expected_lines = [ - "Asset Editor opened: True", - "New Event Groups added when + is clicked", - "Event Group deleted when the Delete button is clicked on an Event Group", - "All event groups deleted on clicking the Delete button", - "Asset Editor closed: True", - ] - - unexpected_lines = [ - "Asset Editor opened: False", - "Asset Editor closed: False", - ] - - hydra.launch_and_validate_results( - request, - test_directory, - editor, - "InputBindings_Add_Remove_Input_Events.py", - expected_lines, - unexpected_lines=unexpected_lines, - cfg_args=[level], - run_python="--runpython", - auto_test_mode=False, - timeout=log_monitor_timeout, - ) diff --git a/AutomatedTesting/Gem/PythonTests/editor/test_Menus.py b/AutomatedTesting/Gem/PythonTests/editor/test_Menus.py deleted file mode 100644 index d35fd021ee..0000000000 --- a/AutomatedTesting/Gem/PythonTests/editor/test_Menus.py +++ /dev/null @@ -1,132 +0,0 @@ -""" -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 -""" - -import os -import pytest - -# Bail on the test if ly_test_tools doesn't exist. -pytest.importorskip('ly_test_tools') -import ly_test_tools.environment.file_system as file_system -import ly_test_tools.environment.process_utils as process_utils -import editor_python_test_tools.hydra_test_utils as hydra - -test_directory = os.path.join(os.path.dirname(__file__), "EditorScripts") -log_monitor_timeout = 180 - - -@pytest.mark.parametrize('project', ['AutomatedTesting']) -@pytest.mark.parametrize('level', ['tmp_level']) -@pytest.mark.usefixtures("automatic_process_killer") -@pytest.mark.parametrize("launcher_platform", ['windows_editor']) -class TestMenus(object): - - @pytest.fixture(autouse=True) - def setup_teardown(self, request, workspace, project, level): - def teardown(): - file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True) - process_utils.kill_processes_named("o3de", ignore_extensions=True) # Kill ProjectManager windows - - request.addfinalizer(teardown) - - file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True) - - @pytest.mark.test_case_id("C16780783", "C2174438") - @pytest.mark.SUITE_sandbox - def test_Menus_EditMenuOptions_Work(self, request, editor, level, launcher_platform): - expected_lines = [ - "Undo Action triggered", - "Redo Action triggered", - "Duplicate Action triggered", - "Delete Action triggered", - "Select All Action triggered", - "Invert Selection Action triggered", - "Toggle Pivot Location Action triggered", - "Reset Entity Transform", - "Reset Manipulator", - "Reset Transform (Local) Action triggered", - "Reset Transform (World) Action triggered", - "Hide Selection Action triggered", - "Show All Action triggered", - "Snap angle Action triggered", - "Move Action triggered", - "Rotate Action triggered", - "Scale Action triggered", - "Global Preferences Action triggered", - "Editor Settings Manager Action triggered", - "Customize Keyboard Action triggered", - "Export Keyboard Settings Action triggered", - "Import Keyboard Settings Action triggered", - "Menus_EditMenuOptions: result=SUCCESS" - ] - - hydra.launch_and_validate_results( - request, - test_directory, - editor, - "Menus_EditMenuOptions.py", - expected_lines, - cfg_args=[level], - run_python="--runpython", - timeout=log_monitor_timeout - ) - - @pytest.mark.test_case_id("C16780807") - @pytest.mark.SUITE_periodic - def test_Menus_ViewMenuOptions_Work(self, request, editor, level, launcher_platform): - expected_lines = [ - "Center on Selection Action triggered", - "Show Quick Access Bar Action triggered", - "Configure Layout Action triggered", - "Go to Position Action triggered", - "Center on Selection Action triggered", - "Go to Location Action triggered", - "Remember Location Action triggered", - "Switch Camera Action triggered", - "Show/Hide Helpers Action triggered", - "Refresh Style Action triggered", - ] - hydra.launch_and_validate_results( - request, - test_directory, - editor, - "Menus_ViewMenuOptions.py", - expected_lines, - cfg_args=[level], - run_python="--runpython", - timeout=log_monitor_timeout - ) - - @pytest.mark.test_case_id("C16780778") - @pytest.mark.SUITE_sandbox - @pytest.mark.xfail # LYN-4208 - def test_Menus_FileMenuOptions_Work(self, request, editor, level, launcher_platform): - expected_lines = [ - "New Level Action triggered", - "Open Level Action triggered", - "Import Action triggered", - "Save Action triggered", - "Save As Action triggered", - "Save Level Statistics Action triggered", - "Edit Project Settings Action triggered", - "Edit Platform Settings Action triggered", - "New Project Action triggered", - "Open Project Action triggered", - "Show Log File Action triggered", - "Resave All Slices Action triggered", - "Exit Action triggered", - ] - - hydra.launch_and_validate_results( - request, - test_directory, - editor, - "Menus_FileMenuOptions.py", - expected_lines, - cfg_args=[level], - run_python="--runpython", - timeout=log_monitor_timeout - ) diff --git a/Tools/LyTestTools/ly_test_tools/o3de/editor_test.py b/Tools/LyTestTools/ly_test_tools/o3de/editor_test.py index 0f456cee1a..4e15f32b37 100644 --- a/Tools/LyTestTools/ly_test_tools/o3de/editor_test.py +++ b/Tools/LyTestTools/ly_test_tools/o3de/editor_test.py @@ -62,8 +62,11 @@ class EditorTestBase(ABC): # Test that will be run alone in one editor class EditorSingleTest(EditorTestBase): + #- Configurable params -# # Extra cmdline arguments to supply to the editor for the test extra_cmdline_args = [] + # Whether to use null renderer, this will override use_null_renderer for the Suite if not None + use_null_renderer = None # Custom setup function, will run before the test @staticmethod @@ -584,7 +587,7 @@ class EditorTestSuite(): test_spec : EditorTestBase, cmdline_args : List[str] = []): test_cmdline_args = self.global_extra_cmdline_args + cmdline_args - if self.use_null_renderer: + if test_spec.use_null_renderer or (test_spec.use_null_renderer is None and self.use_null_renderer): test_cmdline_args += ["-rhi=null"] # Cycle any old crash report in case it wasn't cycled properly