Integrating latest 47acbe8

This commit is contained in:
alexpete
2021-03-25 13:57:57 -07:00
parent 448c549698
commit 75dc720198
10312 changed files with 2711566 additions and 671451 deletions
@@ -0,0 +1,136 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
"""
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 automatedtesting_shared.hydra_editor_utils as hydra
from automatedtesting_shared.editor_test_helper import EditorTestHelper
import automatedtesting_shared.pyside_utils as pyside_utils
class AddDeleteComponentsTest(EditorTestHelper):
def __init__(self):
EditorTestHelper.__init__(self, log_prefix="ComponentCRUD_Add_Delete_Components", args=["level"])
@pyside_utils.wrap_async
async def run_test(self):
"""
Summary:
Add/Delete Components to an entity.
Expected Behavior:
1) Components can be added to an entity.
2) Multiple components can be added to a single entity.
3) Components can be selected in the Entity Inspector.
4) Components can be deleted from entities.
5) Component deletion can be undone.
Test Steps:
1) Open level
2) Create entity
3) Select the newly created entity
4) Add/verify Box Shape Component
5) Add/verify Mesh component
6) Delete Mesh Component
7) Undo deletion of component
Note:
- This test file must be called from the Lumberyard 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
"""
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")
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,
)
# 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")
# 3) Select the newly created entity
general.clear_selection()
general.select_object("Entity2")
# Give the Entity Inspector time to fully create its contents
general.idle_wait(0.5)
# 4) Add/verify Box Shape Component
editor_window = pyside_utils.get_editor_main_window()
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'])}")
# 5) Add/verify Mesh component
await add_component("Mesh")
print(
f"Box Shape and Mesh Components present in the entity: {hydra.has_components(entity_id, ['Box Shape', 'Mesh'])}"
)
# 6) Delete Mesh Component
general.idle_wait(0.5)
comp_list_contents = entity_inspector.findChild(QtWidgets.QWidget, "m_componentListContents")
await pyside_utils.wait_for_condition(lambda: len(comp_list_contents.children()) > 3)
# Mesh Component is the 3rd component added to the entity including the default Transform component
# There is one QVBoxLayout child before the QFrames, making the Mesh component the 4th child in the list
mesh_frame = comp_list_contents.children()[3]
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'])}")
# 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'])}")
test = AddDeleteComponentsTest()
test.run()
@@ -0,0 +1,157 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
"""
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 automatedtesting_shared.hydra_editor_utils as hydra
from automatedtesting_shared.editor_test_helper import EditorTestHelper
import automatedtesting_shared.pyside_utils as pyside_utils
class AddRemoveInputEventsTest(EditorTestHelper):
def __init__(self):
EditorTestHelper.__init__(self, log_prefix="InputBindings_Add_Remove_Input_Events", args=["level"])
@pyside_utils.wrap_async
async def run_test(self):
"""
Summary:
Verify if we are able add/remove input events in inputbindings file.
Expected Behavior:
New Events are created with the "+" button.
Individual Events are removed with the "x" button.
All of the Events under the Input Event Groups are removed with the square button.
Test Steps:
1) Open a new level
2) Open Asset Editor
3) Access Asset Editor
4) Create a new .inputbindings file and add event groups
5) Verify if there are 3 elements in the Input Event Groups label
6) Delete one event group
7) Ensure one event group is deleted
8) Click on Delete button to delete all the Event Groups
9) Verify if all the elements are deleted
10) Close Asset Editor
Note:
- This test file must be called from the Lumberyard 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 open_asset_editor():
general.open_pane("Asset Editor")
return general.is_pane_visible("Asset Editor")
def close_asset_editor():
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,
)
# 2) Open Asset Editor
print(f"Asset Editor opened: {open_asset_editor()}")
# 3) Access Asset Editor
editor_window = pyside_utils.get_editor_main_window()
app = QtWidgets.QApplication.instance()
asset_editor = editor_window.findChild(QtWidgets.QDockWidget, "Asset Editor")
asset_editor_widget = asset_editor.findChild(QtWidgets.QWidget, "m_assetEditorWidget")
# 4) Create a new .inputbindings file and add event groups
# Get the action File->New->Input Bindings and trigger it
action = pyside_utils.find_child_by_pattern(asset_editor_widget, {"text": "Input Bindings"})
action.trigger()
# Add event groups
input_event_groups = asset_editor_widget.findChild(QtWidgets.QFrame, "Input Event Groups")
# First QToolButton is +, Second QToolButton is Delete
add_button = input_event_groups.findChildren(QtWidgets.QToolButton, "")[0]
add_button.click()
add_button.click()
add_button.click()
# 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")
# 6) Delete one event group
event = asset_editor_widget.findChildren(QtWidgets.QFrame, "<Unspecified Event>")[0]
delete_button = event.findChildren(QtWidgets.QToolButton, "")[0]
delete_button.click()
# 7) Ensure one event group is deleted
# NOTE: Here when we delete an input group a new "Input Event Groups" QFrame is generated from which
# the QLabel showing the no of elements is being rendered, so we are taking the 2nd QFrame
# with name "Input Event Groups" to verify the number of elements
def get_elements_label_text(asset_editor_widget):
input_event_groups = asset_editor_widget.findChildren(QtWidgets.QFrame, "Input Event Groups")
if len(input_event_groups) > 1:
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 "";
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")
# 8) Click on Delete button to delete all the Event Groups
# First QToolButton child of active input_event_groups is +, Second QToolButton is Delete
input_event_groups = asset_editor_widget.findChildren(QtWidgets.QFrame, "Input Event Groups")[1]
delete_all_button = input_event_groups.findChildren(QtWidgets.QToolButton, "")[1]
pyside_utils.click_button_async(delete_all_button)
# Clicking the Delete All button will prompt the user if they are sure they want to
# delete all the entries, so we wait for this modal dialog and then accept it
active_modal_widget = await pyside_utils.wait_for_modal_widget()
message_box = active_modal_widget.findChild(QtWidgets.QMessageBox)
yes_button = message_box.button(QtWidgets.QMessageBox.Yes)
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")
# 10) Close Asset Editor
print(f"Asset Editor closed: {close_asset_editor()}")
test = AddRemoveInputEventsTest()
test.run()
@@ -0,0 +1,165 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
"""
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
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
import automatedtesting_shared.hydra_editor_utils as hydra
from automatedtesting_shared.editor_test_helper import EditorTestHelper
import automatedtesting_shared.pyside_utils as pyside_utils
class TestAssetBrowserSearchFiltering(EditorTestHelper):
def __init__(self):
EditorTestHelper.__init__(self, log_prefix="SearchFiltering_Asset_Browser_Filtering", args=["level"])
@pyside_utils.wrap_async
async def run_test(self):
"""
Summary:
Asset Browser - Filtering
Expected Behavior:
The file tree is expanded and the list of assets is reduced while typing to eventually show only the filtered asset.
The search bar is cleared.
The file tree is reduced upon selecting the filter.
The file tree is increased upon selecting additional file types.
The file tree is reduced upon removing the file type filter.
The file tree is reset and all folders are displayed.
Test Steps:
1) Open level
2) Open Asset Browser
3) Type the name of an asset in the search bar and make sure only one asset is filtered in Asset browser
4) Click the "X" in the search bar.
5) Select an asset type to filter by (Animation)
6) Add additional filter(FileTag) from the filter menu
7) Remove one of the filtered asset types from the list of applied filters
8) Remove all of the filter asset types from the list of filters
Note:
- This test file must be called from the Lumberyard 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
"""
self.incorrect_file_found = False
def verify_files_appeared(model, allowed_asset_extentions, parent_index=QtCore.QModelIndex()):
indexes = [parent_index]
while len(indexes) > 0:
parent_index = indexes.pop(0)
for row in range(model.rowCount(parent_index)):
cur_index = model.index(row, 0, parent_index)
cur_data = cur_index.data(Qt.DisplayRole)
if (
"." in cur_data
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
indexes.append(cur_index)
# 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")
editor_window = pyside_utils.get_editor_main_window()
app = QtWidgets.QApplication.instance()
# 3) Type the name of an asset in the search bar and make sure only one asset is filtered in Asset browser
asset_browser = editor_window.findChild(QtWidgets.QDockWidget, "Asset Browser")
search_bar = asset_browser.findChild(QtWidgets.QLineEdit, "textSearch")
search_bar.setText("cedar.fbx")
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(
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")
# 4) Click the "X" in the search bar.
clear_search = asset_browser.findChild(QtWidgets.QToolButton, "ClearToolButton")
clear_search.click()
# 5) Select an asset type to filter by (Animation)
tool_button = asset_browser.findChild(QtWidgets.QToolButton, "assetTypeSelector")
pyside_utils.click_button_async(tool_button)
line_edit = tool_button.findChildren(QtWidgets.QLineEdit, "filteredSearchWidget")[0]
line_edit.setText("Animation")
tree = tool_button.findChildren(QtWidgets.QTreeView)[0]
animation_model_index = await pyside_utils.wait_for_child_by_pattern(tree, "Animation")
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}")
# 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(
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}")
# 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}")
# 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()
test = TestAssetBrowserSearchFiltering()
test.run()
@@ -0,0 +1,132 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
"""
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 automatedtesting_shared.editor_test_helper import EditorTestHelper
import automatedtesting_shared.pyside_utils as pyside_utils
class AssetBrowserTreeNavigationTest(EditorTestHelper):
def __init__(self):
EditorTestHelper.__init__(self, log_prefix="TreeNavigation_Asset_Browser", 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 Lumberyard 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", "lumberyard_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()
@@ -0,0 +1,10 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""