Merge branch 'development' into memory/overrideshim_removal

Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com>
This commit is contained in:
Esteban Papp
2022-01-20 13:43:12 -08:00
1545 changed files with 24982 additions and 22444 deletions
+1 -8
View File
@@ -2,18 +2,14 @@
.vs/
.vscode/
__pycache__
AssetProcessorTemp/**
[Bb]uild/
[Oo]ut/**
CMakeUserPresets.json
[Cc]ache/
/[Ii]nstall/
Editor/EditorEventLog.xml
Editor/EditorLayout.xml
**/*egg-info/**
**/*egg-link
**/[Rr]estricted
UserSettings.xml
[Uu]ser/
FrameCapture/**
.DS_Store
@@ -22,9 +18,6 @@ client*.cfg
server*.cfg
.mayaSwatches/
_savebackup/
#Output folder for test results when running Automated Tests
TestResults/**
*.swatches
/imgui.ini
/scripts/project_manager/logs/
/AutomatedTesting/Gem/PythonTests/scripting/TestResults
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
<path d="M3.145,8.433c0-1.47,1.196-2.666,2.666-2.666h9.544c-0.158-0.819-0.88-1.443-1.744-1.443H3.487
c-0.978,0-1.778,0.8-1.778,1.778v5.356c0,0.861,0.62,1.582,1.436,1.743V8.433z" fill="#FFFFFF"/>
<g>
<path d="M6.833,11.654c0-1.47,1.196-2.666,2.666-2.666h9.069c-0.158-0.819-0.88-1.443-1.744-1.443H6.7
c-0.978,0-1.778,0.8-1.778,1.778v5.356c0,0.978,0.8,1.778,1.778,1.778h0.133V11.654z" fill="#FFFFFF"/>
</g>
<path d="M20.513,10.765H10.388c-0.978,0-1.778,0.8-1.778,1.777v5.356c0,0.978,0.8,1.778,1.778,1.778h10.125
c0.978,0,1.778-0.8,1.778-1.778v-5.356C22.29,11.565,21.49,10.765,20.513,10.765z M19.332,15.967h-7.763
c-0.264,0-0.478-0.355-0.478-0.793c0-0.438,0.214-0.793,0.478-0.793h7.763c0.264,0,0.478,0.355,0.478,0.793
C19.81,15.612,19.597,15.967,19.332,15.967z" fill="#FFFFFF"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

-1
View File
@@ -27,5 +27,4 @@ else()
set_property(GLOBAL APPEND PROPERTY LY_PROJECTS_TARGET_NAME ${project_target_name})
add_subdirectory(Gem)
endif()
+5 -2
View File
@@ -6,6 +6,9 @@
#
#
set(gem_path ${CMAKE_CURRENT_LIST_DIR})
set(gem_json ${gem_path}/gem.json)
o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path)
add_subdirectory(Code)
add_subdirectory(PythonTests)
add_subdirectory(PythonCoverage)
add_subdirectory(PythonTests)
+1 -1
View File
@@ -6,7 +6,7 @@
#
#
ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME})
o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path})
ly_add_target(
NAME AutomatedTesting ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
@@ -6,4 +6,8 @@
#
#
set(gem_path ${CMAKE_CURRENT_LIST_DIR})
set(gem_json ${gem_path}/gem.json)
o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path)
add_subdirectory(Code)
@@ -6,7 +6,7 @@
#
#
ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${o3de_gem_restricted_path} ${o3de_gem_path} ${o3de_gem_name})
o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path})
include(${pal_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake)
if(PAL_TRAIT_PYTHONCOVERAGE_SUPPORTED)
+5 -1
View File
@@ -4,6 +4,7 @@
"license": "Apache-2.0 Or MIT",
"license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt",
"origin": "Open 3D Engine - o3de.org",
"origin_url": "https://github.com/o3de/o3de",
"type": "Tool",
"summary": "A tool for generating gem coverage for Python tests.",
"canonical_tags": [
@@ -13,5 +14,8 @@
"PythonCoverage"
],
"icon_path": "preview.png",
"requirements": ""
"requirements": "",
"documentation_url": "",
"dependencies": [
]
}
@@ -4,10 +4,18 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import logging
import os
import pytest
import ly_test_tools.environment.file_system as file_system
import editor_python_test_tools.hydra_test_utils as hydra
from ly_test_tools.o3de.editor_test import EditorSharedTest, EditorTestSuite
logger = logging.getLogger(__name__)
TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "tests")
@pytest.mark.parametrize("project", ["AutomatedTesting"])
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
@@ -114,3 +122,75 @@ class TestAutomation(EditorTestSuite):
class ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges(EditorSharedTest):
from Atom.tests import hydra_ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges as test_module
@pytest.mark.parametrize("project", ["AutomatedTesting"])
@pytest.mark.parametrize("launcher_platform", ['windows_generic'])
class TestMaterialEditorBasicTests(object):
@pytest.fixture(autouse=True)
def setup_teardown(self, request, workspace, project):
def delete_files():
file_system.delete(
[
os.path.join(workspace.paths.project(), "Materials", "test_material.material"),
os.path.join(workspace.paths.project(), "Materials", "test_material_1.material"),
os.path.join(workspace.paths.project(), "Materials", "test_material_2.material"),
],
True,
True,
)
# Cleanup our newly created materials
delete_files()
def teardown():
# Cleanup our newly created materials
delete_files()
request.addfinalizer(teardown)
@pytest.mark.parametrize("exe_file_name", ["MaterialEditor"])
@pytest.mark.test_case_id("C34448113") # Creating a New Asset.
@pytest.mark.test_case_id("C34448114") # Opening an Existing Asset.
@pytest.mark.test_case_id("C34448115") # Closing Selected Material.
@pytest.mark.test_case_id("C34448116") # Closing All Materials.
@pytest.mark.test_case_id("C34448117") # Closing all but Selected Material.
@pytest.mark.test_case_id("C34448118") # Saving Material.
@pytest.mark.test_case_id("C34448119") # Saving as a New Material.
@pytest.mark.test_case_id("C34448120") # Saving as a Child Material.
@pytest.mark.test_case_id("C34448121") # Saving all Open Materials.
def test_MaterialEditorBasicTests(
self, request, workspace, project, launcher_platform, generic_launcher, exe_file_name):
expected_lines = [
"Material opened: True",
"Test asset doesn't exist initially: True",
"New asset created: True",
"New Material opened: True",
"Material closed: True",
"All documents closed: True",
"Close All Except Selected worked as expected: True",
"Actual Document saved with changes: True",
"Document saved as copy is saved with changes: True",
"Document saved as child is saved with changes: True",
"Save All worked as expected: True",
"P1: Asset Browser visibility working as expected: True",
"P1: Inspector visibility working as expected: True",
]
unexpected_lines = [
# Including any lines in unexpected_lines will cause the test to run for the duration of the timeout
]
hydra.launch_and_validate_results(
request,
TEST_DIRECTORY,
generic_launcher,
"hydra_AtomMaterialEditor_BasicTests.py",
run_python="--runpython",
timeout=43,
expected_lines=expected_lines,
unexpected_lines=unexpected_lines,
halt_on_unexpected=True,
null_renderer=True,
log_file_name="MaterialEditor.log",
enable_prefab_system=False,
)
@@ -9,158 +9,20 @@ import os
import pytest
import ly_test_tools.environment.file_system as file_system
import editor_python_test_tools.hydra_test_utils as hydra
from ly_test_tools.o3de.editor_test import EditorSharedTest, EditorTestSuite
from Atom.atom_utils.atom_constants import LIGHT_TYPES
logger = logging.getLogger(__name__)
TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "tests")
@pytest.mark.parametrize("project", ["AutomatedTesting"])
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
@pytest.mark.parametrize("level", ["auto_test"])
class TestAtomEditorComponentsMain(object):
"""Holds tests for Atom components."""
@pytest.mark.test_case_id("C34525095")
def test_AtomEditorComponents_LightComponent(
self, request, editor, workspace, project, launcher_platform, level):
"""
Please review the hydra script run by this test for more specific test info.
Tests that the Light component has the expected property options available to it.
"""
cfg_args = [level]
expected_lines = [
"light_entity Entity successfully created",
"Entity has a Light component",
"light_entity_test: Component added to the entity: True",
f"light_entity_test: Property value is {LIGHT_TYPES['sphere']} which matches {LIGHT_TYPES['sphere']}",
"Controller|Configuration|Shadows|Enable shadow set to True",
"light_entity Controller|Configuration|Shadows|Shadowmap size: SUCCESS",
"Controller|Configuration|Shadows|Shadow filter method set to 1", # PCF
"Controller|Configuration|Shadows|Filtering sample count set to 4",
"Controller|Configuration|Shadows|Filtering sample count set to 64",
"Controller|Configuration|Shadows|Shadow filter method set to 2", # ESM
"Controller|Configuration|Shadows|ESM exponent set to 50.0",
"Controller|Configuration|Shadows|ESM exponent set to 5000.0",
"Controller|Configuration|Shadows|Shadow filter method set to 3", # ESM+PCF
f"light_entity_test: Property value is {LIGHT_TYPES['spot_disk']} which matches {LIGHT_TYPES['spot_disk']}",
f"light_entity_test: Property value is {LIGHT_TYPES['capsule']} which matches {LIGHT_TYPES['capsule']}",
f"light_entity_test: Property value is {LIGHT_TYPES['quad']} which matches {LIGHT_TYPES['quad']}",
"light_entity Controller|Configuration|Fast approximation: SUCCESS",
"light_entity Controller|Configuration|Both directions: SUCCESS",
f"light_entity_test: Property value is {LIGHT_TYPES['polygon']} which matches {LIGHT_TYPES['polygon']}",
f"light_entity_test: Property value is {LIGHT_TYPES['simple_point']} "
f"which matches {LIGHT_TYPES['simple_point']}",
"Controller|Configuration|Attenuation radius|Mode set to 0",
"Controller|Configuration|Attenuation radius|Radius set to 100.0",
f"light_entity_test: Property value is {LIGHT_TYPES['simple_spot']} "
f"which matches {LIGHT_TYPES['simple_spot']}",
"Controller|Configuration|Shutters|Outer angle set to 45.0",
"Controller|Configuration|Shutters|Outer angle set to 90.0",
"light_entity_test: Component added to the entity: True",
"Light component test (non-GPU) completed.",
]
unexpected_lines = ["Traceback (most recent call last):"]
hydra.launch_and_validate_results(
request,
TEST_DIRECTORY,
editor,
"hydra_AtomEditorComponents_LightComponent.py",
timeout=120,
expected_lines=expected_lines,
unexpected_lines=unexpected_lines,
halt_on_unexpected=True,
null_renderer=True,
cfg_args=cfg_args,
enable_prefab_system=False,
)
@pytest.mark.parametrize("project", ["AutomatedTesting"])
@pytest.mark.parametrize("launcher_platform", ['windows_generic'])
@pytest.mark.system
class TestMaterialEditorBasicTests(object):
@pytest.fixture(autouse=True)
def setup_teardown(self, request, workspace, project):
def delete_files():
file_system.delete(
[
os.path.join(workspace.paths.project(), "Materials", "test_material.material"),
os.path.join(workspace.paths.project(), "Materials", "test_material_1.material"),
os.path.join(workspace.paths.project(), "Materials", "test_material_2.material"),
],
True,
True,
)
# Cleanup our newly created materials
delete_files()
def teardown():
# Cleanup our newly created materials
delete_files()
request.addfinalizer(teardown)
@pytest.mark.parametrize("exe_file_name", ["MaterialEditor"])
@pytest.mark.test_case_id("C34448113") # Creating a New Asset.
@pytest.mark.test_case_id("C34448114") # Opening an Existing Asset.
@pytest.mark.test_case_id("C34448115") # Closing Selected Material.
@pytest.mark.test_case_id("C34448116") # Closing All Materials.
@pytest.mark.test_case_id("C34448117") # Closing all but Selected Material.
@pytest.mark.test_case_id("C34448118") # Saving Material.
@pytest.mark.test_case_id("C34448119") # Saving as a New Material.
@pytest.mark.test_case_id("C34448120") # Saving as a Child Material.
@pytest.mark.test_case_id("C34448121") # Saving all Open Materials.
def test_MaterialEditorBasicTests(
self, request, workspace, project, launcher_platform, generic_launcher, exe_file_name):
expected_lines = [
"Material opened: True",
"Test asset doesn't exist initially: True",
"New asset created: True",
"New Material opened: True",
"Material closed: True",
"All documents closed: True",
"Close All Except Selected worked as expected: True",
"Actual Document saved with changes: True",
"Document saved as copy is saved with changes: True",
"Document saved as child is saved with changes: True",
"Save All worked as expected: True",
]
unexpected_lines = [
"Traceback (most recent call last):"
]
hydra.launch_and_validate_results(
request,
TEST_DIRECTORY,
generic_launcher,
"hydra_AtomMaterialEditor_BasicTests.py",
run_python="--runpython",
timeout=120,
expected_lines=expected_lines,
unexpected_lines=unexpected_lines,
halt_on_unexpected=True,
null_renderer=True,
log_file_name="MaterialEditor.log",
enable_prefab_system=False,
)
@pytest.mark.parametrize("project", ["AutomatedTesting"])
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
class TestAutomation(EditorTestSuite):
enable_prefab_system = False
#this test is intermittently timing out without ever having executed. sandboxing while we investigate cause.
# this test is intermittently timing out without ever having executed. sandboxing while we investigate cause.
@pytest.mark.test_case_id("C36525660")
class AtomEditorComponents_DisplayMapperAdded(EditorSharedTest):
from Atom.tests import hydra_AtomEditorComponents_DisplayMapperAdded as test_module
@@ -125,11 +125,11 @@ def is_pane_visible(pane_name):
"""
:return: bool
"""
return atomtools.AtomToolsWindowRequestBus(bus.Broadcast, "IsDockWidgetVisible", pane_name)
return atomtools.AtomToolsMainWindowRequestBus(bus.Broadcast, "IsDockWidgetVisible", pane_name)
def set_pane_visibility(pane_name, value):
atomtools.AtomToolsWindowRequestBus(bus.Broadcast, "SetDockWidgetVisible", pane_name, value)
atomtools.AtomToolsMainWindowRequestBus(bus.Broadcast, "SetDockWidgetVisible", pane_name, value)
def select_lighting_config(config_name):
@@ -162,6 +162,13 @@ def select_model_config(configname):
azlmbr.materialeditor.MaterialViewportRequestBus(azlmbr.bus.Broadcast, "SelectModelPresetByName", configname)
def destroy_main_window():
"""
Closes the Material Editor window
"""
azlmbr.atomtools.AtomToolsMainWindowFactoryRequestBus(azlmbr.bus.Broadcast, "DestroyMainWindow")
def wait_for_condition(function, timeout_in_seconds=1.0):
# type: (function, float) -> bool
"""
@@ -1,213 +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 sys
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.math as math
import azlmbr.paths
import azlmbr.legacy.general as general
sys.path.append(os.path.join(azlmbr.paths.projectroot, "Gem", "PythonTests"))
import editor_python_test_tools.hydra_editor_utils as hydra
from Atom.atom_utils.atom_constants import LIGHT_TYPES
LIGHT_TYPE_PROPERTY = 'Controller|Configuration|Light type'
SPHERE_AND_SPOT_DISK_LIGHT_PROPERTIES = [
("Controller|Configuration|Shadows|Enable shadow", True),
("Controller|Configuration|Shadows|Shadowmap size", 0), # 256
("Controller|Configuration|Shadows|Shadowmap size", 1), # 512
("Controller|Configuration|Shadows|Shadowmap size", 2), # 1024
("Controller|Configuration|Shadows|Shadowmap size", 3), # 2048
("Controller|Configuration|Shadows|Shadow filter method", 1), # PCF
("Controller|Configuration|Shadows|Filtering sample count", 4.0),
("Controller|Configuration|Shadows|Filtering sample count", 64.0),
("Controller|Configuration|Shadows|Shadow filter method", 2), # ECM
("Controller|Configuration|Shadows|ESM exponent", 50),
("Controller|Configuration|Shadows|ESM exponent", 5000),
("Controller|Configuration|Shadows|Shadow filter method", 3), # ESM+PCF
]
QUAD_LIGHT_PROPERTIES = [
("Controller|Configuration|Both directions", True),
("Controller|Configuration|Fast approximation", True),
]
SIMPLE_POINT_LIGHT_PROPERTIES = [
("Controller|Configuration|Attenuation radius|Mode", 0),
("Controller|Configuration|Attenuation radius|Radius", 100.0),
]
SIMPLE_SPOT_LIGHT_PROPERTIES = [
("Controller|Configuration|Shutters|Inner angle", 45.0),
("Controller|Configuration|Shutters|Outer angle", 90.0),
]
def verify_required_component_property_value(entity_name, component, property_path, expected_property_value):
"""
Compares the property value of component against the expected_property_value.
:param entity_name: name of the entity to use (for test verification purposes).
:param component: component to check on a given entity for its current property value.
:param property_path: the path to the property inside the component.
:param expected_property_value: The value expected from the value inside property_path.
:return: None, but prints to general.log() which the test uses to verify against.
"""
property_value = editor.EditorComponentAPIBus(
bus.Broadcast, "GetComponentProperty", component, property_path).GetValue()
general.log(f"{entity_name}_test: Property value is {property_value} "
f"which matches {expected_property_value}")
def run():
"""
Test Case - Light Component
1. Creates a "light_entity" Entity and attaches a "Light" component to it.
2. Updates the Light component to each light type option from the LIGHT_TYPES constant.
3. The test will check the Editor log to ensure each light type was selected.
4. Prints the string "Light component test (non-GPU) completed" after completion.
Tests will fail immediately if any of these log lines are found:
1. Trace::Assert
2. Trace::Error
3. Traceback (most recent call last):
:return: None
"""
# Create a "light_entity" entity with "Light" component.
light_entity_name = "light_entity"
light_component = "Light"
light_entity = hydra.Entity(light_entity_name)
light_entity.create_entity(math.Vector3(-1.0, -2.0, 3.0), [light_component])
general.log(
f"{light_entity_name}_test: Component added to the entity: "
f"{hydra.has_components(light_entity.id, [light_component])}")
# Populate the light_component_id_pair value so that it can be used to select all Light component options.
light_component_id_pair = None
component_type_id_list = azlmbr.editor.EditorComponentAPIBus(
azlmbr.bus.Broadcast, 'FindComponentTypeIdsByEntityType', [light_component], 0)
if len(component_type_id_list) < 1:
general.log(f"ERROR: A component class with name {light_component} doesn't exist")
light_component_id_pair = None
elif len(component_type_id_list) > 1:
general.log(f"ERROR: Found more than one component classes with same name: {light_component}")
light_component_id_pair = None
entity_component_id_pair = azlmbr.editor.EditorComponentAPIBus(
azlmbr.bus.Broadcast, 'GetComponentOfType', light_entity.id, component_type_id_list[0])
if entity_component_id_pair.IsSuccess():
light_component_id_pair = entity_component_id_pair.GetValue()
# Test each Light component option can be selected and it's properties updated.
# Point (sphere) light type checks.
light_type_property_test(
light_type=LIGHT_TYPES['sphere'],
light_properties=SPHERE_AND_SPOT_DISK_LIGHT_PROPERTIES,
light_component_id_pair=light_component_id_pair,
light_entity_name=light_entity_name,
light_entity=light_entity
)
# Spot (disk) light type checks.
light_type_property_test(
light_type=LIGHT_TYPES['spot_disk'],
light_properties=SPHERE_AND_SPOT_DISK_LIGHT_PROPERTIES,
light_component_id_pair=light_component_id_pair,
light_entity_name=light_entity_name,
light_entity=light_entity
)
# Capsule light type checks.
azlmbr.editor.EditorComponentAPIBus(
azlmbr.bus.Broadcast,
'SetComponentProperty',
light_component_id_pair,
LIGHT_TYPE_PROPERTY,
LIGHT_TYPES['capsule']
)
verify_required_component_property_value(
entity_name=light_entity_name,
component=light_entity.components[0],
property_path=LIGHT_TYPE_PROPERTY,
expected_property_value=LIGHT_TYPES['capsule']
)
# Quad light type checks.
light_type_property_test(
light_type=LIGHT_TYPES['quad'],
light_properties=QUAD_LIGHT_PROPERTIES,
light_component_id_pair=light_component_id_pair,
light_entity_name=light_entity_name,
light_entity=light_entity
)
# Polygon light type checks.
azlmbr.editor.EditorComponentAPIBus(
azlmbr.bus.Broadcast,
'SetComponentProperty',
light_component_id_pair,
LIGHT_TYPE_PROPERTY,
LIGHT_TYPES['polygon']
)
verify_required_component_property_value(
entity_name=light_entity_name,
component=light_entity.components[0],
property_path=LIGHT_TYPE_PROPERTY,
expected_property_value=LIGHT_TYPES['polygon']
)
# Point (simple punctual) light type checks.
light_type_property_test(
light_type=LIGHT_TYPES['simple_point'],
light_properties=SIMPLE_POINT_LIGHT_PROPERTIES,
light_component_id_pair=light_component_id_pair,
light_entity_name=light_entity_name,
light_entity=light_entity
)
# Spot (simple punctual) light type checks.
light_type_property_test(
light_type=LIGHT_TYPES['simple_spot'],
light_properties=SIMPLE_SPOT_LIGHT_PROPERTIES,
light_component_id_pair=light_component_id_pair,
light_entity_name=light_entity_name,
light_entity=light_entity
)
general.log("Light component test (non-GPU) completed.")
def light_type_property_test(light_type, light_properties, light_component_id_pair, light_entity_name, light_entity):
"""
Updates the current light type and modifies its properties, then verifies they are accurate to what was set.
:param light_type: The type of light to update, must match a value in LIGHT_TYPES
:param light_properties: List of tuples detailing properties to modify with update values.
:param light_component_id_pair: Entity + component ID pair for updating the light component on a given entity.
:param light_entity_name: the name of the Entity holding the light component.
:param light_entity: the Entity object containing the light component.
:return: None
"""
azlmbr.editor.EditorComponentAPIBus(
azlmbr.bus.Broadcast,
'SetComponentProperty',
light_component_id_pair,
LIGHT_TYPE_PROPERTY,
light_type
)
verify_required_component_property_value(
entity_name=light_entity_name,
component=light_entity.components[0],
property_path=LIGHT_TYPE_PROPERTY,
expected_property_value=light_type
)
for light_property in light_properties:
light_entity.get_set_test(0, light_property[0], light_property[1])
if __name__ == "__main__":
run()
@@ -36,6 +36,19 @@ MATERIAL_TYPE_PATH = os.path.join(
CACHE_FILE_EXTENSION = ".azmaterial"
def verify_pane_visibility(pane_name: str):
"""
print log lines indicating Material Editor pane visibility function
:param pane_name: Name of the pane to be tested
"""
initial_value = material_editor.is_pane_visible(pane_name)
material_editor.set_pane_visibility(pane_name, not initial_value)
result = (material_editor.is_pane_visible(pane_name) is not initial_value)
material_editor.set_pane_visibility(pane_name, initial_value)
result = result and (initial_value is material_editor.is_pane_visible(pane_name))
print(f"P1: {pane_name} visibility working as expected: {result}")
def run():
"""
Summary:
@@ -49,9 +62,12 @@ def run():
7. Saving as a New Material
8. Saving as a Child Material
9. Saving all Open Materials
10. Verify Asset Browser pane visibility
11. Verify Material Inspector pane visibility
Expected Result:
All the above functions work as expected in Material Editor.
Pane visibility functions as expected
:return: None
"""
@@ -187,6 +203,19 @@ def run():
material_editor.save_all()
material_editor.close_all_documents()
# 10) Verify Asset Browser pane visibility
verify_pane_visibility("Asset Browser")
# 11) Verify Material Inspector pane visibility
verify_pane_visibility("Inspector")
# Confirm documents closed and exit Material Editor
material_editor.wait_for_condition(lambda:
(not material_editor.is_open(document1_id)) and
(not material_editor.is_open(document2_id)) and
(not material_editor.is_open(document3_id)), 2.0)
material_editor.destroy_main_window()
if __name__ == "__main__":
run()
@@ -6,7 +6,7 @@
#
#
ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME})
o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path})
include(${pal_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) # for PAL_TRAIT_BLAST Traits
@@ -10,7 +10,7 @@
# Automated Tests
################################################################################
ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME})
o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path})
include(${pal_dir}/PAL_traits_${PAL_PLATFORM_NAME_LOWERCASE}.cmake)
@@ -8,7 +8,8 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
# Built-in Imports
from __future__ import annotations
from typing import List, Tuple, Union
from enum import Enum
import warnings
# Open 3D Engine Imports
import azlmbr
@@ -21,14 +22,25 @@ import azlmbr.legacy.general as general
from editor_python_test_tools.utils import Report
class EditorEntityType(Enum):
GAME = azlmbr.entity.EntityType().Game
LEVEL = azlmbr.entity.EntityType().Level
class EditorComponent:
"""
EditorComponent class used to set and get the component property value using path
EditorComponent object is returned from either of
EditorEntity.add_component() or Entity.add_components() or EditorEntity.get_components_of_type()
which also assigns self.id and self.type_id to the EditorComponent object.
self.type_id is the UUID for the component type as provided by an ebus call.
"""
def __init__(self, type_id: uuid):
self.type_id = type_id
self.id = None
self.property_tree_editor = None
def get_component_name(self) -> str:
"""
Used to get name of component
@@ -38,9 +50,9 @@ class EditorComponent:
assert len(type_names) != 0, "Component object does not have type id"
return type_names[0]
def get_property_tree(self):
def get_property_tree(self, force_get: bool = False):
"""
Used to get the property tree object of component that has following functions associated with it:
Used to get and cache the property tree editor of component that has following functions associated with it:
1. prop_tree.is_container(path)
2. prop_tree.get_container_count(path)
3. prop_tree.reset_container(path)
@@ -48,17 +60,161 @@ class EditorComponent:
5. prop_tree.remove_container_item(path, key)
6. prop_tree.update_container_item(path, key, value)
7. prop_tree.get_container_item(path, key)
:return: Property tree object of a component
:param force_get: Force a fresh property tree editor rather than the cached self.property_tree_editor
:return: Property tree editor of the component
"""
if (not force_get) and (self.property_tree_editor is not None):
return self.property_tree_editor
build_prop_tree_outcome = editor.EditorComponentAPIBus(
bus.Broadcast, "BuildComponentPropertyTreeEditor", self.id
)
assert (
build_prop_tree_outcome.IsSuccess()
), f"Failure: Could not build property tree of component: '{self.get_component_name()}'"
), f"Failure: Could not build property tree editor of component: '{self.get_component_name()}'"
prop_tree = build_prop_tree_outcome.GetValue()
Report.info(prop_tree.build_paths_list())
return prop_tree
self.property_tree_editor = prop_tree
return self.property_tree_editor
def is_property_container(self, component_property_path: str) -> bool:
"""
Used to determine if a component property is a container.
Containers are a collection of same typed values that can expand/shrink to contain more or less.
There are two types of containers; indexed and associative.
Indexed containers use integer key and are something like a linked list
Associative containers utilize keys of the same type which could be any supported type.
:param component_property_path: String of component property. (e.g. 'Settings|Visible')
:return: Boolean True if the property is a container False if it is not.
"""
if self.property_tree_editor is None:
self.get_property_tree()
result = self.property_tree_editor.is_container(component_property_path)
if not result:
Report.info(f"{self.get_component_name()}: '{component_property_path}' is not a container")
return result
def get_container_count(self, component_property_path: str) -> int:
"""
Used to get the count of items in the container.
:param component_property_path: String of component property. (e.g. 'Settings|Visible')
:return: Count of items in the container as unsigned integer
"""
assert (
self.is_property_container(component_property_path)
), f"Failure: '{component_property_path}' is not a property container"
container_count_outcome = self.property_tree_editor.get_container_count(component_property_path)
assert (
container_count_outcome.IsSuccess()
), f"Failure: get_container_count did not return success for '{component_property_path}'"
return container_count_outcome.GetValue()
def reset_container(self, component_property_path: str):
"""
Used to reset a container to empty
:param component_property_path: String of component property. (e.g. 'Settings|Visible')
:return: None
"""
assert (
self.is_property_container(component_property_path)
), f"Failure: '{component_property_path}' is not a property container"
reset_outcome = self.property_tree_editor.reset_container(component_property_path)
assert (
reset_outcome.IsSuccess()
), f"Failure: could not reset_container on '{component_property_path}'"
def append_container_item(self, component_property_path: str, value: any):
"""
Used to append a value to an indexed container item without providing an index key.
Append will fail on an associative container
:param component_property_path: String of component property. (e.g. 'Settings|Visible')
:param value: Value to be set
:return: None
"""
assert (
self.is_property_container(component_property_path)
), f"Failure: '{component_property_path}' is not a property container"
append_outcome = self.property_tree_editor.append_container_item(component_property_path, value)
assert (
append_outcome.IsSuccess()
), f"Failure: could not append_container_item to '{component_property_path}'"
def add_container_item(self, component_property_path: str, key: any, value: any):
"""
Used to add a container item at a specified key.
There are two types of containers; indexed and associative.
Indexed containers use integer key.
Associative containers utilize keys of the same type which could be any supported type.
:param component_property_path: String of component property. (e.g. 'Settings|Visible')
:param key: Zero index integer key or any supported type for associative container
:param value: Value to be set
:return: None
"""
assert (
self.is_property_container(component_property_path)
), f"Failure: '{component_property_path}' is not a property container"
add_outcome = self.property_tree_editor.add_container_item(component_property_path, key, value)
assert (
add_outcome.IsSuccess()
), f"Failure: could not add_container_item '{key}' to '{component_property_path}'"
def get_container_item(self, component_property_path: str, key: any) -> any:
"""
Used to retrieve a container item value at the specified key.
There are two types of containers; indexed and associative.
Indexed containers use integer key.
Associative containers utilize keys of the same type which could be any supported type.
:param component_property_path: String of component property. (e.g. 'Settings|Visible')
:param key: Zero index integer key or any supported type for associative container
:return: Value stored at the key specified
"""
assert (
self.is_property_container(component_property_path)
), f"Failure: '{component_property_path}' is not a property container"
get_outcome = self.property_tree_editor.get_container_item(component_property_path, key)
assert (
get_outcome.IsSuccess()
), (
f"Failure: could not get a value for {self.get_component_name()}: '{component_property_path}' [{key}]. "
f"Error returned by get_container_item: {get_outcome.GetError()}")
return get_outcome.GetValue()
def remove_container_item(self, component_property_path: str, key: any):
"""
Used to remove a container item value at the specified key.
There are two types of containers; indexed and associative.
Indexed containers use integer key.
Associative containers utilize keys of the same type which could be any supported type.
:param component_property_path: String of component property. (e.g. 'Settings|Visible')
:param key: Zero index integer key or any supported type for associative container
:return: None
"""
assert (
self.is_property_container(component_property_path)
), f"Failure: '{component_property_path}' is not a property container"
remove_outcome = self.property_tree_editor.remove_container_item(component_property_path, key)
assert (
remove_outcome.IsSuccess()
), f"Failure: could not remove_container_item '{key}' from '{component_property_path}'"
def update_container_item(self, component_property_path: str, key: any, value: any):
"""
Used to update a container item at a specified key.
There are two types of containers; indexed and associative.
Indexed containers use integer key.
Associative containers utilize keys of the same type which could be any supported type.
:param component_property_path: String of component property. (e.g. 'Settings|Visible')
:param key: Zero index integer key or any supported type for associative container
:param value: Value to be set
:return: None
"""
assert (
self.is_property_container(component_property_path)
), f"Failure: '{component_property_path}' is not a property container"
update_outcome = self.property_tree_editor.update_container_item(component_property_path, key, value)
assert (
update_outcome.IsSuccess()
), f"Failure: could not update '{key}' in '{component_property_path}'"
def get_component_property_value(self, component_property_path: str):
"""
@@ -94,23 +250,36 @@ class EditorComponent:
"""
return editor.EditorComponentAPIBus(bus.Broadcast, "IsComponentEnabled", self.id)
def set_enabled(self, new_state: bool):
"""
Used to set the component enabled state
:param new_state: Boolean enabled True, disabled False
:return: None
"""
if new_state:
editor.EditorComponentAPIBus(bus.Broadcast, "EnableComponents", [self.id])
else:
editor.EditorComponentAPIBus(bus.Broadcast, "DisableComponents", [self.id])
def disable_component(self):
"""
Used to disable the component using its id value.
Deprecation warning! Use set_enabled(False) instead as this method is in deprecation
:return: None
"""
warnings.warn("disable_component is deprecated, use set_enabled(False) instead.", DeprecationWarning)
editor.EditorComponentAPIBus(bus.Broadcast, "DisableComponents", [self.id])
@staticmethod
def get_type_ids(component_names: list) -> list:
def get_type_ids(component_names: list, entity_type: EditorEntityType = EditorEntityType.GAME) -> list:
"""
Used to get type ids of given components list
:param: component_names: List of components to get type ids
:return: List of type ids of given components.
:param component_names: List of components to get type ids
:param entity_type: Entity_Type enum value Entity_Type.GAME is the default
:return: List of type ids of given components. Type id is a UUID as provided by the ebus call
"""
type_ids = editor.EditorComponentAPIBus(
bus.Broadcast, "FindComponentTypeIdsByEntityType", component_names, azlmbr.entity.EntityType().Game
)
bus.Broadcast, "FindComponentTypeIdsByEntityType", component_names, entity_type.value)
return type_ids
@@ -131,7 +300,7 @@ class EditorEntity:
"""
Entity class is used to create and interact with Editor Entities.
Example: To create Editor Entity, Use the code:
test_entity = Entity.create_editor_entity("TestEntity")
test_entity = EditorEntity.create_editor_entity("TestEntity")
# This creates a python object with 'test_entity' linked to entity name "TestEntity" in Editor.
# To add component, use:
test_entity.add_component(<COMPONENT_NAME>)
@@ -276,10 +445,9 @@ class EditorEntity:
:return: List of newly added components to the entity
"""
components = []
type_ids = EditorComponent.get_type_ids(component_names)
type_ids = EditorComponent.get_type_ids(component_names, EditorEntityType.GAME)
for type_id in type_ids:
new_comp = EditorComponent()
new_comp.type_id = type_id
new_comp = EditorComponent(type_id)
add_component_outcome = editor.EditorComponentAPIBus(
bus.Broadcast, "AddComponentsOfType", self.id, [type_id]
)
@@ -291,6 +459,27 @@ class EditorEntity:
self.components.append(new_comp)
return components
def remove_component(self, component_name: str) -> None:
"""
Used to remove a component from Entity
:param component_name: String of component name to remove
:return: None
"""
self.remove_components([component_name])
def remove_components(self, component_names: list):
"""
Used to remove a list of components from Entity
:param component_names: List of component names to remove
:return: None
"""
type_ids = EditorComponent.get_type_ids(component_names, EditorEntityType.GAME)
for type_id in type_ids:
remove_outcome = editor.EditorComponentAPIBus(bus.Broadcast, "RemoveComponents", self.id, [type_id])
assert (
remove_outcome.IsSuccess()
), f"Failure: could not remove component from '{self.get_name()}'"
def get_components_of_type(self, component_names: list) -> List[EditorComponent]:
"""
Used to get components of type component_name that already exists on Entity
@@ -298,10 +487,9 @@ class EditorEntity:
:return: List of Entity Component objects of given component name
"""
component_list = []
type_ids = EditorComponent.get_type_ids(component_names)
type_ids = EditorComponent.get_type_ids(component_names, EditorEntityType.GAME)
for type_id in type_ids:
component = EditorComponent()
component.type_id = type_id
component = EditorComponent(type_id)
get_component_of_type_outcome = editor.EditorComponentAPIBus(
bus.Broadcast, "GetComponentOfType", self.id, type_id
)
@@ -319,7 +507,7 @@ class EditorEntity:
:param component_name: Name of component to check for
:return: True, if entity has specified component. Else, False
"""
type_ids = EditorComponent.get_type_ids([component_name])
type_ids = EditorComponent.get_type_ids([component_name], EditorEntityType.GAME)
return editor.EditorComponentAPIBus(bus.Broadcast, "HasComponentOfType", self.id, type_ids[0])
def get_start_status(self) -> int:
@@ -359,6 +547,21 @@ class EditorEntity:
set_status = self.get_start_status()
assert set_status == status_to_set, f"Failed to set start status of {desired_start_status} to {self.get_name}"
def is_locked(self) -> bool:
"""
Used to get the locked status of the entity
:return: Boolean True if locked False if not locked
"""
return editor.EditorEntityInfoRequestBus(bus.Event, "IsLocked", self.id)
def set_lock_state(self, is_locked: bool) -> None:
"""
Sets the lock state on the object to locked or not locked.
:param is_locked: True for locking, False to unlock.
:return: None
"""
editor.EditorEntityAPIBus(bus.Event, "SetLockState", self.id, is_locked)
def delete(self) -> None:
"""
Used to delete the Entity.
@@ -488,18 +691,6 @@ class EditorLevelEntity:
EditorLevelComponentAPIBus requests.
"""
@staticmethod
def get_type_ids(component_names: list) -> list:
"""
Used to get type ids of given components list for EntityType Level
:param: component_names: List of components to get type ids
:return: List of type ids of given components.
"""
type_ids = editor.EditorComponentAPIBus(
bus.Broadcast, "FindComponentTypeIdsByEntityType", component_names, azlmbr.entity.EntityType().Level
)
return type_ids
@staticmethod
def add_component(component_name: str) -> EditorComponent:
"""
@@ -518,10 +709,9 @@ class EditorLevelEntity:
:return: List of newly added components to the level
"""
components = []
type_ids = EditorLevelEntity.get_type_ids(component_names)
type_ids = EditorComponent.get_type_ids(component_names, EditorEntityType.LEVEL)
for type_id in type_ids:
new_comp = EditorComponent()
new_comp.type_id = type_id
new_comp = EditorComponent(type_id)
add_component_outcome = editor.EditorLevelComponentAPIBus(
bus.Broadcast, "AddComponentsOfType", [type_id]
)
@@ -540,10 +730,9 @@ class EditorLevelEntity:
:return: List of Level Component objects of given component name
"""
component_list = []
type_ids = EditorLevelEntity.get_type_ids(component_names)
type_ids = EditorComponent.get_type_ids(component_names, EditorEntityType.LEVEL)
for type_id in type_ids:
component = EditorComponent()
component.type_id = type_id
component = EditorComponent(type_id)
get_component_of_type_outcome = editor.EditorLevelComponentAPIBus(
bus.Broadcast, "GetComponentOfType", type_id
)
@@ -562,7 +751,7 @@ class EditorLevelEntity:
:param component_name: Name of component to check for
:return: True, if level has specified component. Else, False
"""
type_ids = EditorLevelEntity.get_type_ids([component_name])
type_ids = EditorComponent.get_type_ids([component_name], EditorEntityType.LEVEL)
return editor.EditorLevelComponentAPIBus(bus.Broadcast, "HasComponentOfType", type_ids[0])
@staticmethod
@@ -572,5 +761,5 @@ class EditorLevelEntity:
:param component_name: Name of component to check for
:return: integer count of occurences of level component attached to level or zero if none are present
"""
type_ids = EditorLevelEntity.get_type_ids([component_name])
type_ids = EditorComponent.get_type_ids([component_name], EditorEntityType.LEVEL)
return editor.EditorLevelComponentAPIBus(bus.Broadcast, "CountComponentsOfType", type_ids[0])
@@ -5,15 +5,22 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
from typing import List
from math import isclose
import collections.abc
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.entity as entity
import azlmbr.legacy.general as general
import azlmbr.object
from typing import List
from math import isclose
import collections.abc
from editor_python_test_tools.utils import TestHelper as helper
def open_base_level():
helper.init_idle()
helper.open_level("Prefab", "Base")
def find_entity_by_name(entity_name):
@@ -127,7 +127,7 @@ def Collider_SameCollisionGroupSameCustomLayerCollide():
# Main Script
# 1) Load the level
helper.init_idle()
helper.open_level("physics", "Collider_SameCollisionGroupSameCustomLayerCollide")
helper.open_level("Physics", "Collider_SameCollisionGroupSameCustomLayerCollide")
# 2) Enter Game Mode
helper.enter_game_mode(Tests.enter_game_mode)
@@ -162,7 +162,7 @@ def ForceRegion_MultipleForcesInSameComponentCombineForces():
helper.init_idle()
# 1) Load Level
helper.open_level("physics", "ForceRegion_MultipleForcesInSameComponentCombineForces")
helper.open_level("Physics", "ForceRegion_MultipleForcesInSameComponentCombineForces")
# 2) Enter Game Mode
helper.enter_game_mode(Tests.enter_game_mode)
@@ -229,8 +229,8 @@ def Material_DefaultLibraryUpdatedAcrossLevels_after():
for test in test_list:
# 1) Open the correct level is open
helper.open_level(
"physics",
f"Material_DefaultLibraryUpdatedAcrossLevels\\{test.level}"
"Physics",
os.path.join("Material_DefaultLibraryUpdatedAcrossLevels", str(test.level))
)
# 2) Enter Game Mode
@@ -189,7 +189,7 @@ def Material_DefaultLibraryUpdatedAcrossLevels_before():
# 1) Open the correct level is open
helper.open_level(
"Physics",
f"Material_DefaultLibraryUpdatedAcrossLevels\\{test.level}"
os.path.join("Material_DefaultLibraryUpdatedAcrossLevels", str(test.level))
)
# 2) Enter Game Mode
@@ -252,10 +252,8 @@ def Material_LibraryUpdatedAcrossLevels():
for test in test_list:
# 1) Open the correct level for the test
helper.open_level(
"physics",
"Material_LibraryUpdatedAcrossLevels\\Material_LibraryUpdatedAcrossLevels_{}".format(
test.level_index
),
"Physics",
os.path.join("Material_LibraryUpdatedAcrossLevels", str(test.level_index))
)
# 2) Open Game Mode
@@ -106,7 +106,7 @@ def ScriptCanvas_SpawnEntityWithPhysComponents():
# Main Script
helper.init_idle()
# 1) Open Level
helper.open_level("physics", "ScriptCanvas_SpawnEntityWithPhysComponents")
helper.open_level("Physics", "ScriptCanvas_SpawnEntityWithPhysComponents")
# 2) Enter Game Mode
helper.enter_game_mode(Tests.enter_game_mode)
@@ -12,12 +12,36 @@ import sys
import os
import pytest
import logging
import sqlite3
pytest.importorskip('ly_test_tools')
import ly_test_tools.environment.file_system as file_system
import ly_test_tools.log.log_monitor
import ly_test_tools.environment.waiter as waiter
def detect_product(sql_connection, platform, target):
cur = sql_connection.cursor()
product_target = f'{platform}/{target}'
print(f'Detecting {product_target} in assetdb.sqlite')
hits = 0
for row in cur.execute(f'select ProductID from Products where ProductName is "{product_target}"'):
hits = hits + 1
assert hits == 1
def find_products(cache_folder, platform):
con = sqlite3.connect(os.path.join(cache_folder, 'assetdb.sqlite'))
detect_product(con, platform, 'gem/pythontests/pythonassetbuilder/test_asset.mock_asset')
detect_product(con, platform, 'gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_positive_1.azmodel')
detect_product(con, platform, 'gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_negative_1.azmodel')
detect_product(con, platform, 'gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_positive_1.azmodel')
detect_product(con, platform, 'gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_negative_1.azmodel')
detect_product(con, platform, 'gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_positive_1.azmodel')
detect_product(con, platform, 'gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_negative_1.azmodel')
detect_product(con, platform, 'gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center_1.azmodel')
con.close()
@pytest.mark.SUITE_periodic
@pytest.mark.parametrize('launcher_platform', ['windows_editor'])
@pytest.mark.parametrize('project', ['AutomatedTesting'])
@@ -25,16 +49,7 @@ import ly_test_tools.environment.waiter as waiter
class TestPythonAssetProcessing(object):
def test_DetectPythonCreatedAsset(self, request, editor, level, launcher_platform):
unexpected_lines = []
expected_lines = [
'Mock asset exists',
'AssetId found for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_positive_1.azmodel) found',
'AssetId found for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_negative_1.azmodel) found',
'AssetId found for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_positive_1.azmodel) found',
'AssetId found for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_negative_1.azmodel) found',
'AssetId found for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_positive_1.azmodel) found',
'AssetId found for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_negative_1.azmodel) found',
'AssetId found for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center_1.azmodel) found'
]
expected_lines = []
timeout = 180
halt_on_unexpected = False
test_directory = os.path.join(os.path.dirname(__file__))
@@ -50,3 +65,9 @@ class TestPythonAssetProcessing(object):
exc=("Log file '{}' was never opened by another process.".format(editorlog_file)),
interval=1)
log_monitor.monitor_log_for_lines(expected_lines, unexpected_lines, halt_on_unexpected, timeout)
cache_folder = editor.workspace.paths.cache()
platform = editor.workspace.asset_processor_platform
if platform == 'windows':
platform = 'pc'
find_products(cache_folder, platform)
@@ -6,7 +6,7 @@
#
#
ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME})
o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path})
include(${pal_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) # for PAL_TRAIT_WHITEBOX Traits
@@ -93,15 +93,19 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
)
ly_add_pytest(
NAME AssetPipelineTests.AssetBundler
PATH ${CMAKE_CURRENT_LIST_DIR}/asset_bundler_batch_tests.py
NAME AssetPipelineTests.AssetBuilder
PATH ${CMAKE_CURRENT_LIST_DIR}/asset_builder_tests.py
EXCLUDE_TEST_RUN_TARGET_FROM_IDE
TEST_SERIAL
TEST_SUITE periodic
RUNTIME_DEPENDENCIES
AZ::AssetProcessor
AZ::AssetBundlerBatch
)
set(SUPPORTED_PLATFORMS "Windows" "Mac")
if (NOT "${PAL_PLATFORM_NAME}" IN_LIST SUPPORTED_PLATFORMS)
return()
endif()
ly_add_pytest(
NAME AssetPipelineTests.BundleMode
@@ -117,16 +121,16 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
)
ly_add_pytest(
NAME AssetPipelineTests.AssetBuilder
PATH ${CMAKE_CURRENT_LIST_DIR}/asset_builder_tests.py
NAME AssetPipelineTests.AssetBundler
PATH ${CMAKE_CURRENT_LIST_DIR}/asset_bundler_batch_tests.py
EXCLUDE_TEST_RUN_TARGET_FROM_IDE
TEST_SERIAL
TEST_SUITE periodic
RUNTIME_DEPENDENCIES
AZ::AssetProcessor
AZ::AssetBundlerBatch
)
ly_add_pytest(
NAME AssetPipelineTests.MissingDependency
PATH ${CMAKE_CURRENT_LIST_DIR}/missing_dependency_tests.py
@@ -136,5 +140,5 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
RUNTIME_DEPENDENCIES
AZ::AssetProcessorBatch
)
endif()
@@ -108,7 +108,7 @@ class TestsAssetBundlerBatch_WindowsAndMac(object):
"""
helper = bundler_batch_helper
seed_list = os.path.join(workspace.paths.engine_root(), "Assets", "Engine", "SeedAssetList.seed") # Engine seed list
asset = r"levels\testdependencieslevel\level.pak"
asset = r"levels\testdependencieslevel\testdependencieslevel.spawnable"
# Create Asset list
helper.call_assetLists(
@@ -191,7 +191,7 @@ class TestsAssetBundlerBatch_WindowsAndMac(object):
"""
helper = bundler_batch_helper
seed_list = os.path.join(workspace.paths.engine_root(), "Assets", "Engine", "SeedAssetList.seed") # Engine seed list
asset = r"levels\testdependencieslevel\level.pak"
asset = r"levels\testdependencieslevel\testdependencieslevel.spawnable"
# Useful bundle locations / names (2 for comparing contents)
# fmt:off
@@ -924,7 +924,7 @@ class TestsAssetBundlerBatch_WindowsAndMac(object):
# Create a seed file
helper.call_seeds(
seedListFile=helper["seed_list_file"],
addSeed=r"levels\testdependencieslevel\level.pak",
addSeed=r"levels\testdependencieslevel\testdependencieslevel.spawnable",
platform="pc",
)
@@ -947,9 +947,9 @@ class TestsAssetBundlerBatch_WindowsAndMac(object):
# Specifying platform but not "add" or "remove" should fail
result, _ = helper.call_assetLists(
assetListFile=helper["asset_info_file_request"],
allowOverwrites="",
seedListFile=helper["seed_list_file"],
platform="pc",
allowOverwrites="",
)
assert result, "Overwriting with override threw an error"
@@ -982,7 +982,7 @@ class TestsAssetBundlerBatch_WindowsAndMac(object):
request.addfinalizer(lambda: fs.delete([bundle_result_path], True, False))
bundles_folder = os.path.join(workspace.paths.project(), "Bundles")
level_pak = r"levels\testdependencieslevel\level.pak"
level_pak = r"levels\testdependencieslevel\testdependencieslevel.spawnable"
bundle_request_path = os.path.join(bundles_folder, "bundle.pak")
bundle_result_path = os.path.join(bundles_folder,
helper.platform_file_name("bundle.pak", workspace.asset_processor_platform))
@@ -23,12 +23,11 @@ from ..ap_fixtures.timeout_option_fixture import timeout_option_fixture as timeo
@pytest.mark.SUITE_periodic
@pytest.mark.parametrize('launcher_platform', ['windows_editor'])
@pytest.mark.parametrize('project', ['AutomatedTesting'])
@pytest.mark.parametrize('level', ['auto_test'])
@pytest.mark.parametrize('level', ['TestDependenciesLevel'])
class TestBundleMode(object):
def test_bundle_mode_with_levels_mounts_bundles_correctly(self, request, editor, level, launcher_platform,
asset_processor, workspace, bundler_batch_helper):
level_pak = os.path.join("levels", level, "level.pak")
level_pak = os.path.join("levels", level, "TestDependenciesLevel.spawnable")
bundles_folder = os.path.join(workspace.paths.project(), "Bundles")
bundle_request_path = os.path.join(bundles_folder, "bundle.pak")
bundle_result_path = os.path.join(bundles_folder,
@@ -23,7 +23,7 @@ def output_test_data(scene):
# Just write something to the file, but the filename is the main information
# used for the test.
f.write(f"scene.sourceFilename: {scene.sourceFilename}\n")
return True
return ''
mySceneJobHandler = None
@@ -182,7 +182,7 @@ class TestAutomationBase:
@staticmethod
def _kill_ly_processes(include_asset_processor=True):
LY_PROCESSES = [
'Editor', 'Profiler', 'RemoteConsole', 'AutomatedTesting.ServerLauncher'
'Editor', 'Profiler', 'RemoteConsole', 'AutomatedTesting.ServerLauncher', 'o3de'
]
AP_PROCESSES = [
'AssetProcessor', 'AssetProcessorBatch', 'AssetBuilder', 'CrySCompileServer',
@@ -9,10 +9,10 @@
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_FOUNDATION_TEST_SUPPORTED)
ly_add_pytest(
NAME AutomatedTesting::EditorTests_Main_Optimized
NAME AutomatedTesting::EditorTests_Main
TEST_SUITE main
TEST_SERIAL
PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main_Optimized.py
PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main.py
PYTEST_MARKS "not REQUIRES_gpu"
RUNTIME_DEPENDENCIES
Legacy::Editor
@@ -27,7 +27,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
TEST_SUITE main
TEST_SERIAL
TEST_REQUIRES gpu
PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main_Optimized.py
PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main.py
PYTEST_MARKS "REQUIRES_gpu"
RUNTIME_DEPENDENCIES
Legacy::Editor
@@ -37,17 +37,4 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
Editor
)
ly_add_pytest(
NAME AutomatedTesting::EditorTests_Sandbox_Optimized
TEST_SUITE sandbox
TEST_SERIAL
PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Sandbox_Optimized.py
RUNTIME_DEPENDENCIES
Legacy::Editor
AZ::AssetProcessor
AutomatedTesting.Assets
COMPONENT
Editor
)
endif()
@@ -59,8 +59,8 @@ def AssetBrowser_SearchFiltering():
import azlmbr.legacy.general as general
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
def verify_files_appeared(model, allowed_asset_extensions, parent_index=QtCore.QModelIndex()):
indexes = [parent_index]
@@ -80,8 +80,7 @@ def AssetBrowser_SearchFiltering():
return True
# 1) Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
# 2) Open Asset Browser (if not opened already)
editor_window = pyside_utils.get_editor_main_window()
@@ -98,7 +97,13 @@ def AssetBrowser_SearchFiltering():
# 3) Type the name of an asset in the search bar and make sure it is filtered to and selectable
asset_browser = editor_window.findChild(QtWidgets.QDockWidget, "Asset Browser")
search_bar = asset_browser.findChild(QtWidgets.QLineEdit, "textSearch")
search_bar.setText("cedar.fbx")
# Add a small pause when typing in the search bar in order to check that the entries are updated properly
search_bar.setText("Cedar.f")
general.idle_wait(0.5)
search_bar.setText("Cedar.fbx")
general.idle_wait(0.5)
asset_browser_tree = asset_browser.findChild(QtWidgets.QTreeView, "m_assetBrowserTreeViewWidget")
asset_browser_table = asset_browser.findChild(QtWidgets.QTreeView, "m_assetBrowserTableViewWidget")
found = await pyside_utils.wait_for_condition(lambda: pyside_utils.find_child_by_pattern(asset_browser_table, "cedar.fbx"), 5.0)
@@ -53,6 +53,7 @@ def AssetBrowser_TreeNavigation():
import azlmbr.legacy.general as general
import editor_python_test_tools.pyside_utils as pyside_utils
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
@@ -69,8 +70,7 @@ def AssetBrowser_TreeNavigation():
file_path = ("AutomatedTesting", "Assets", "ImageGradients", "image_grad_test_gsi.png")
# 1) Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
# 2) Open Asset Browser (if not opened already)
editor_window = pyside_utils.get_editor_main_window()
@@ -215,8 +215,7 @@ def AssetPicker_UI_UX():
QtTest.QTest.keyClick(tree, Qt.Key_Enter, Qt.NoModifier)
# 1) Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
# 2) Create entity and add Mesh component
entity_position = math.Vector3(125.0, 136.0, 32.0)
@@ -56,19 +56,17 @@ def BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD():
06. delete parent entity
"""
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.utils import Report
from editor_python_test_tools.editor_entity_utils import EditorEntity
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.entity as entity
import azlmbr.legacy.general as general
import azlmbr.object
# 01. load an existing level
test_level = 'Simple'
general.open_level_no_prompt(test_level)
Report.result(Tests.load_level, general.get_current_level_name() == test_level)
hydra.open_base_level()
# 02. create parent entity and set name
# Delete any exiting entity and Create a new Entity at the root level
@@ -31,7 +31,7 @@ class Tests:
"Component removed from entity successfully",
"Failed to remove component from entity"
)
level_saved_and_exported = (
saved_and_exported = (
"Level saved and exported successfully",
"Failed to save/export level"
)
@@ -52,8 +52,7 @@ def BasicEditorWorkflows_LevelEntityComponentCRUD():
- A new entity can be created
- Entity hierarchy can be adjusted
- Components can be added/removed/updated
- Level can be saved
- Level can be exported
- Level can be saved/exported
Note:
- This test file must be called from the O3DE Editor command terminal
@@ -70,7 +69,7 @@ def BasicEditorWorkflows_LevelEntityComponentCRUD():
import azlmbr.editor as editor
import azlmbr.entity as entity
import azlmbr.math as math
import azlmbr.paths
import azlmbr.paths as paths
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.utils import Report
@@ -84,7 +83,7 @@ def BasicEditorWorkflows_LevelEntityComponentCRUD():
return None
# 1) Create a new level
level = "tmp_level"
lvl_name = "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)
@@ -95,23 +94,24 @@ def BasicEditorWorkflows_LevelEntityComponentCRUD():
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(level)
level_name.setText(lvl_name)
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") == level, 5.0)
bus.Broadcast, "GetCurrentLevelName") == lvl_name, 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()
all_entities = entity.SearchBus(azlmbr.bus.Broadcast, "SearchEntities", search_filter)
editor.ToolsApplicationRequestBus(bus.Broadcast, "DeleteEntities", all_entities)
entity_outliner_widget = editor_window.findChild(QtWidgets.QWidget, "OutlinerWidgetUI")
entity_outliner_widget = editor_window.findChild(QtWidgets.QWidget, "EntityOutlinerWidgetUI")
outliner_object_list = entity_outliner_widget.findChild(QtWidgets.QWidget, "m_objectList_Contents")
outliner_tree = outliner_object_list.findChild(QtWidgets.QWidget, "m_objectTree")
await pyside_utils.trigger_context_menu_entry(outliner_tree, "Create entity")
outliner_viewport = outliner_tree.findChild(QtWidgets.QWidget, "qt_scrollarea_viewport")
await pyside_utils.trigger_context_menu_entry(outliner_viewport, "Create entity")
# Find the new entity
parent_entity_id = find_entity_by_name("Entity1")
@@ -153,14 +153,10 @@ def BasicEditorWorkflows_LevelEntityComponentCRUD():
save_level_action = pyside_utils.get_action_for_menu_path(editor_window, "File", "Save")
pyside_utils.trigger_action_async(save_level_action)
# 5) Export the level
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", level, "level.pak"
)
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)
# 5) Verify the save/export of the level
level_prefab_path = os.path.join(paths.products, "levels", lvl_name, f"{lvl_name}.spawnable")
success = await pyside_utils.wait_for_condition(lambda: os.path.exists(level_prefab_path), 5.0)
Report.result(Tests.saved_and_exported, success)
run_test()
@@ -63,7 +63,7 @@ def ComponentCRUD_Add_Delete_Components():
:return: None
"""
from PySide2 import QtWidgets, QtTest, QtCore
from PySide2 import QtWidgets, QtTest
from PySide2.QtCore import Qt
import azlmbr.legacy.general as general
@@ -74,7 +74,6 @@ def ComponentCRUD_Add_Delete_Components():
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)
@@ -88,8 +87,7 @@ def ComponentCRUD_Add_Delete_Components():
QtTest.QTest.keyClick(tree, Qt.Key_Enter, Qt.NoModifier)
# 1) Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
# 2) Create entity
entity_position = math.Vector3(125.0, 136.0, 32.0)
@@ -62,12 +62,11 @@ def Docking_BasicDockedTools():
import azlmbr.editor as editor
import azlmbr.entity as entity
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
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
# Make sure the Entity Outliner, Entity Inspector and Console tools are open
general.open_pane("Entity Outliner (PREVIEW)")
@@ -80,7 +79,7 @@ def Docking_BasicDockedTools():
editor.EditorEntityAPIBus(bus.Event, 'SetName', entity_id, entity_original_name)
editor_window = pyside_utils.get_editor_main_window()
entity_outliner = editor_window.findChild(QtWidgets.QDockWidget, "Entity Outliner (PREVIEW)")
entity_outliner = editor_window.findChild(QtWidgets.QDockWidget, "Entity Outliner")
# 1) Open the tools and dock them together in a floating tabbed widget.
# We drag/drop it over the viewport since it doesn't allow docking, so this will undock it
@@ -88,15 +87,15 @@ def Docking_BasicDockedTools():
pyside_utils.drag_and_drop(entity_outliner, render_overlay)
# We need to grab a new reference to the Entity Outliner QDockWidget because when it gets moved
# to the floating window, its parent changes so the wrapped intance we had becomes invalid
entity_outliner = editor_window.findChild(QtWidgets.QDockWidget, "Entity Outliner (PREVIEW)")
# to the floating window, its parent changes so the wrapped instance we had becomes invalid
entity_outliner = editor_window.findChild(QtWidgets.QDockWidget, "Entity Outliner")
# Dock the Entity Inspector tabbed with the floating Entity Outliner
entity_inspector = editor_window.findChild(QtWidgets.QDockWidget, "Entity Inspector")
pyside_utils.drag_and_drop(entity_inspector, entity_outliner)
# We need to grab a new reference to the Entity Inspector QDockWidget because when it gets moved
# to the floating window, its parent changes so the wrapped intance we had becomes invalid
# to the floating window, its parent changes so the wrapped instance we had becomes invalid
entity_inspector = editor_window.findChild(QtWidgets.QDockWidget, "Entity Inspector")
# Dock the Console tabbed with the floating Entity Inspector
@@ -106,7 +105,7 @@ def Docking_BasicDockedTools():
# Check to ensure all the tools are parented to the same QStackedWidget
def check_all_panes_tabbed():
entity_inspector = editor_window.findChild(QtWidgets.QDockWidget, "Entity Inspector")
entity_outliner = editor_window.findChild(QtWidgets.QDockWidget, "Entity Outliner (PREVIEW)")
entity_outliner = editor_window.findChild(QtWidgets.QDockWidget, "Entity Outliner")
console = editor_window.findChild(QtWidgets.QDockWidget, "Console")
entity_inspector_parent = entity_inspector.parentWidget()
entity_outliner_parent = entity_outliner.parentWidget()
@@ -122,7 +121,7 @@ def Docking_BasicDockedTools():
# 2.1,2) Select an Entity in the Entity Outliner.
entity_inspector = editor_window.findChild(QtWidgets.QDockWidget, "Entity Inspector")
entity_outliner = editor_window.findChild(QtWidgets.QDockWidget, "Entity Outliner (PREVIEW)")
entity_outliner = editor_window.findChild(QtWidgets.QDockWidget, "Entity Outliner")
console = editor_window.findChild(QtWidgets.QDockWidget, "Console")
object_tree = entity_outliner.findChild(QtWidgets.QTreeView, "m_objectTree")
test_entity_index = pyside_utils.find_child_by_pattern(object_tree, entity_original_name)
@@ -30,11 +30,13 @@ def EntityOutliner_EntityOrdering():
5) Add another new entity, ensure the rest of the order is unchanged
"""
import editor_python_test_tools.pyside_utils as pyside_utils
from PySide2 import QtCore
import azlmbr.legacy.general as general
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.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
from PySide2 import QtCore, QtWidgets, QtGui, QtTest
# Grab the Editor, Entity Outliner, and Outliner Model
editor_window = pyside_utils.get_editor_main_window()
@@ -110,8 +112,7 @@ def EntityOutliner_EntityOrdering():
expected_order = []
# 1) Open the empty Prefab Base level
helper.init_idle()
helper.open_level("Prefab", "Base")
hydra.open_base_level()
# 2) Add 5 entities to the outliner
ENTITIES_TO_ADD = 5
@@ -69,8 +69,8 @@ def InputBindings_Add_Remove_Input_Events():
import azlmbr.legacy.general as general
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
def open_asset_editor():
general.open_pane("Asset Editor")
@@ -81,8 +81,7 @@ def InputBindings_Add_Remove_Input_Events():
return not general.is_pane_visible("Asset Editor")
# 1) Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
# 2) Open Asset Editor
Report.result(Tests.asset_editor_opened, open_asset_editor())
@@ -26,9 +26,9 @@ def Menus_EditMenuOptions_Work():
:return: None
"""
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.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
edit_menu_options = [
("Undo",),
@@ -52,19 +52,20 @@ def Menus_EditMenuOptions_Work():
("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"),
# The following menu options are temporarily disabled due to https://github.com/o3de/o3de/issues/6746
#("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")
hydra.open_base_level()
# 2) Interact with Edit Menu options
editor_window = pyside_utils.get_editor_main_window()
for option in edit_menu_options:
try:
action = pyside_utils.get_action_for_menu_path(editor_window, "Edit", *option)
Report.info(f"Triggering {action.iconText()}")
action.trigger()
action_triggered = True
except Exception as e:
@@ -26,35 +26,34 @@ def Menus_FileMenuOptions_Work():
:return: None
"""
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.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
file_menu_options = [
("New Level",),
("Open Level",),
("Import",),
#("Open Level",), Temporarily disabled due to https://github.com/o3de/o3de/issues/6605
#("Import",), Temporarily disabled due to https://github.com/o3de/o3de/issues/6746
("Save",),
("Save As",),
#("Save As",), Temporarily disabled due to https://github.com/o3de/o3de/issues/6605
("Save Level Statistics",),
("Edit Project Settings",),
("Edit Platform Settings",),
#("Edit Platform Settings",), Temporarily disabled due to https://github.com/o3de/o3de/issues/6604
("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")
hydra.open_base_level()
# 2) Interact with File Menu options
editor_window = pyside_utils.get_editor_main_window()
for option in file_menu_options:
try:
action = pyside_utils.get_action_for_menu_path(editor_window, "File", *option)
Report.info(f"Triggering {action.iconText()}")
action.trigger()
action_triggered = True
except Exception as e:
@@ -26,13 +26,15 @@ def Menus_ViewMenuOptions_Work():
:return: None
"""
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.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
view_menu_options = [
("Center on Selection",),
("Show Quick Access Bar",),
("Layouts", "Component Entity Layout",),
("Layouts", "Save Layout",),
("Viewport", "Configure Layout"),
("Viewport", "Go to Position"),
("Viewport", "Center on Selection"),
@@ -45,14 +47,14 @@ def Menus_ViewMenuOptions_Work():
]
# 1) Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
# 2) Interact with View Menu options
editor_window = pyside_utils.get_editor_main_window()
for option in view_menu_options:
try:
action = pyside_utils.get_action_for_menu_path(editor_window, "View", *option)
Report.info(f"Triggering {action.iconText()}")
action.trigger()
action_triggered = True
except Exception as e:
@@ -7,48 +7,77 @@ 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)
from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite
@pytest.mark.SUITE_main
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
@pytest.mark.parametrize("project", ["AutomatedTesting"])
class TestAutomation(TestAutomationBase):
class TestAutomationNoAutoTestMode(EditorTestSuite):
def test_BasicEditorWorkflows_LevelEntityComponentCRUD(self, request, workspace, editor, launcher_platform,
remove_test_level):
# 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_AssetPicker_UI_UX(EditorSharedTest):
from .EditorScripts import AssetPicker_UI_UX as test_module
class test_BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD(EditorSharedTest):
from .EditorScripts import BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD as test_module
class test_BasicEditorWorkflows_LevelEntityComponentCRUD(EditorSingleTest):
# Custom teardown to remove level 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
self._run_test(request, workspace, editor, test_module, batch_mode=False, autotest_mode=False, enable_prefab_system=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, enable_prefab_system=False)
class test_BasicEditorWorkflows_GPU_LevelEntityComponentCRUD(EditorSingleTest):
# Disable null renderer
use_null_renderer = False
def test_EntityOutlienr_EntityOrdering(self, request, workspace, editor, launcher_platform):
# Custom teardown to remove level 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.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_SearchFiltering(EditorSharedTest):
from .EditorScripts import AssetBrowser_SearchFiltering as test_module
class test_AssetBrowser_TreeNavigation(EditorSharedTest):
from .EditorScripts import AssetBrowser_TreeNavigation as test_module
class test_ComponentCRUD_Add_Delete_Components(EditorSharedTest):
from .EditorScripts import ComponentCRUD_Add_Delete_Components as test_module
@pytest.mark.skip("Passes locally/fails on Jenkins. https://github.com/o3de/o3de/issues/6747")
class test_Docking_BasicDockedTools(EditorSharedTest):
from .EditorScripts import Docking_BasicDockedTools as test_module
class test_EntityOutliner_EntityOrdering(EditorSharedTest):
from .EditorScripts import EntityOutliner_EntityOrdering as test_module
self._run_test(
request,
workspace,
editor,
test_module,
batch_mode=False,
autotest_mode=True,
)
class test_Menus_EditMenuOptions_Work(EditorSharedTest):
from .EditorScripts import Menus_EditMenuOptions as test_module
class test_Menus_FileMenuOptions_Work(EditorSharedTest):
from .EditorScripts import Menus_FileMenuOptions as test_module
class test_Menus_ViewMenuOptions_Work(EditorSharedTest):
from .EditorScripts import Menus_ViewMenuOptions as test_module
@@ -1,79 +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
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 = []
enable_prefab_system = False
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
class test_AssetPicker_UI_UX(EditorSharedTest):
from .EditorScripts import AssetPicker_UI_UX as test_module
@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"]
enable_prefab_system = False
class test_AssetBrowser_TreeNavigation(EditorSharedTest):
from .EditorScripts import AssetBrowser_TreeNavigation as test_module
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
class test_BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD(EditorSharedTest):
from .EditorScripts import BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD as test_module
@@ -1,60 +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
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, enable_prefab_system=False)
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, enable_prefab_system=False)
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, enable_prefab_system=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, enable_prefab_system=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, enable_prefab_system=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, enable_prefab_system=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, enable_prefab_system=False)
@@ -1,27 +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
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, enable_prefab_system=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, enable_prefab_system=False)
@@ -1,28 +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
from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite
@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"]
enable_prefab_system = False
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
@@ -110,7 +110,8 @@ def DynamicSliceInstanceSpawner_Embedded_E2E():
general.save_level()
general.export_to_engine()
pak_path = os.path.join(paths.products, "levels", lvl_name, "level.pak")
Report.result(Tests.saved_and_exported, os.path.exists(pak_path))
success = helper.wait_for_condition(lambda: os.path.exists(pak_path), 10.0)
Report.result(Tests.saved_and_exported, success)
if __name__ == "__main__":
@@ -132,7 +132,8 @@ def DynamicSliceInstanceSpawner_External_E2E():
general.save_level()
general.export_to_engine()
pak_path = os.path.join(paths.products, "levels", lvl_name, "level.pak")
Report.result(Tests.saved_and_exported, os.path.exists(pak_path))
success = helper.wait_for_condition(lambda: os.path.exists(pak_path), 10.0)
Report.result(Tests.saved_and_exported, success)
if __name__ == "__main__":
@@ -156,7 +156,8 @@ def LayerBlender_E2E_Editor():
general.save_level()
general.export_to_engine()
pak_path = os.path.join(paths.products, "levels", lvl_name, "level.pak")
Report.result(Tests.saved_and_exported, os.path.exists(pak_path))
success = helper.wait_for_condition(lambda: os.path.exists(pak_path), 10.0)
Report.result(Tests.saved_and_exported, success)
if __name__ == "__main__":
@@ -68,7 +68,7 @@ def ShapeIntersectionFilter_FilterStageToggle():
# Create a new entity as a child of the vegetation area entity with Box Shape
box = hydra.Entity("box")
box.create_entity(position, ["Box Shape"])
box.get_set_test(0, "Box Shape|Box Configuration|Dimensions", math.Vector3(8.0, 8.0, 1.0))
box.get_set_test(0, "Box Shape|Box Configuration|Dimensions", math.Vector3(5.0, 5.0, 1.0))
# Create a new entity as a child of the vegetation area entity with Cylinder Shape.
cylinder = hydra.Entity("cylinder")
@@ -80,10 +80,10 @@ def ShapeIntersectionFilter_FilterStageToggle():
# On the Shape Intersection Filter component, click the crosshair button, and add child entities one by one
vegetation.get_set_test(3, "Configuration|Shape Entity Id", box.id)
result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 8.0, 100), 2.0)
result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.0, 49), 2.0)
Report.result(Tests.instance_count_in_box_shape, result)
vegetation.get_set_test(3, "Configuration|Shape Entity Id", cylinder.id)
result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.0, 100), 2.0)
result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.0, 121), 2.0)
Report.result(Tests.instance_count_in_cylinder_shape, result)
# Create a new entity as a child of the area entity with Random Noise Gradient, Gradient Transform Modifier,
@@ -98,12 +98,13 @@ def ShapeIntersectionFilter_FilterStageToggle():
# Pin the Random Noise entity to the Gradient Entity Id field of the Position Modifier's Gradient X
vegetation.get_set_test(4, "Configuration|Position X|Gradient|Gradient Entity Id", random_noise.id)
# Toggle between PreProcess and PostProcess
# Toggle between PreProcess and PostProcess and validate instances. Validate in a 0.3m wider radius due to position
# offsets
vegetation.get_set_test(3, "Configuration|Filter Stage", 1)
result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.0, 117), 2.0)
result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.3, 121), 2.0)
Report.result(Tests.preprocess_instance_count, result)
vegetation.get_set_test(3, "Configuration|Filter Stage", 2)
result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.0, 122), 2.0)
result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.3, 122), 2.0)
Report.result(Tests.postprocess_instance_count, result)
@@ -73,7 +73,7 @@ def SpawnerSlices_SliceCreationAndVisibilityToggleWorks():
slice.SliceRequestBus(bus.Broadcast, "CreateNewSlice", veg_1.id, slice_path)
# 2.3) Verify if the slice has been created successfully
spawner_slice_success = helper.wait_for_condition(lambda: path_is_valid_asset(slice_path), 5.0)
spawner_slice_success = helper.wait_for_condition(lambda: path_is_valid_asset(slice_path), 10.0)
Report.result(Tests.spawner_slice_created, spawner_slice_success)
# 3) C2627904: Hiding a slice containing the component clears any visuals from the Viewport
@@ -31,19 +31,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
Smoke
)
ly_add_pytest(
NAME AutomatedTesting::EditorTestWithGPU
TEST_REQUIRES gpu
PATH ${CMAKE_CURRENT_LIST_DIR}/test_Editor_NewExistingLevels_Works.py
TIMEOUT 100
RUNTIME_DEPENDENCIES
AZ::AssetProcessor
AZ::PythonBindingsExample
Legacy::Editor
AutomatedTesting.GameLauncher
AutomatedTesting.Assets
)
ly_add_pytest(
NAME AutomatedTesting::GameLauncherWithGPU
TEST_SUITE sandbox
@@ -1,143 +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
Test Case Title: Create Test for UI apps- Editor
"""
class Tests():
level_created = ("Level created", "Failed to create level")
entity_found = ("New Entity created in level", "Failed to create New Entity in level")
mesh_added = ("Mesh Component added", "Failed to add Mesh Component")
enter_game_mode = ("Game Mode successfully entered", "Failed to enter in Game Mode")
exit_game_mode = ("Game Mode successfully exited", "Failed to exit in Game Mode")
level_opened = ("Level opened successfully", "Failed to open level")
level_exported = ("Level exported successfully", "Failed to export level")
mesh_removed = ("Mesh Component removed", "Failed to remove Mesh Component")
entity_deleted = ("Entity deleted", "Failed to delete Entity")
level_edits_present = ("Level edits persist after saving", "Failed to save level edits after saving")
def Editor_NewExistingLevels_Works():
"""
Summary: Perform the below operations on Editor
1) Launch & Close editor
2) Create new level
3) Saving and loading levels
4) Level edits persist after saving
5) Export Level
6) Can switch to play mode (ctrl+g) and exit that
7) Run editor python bindings test
8) Create an Entity
9) Delete an Entity
10) Add a component to an Entity
Expected Behavior:
All operations succeed and do not cause a crash
Test Steps:
1) Launch editor and Create a new level
2) Create a new entity
3) Add Mesh component
4) Verify enter/exit game mode
5) Save, Load and Export level
6) Remove Mesh component
7) Delete entity
8) Open an existing level
9) Create a new entity in an existing level
10) Save, Load and Export an existing level and close editor
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 os
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.utils import TestHelper as helper
from editor_python_test_tools.utils import Report
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.legacy.general as general
import azlmbr.math as math
# 1) Launch editor and Create a new level
helper.init_idle()
test_level_name = "temp_level"
general.create_level_no_prompt(test_level_name, 128, 1, 128, False)
helper.wait_for_condition(lambda: general.get_current_level_name() == test_level_name, 2.0)
Report.result(Tests.level_created, general.get_current_level_name() == test_level_name)
# 2) Create a new entity
entity_position = math.Vector3(200.0, 200.0, 38.0)
new_entity = hydra.Entity("Entity1")
new_entity.create_entity(entity_position, [])
test_entity = hydra.find_entity_by_name("Entity1")
Report.result(Tests.entity_found, test_entity.IsValid())
# 3) Add Mesh component
new_entity.add_component("Mesh")
Report.result(Tests.mesh_added, hydra.has_components(new_entity.id, ["Mesh"]))
# 4) Verify enter/exit game mode
helper.enter_game_mode(Tests.enter_game_mode)
helper.exit_game_mode(Tests.exit_game_mode)
# 5) Save, Load and Export level
# Save Level
general.save_level()
# Open Level
general.open_level(test_level_name)
Report.result(Tests.level_opened, general.get_current_level_name() == test_level_name)
# Export Level
general.export_to_engine()
level_pak_file = os.path.join("AutomatedTesting", "Levels", test_level_name, "level.pak")
Report.result(Tests.level_exported, os.path.exists(level_pak_file))
# 6) Remove Mesh component
new_entity.remove_component("Mesh")
Report.result(Tests.mesh_removed, not hydra.has_components(new_entity.id, ["Mesh"]))
# 7) Delete entity
editor.ToolsApplicationRequestBus(bus.Broadcast, "DeleteEntityById", new_entity.id)
test_entity = hydra.find_entity_by_name("Entity1")
Report.result(Tests.entity_deleted, len(test_entity) == 0)
# 8) Open an existing level
general.open_level(test_level_name)
Report.result(Tests.level_opened, general.get_current_level_name() == test_level_name)
# 9) Create a new entity in an existing level
entity_position = math.Vector3(200.0, 200.0, 38.0)
new_entity_2 = hydra.Entity("Entity2")
new_entity_2.create_entity(entity_position, [])
test_entity = hydra.find_entity_by_name("Entity2")
Report.result(Tests.entity_found, test_entity.IsValid())
# 10) Save, Load and Export an existing level
# Save Level
general.save_level()
# Open Level
general.open_level(test_level_name)
Report.result(Tests.level_opened, general.get_current_level_name() == test_level_name)
entity_id = hydra.find_entity_by_name(new_entity_2.name)
Report.result(Tests.level_edits_present, entity_id == new_entity_2.id)
# Export Level
general.export_to_engine()
level_pak_file = os.path.join("AutomatedTesting", "Levels", test_level_name, "level.pak")
Report.result(Tests.level_exported, os.path.exists(level_pak_file))
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(Editor_NewExistingLevels_Works)
@@ -1,34 +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
Test should run in both gpu and non gpu
"""
import pytest
import os
from automatedtesting_shared.base import TestAutomationBase
import ly_test_tools
import ly_test_tools.environment.file_system as file_system
@pytest.mark.SUITE_smoke
@pytest.mark.skipif(not ly_test_tools.WINDOWS, reason="Only succeeds on windows https://github.com/o3de/o3de/issues/5539")
@pytest.mark.parametrize("launcher_platform", ["windows_editor"])
@pytest.mark.parametrize("project", ["AutomatedTesting"])
@pytest.mark.parametrize("level", ["temp_level"])
class TestAutomation(TestAutomationBase):
def test_Editor_NewExistingLevels_Works(self, request, workspace, editor, level, project, launcher_platform):
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)
from . import Editor_NewExistingLevels_Works as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@@ -2,7 +2,7 @@
"description": "",
"materialType": "Materials/Types/StandardPBR.materialtype",
"parentMaterial": "",
"propertyLayoutVersion": 3,
"materialTypeVersion": 3,
"properties": {
"baseColor": {
"color": [
@@ -2,7 +2,7 @@
"description": "",
"materialType": "Materials/Types/StandardPBR.materialtype",
"parentMaterial": "",
"propertyLayoutVersion": 3,
"materialTypeVersion": 3,
"properties": {
"baseColor": {
"color": [
@@ -2,7 +2,7 @@
"description": "",
"materialType": "Materials/Types/StandardPBR.materialtype",
"parentMaterial": "",
"propertyLayoutVersion": 3,
"materialTypeVersion": 3,
"properties": {
"baseColor": {
"color": [
@@ -2,7 +2,7 @@
"description": "",
"materialType": "Materials/Types/StandardPBR.materialtype",
"parentMaterial": "",
"propertyLayoutVersion": 3,
"materialTypeVersion": 3,
"properties": {
"baseColor": {
"color": [
@@ -2,7 +2,7 @@
"description": "",
"materialType": "Materials/Types/StandardPBR.materialtype",
"parentMaterial": "",
"propertyLayoutVersion": 3,
"materialTypeVersion": 3,
"properties": {
"baseColor": {
"color": [
@@ -2,7 +2,7 @@
"description": "",
"materialType": "Materials/Types/StandardPBR.materialtype",
"parentMaterial": "",
"propertyLayoutVersion": 3,
"materialTypeVersion": 3,
"properties": {
"baseColor": {
"color": [
@@ -2,7 +2,7 @@
"description": "",
"materialType": "Materials/Types/StandardPBR.materialtype",
"parentMaterial": "",
"propertyLayoutVersion": 3,
"materialTypeVersion": 3,
"properties": {
"baseColor": {
"color": [
@@ -2,7 +2,7 @@
"description": "",
"materialType": "Materials/Types/StandardPBR.materialtype",
"parentMaterial": "",
"propertyLayoutVersion": 3,
"materialTypeVersion": 3,
"properties": {
"baseColor": {
"color": [
@@ -2,7 +2,7 @@
"description": "",
"materialType": "Materials/Types/StandardPBR.materialtype",
"parentMaterial": "",
"propertyLayoutVersion": 3,
"materialTypeVersion": 3,
"properties": {
"emissive": {
"color": [
@@ -2,7 +2,7 @@
"description": "",
"materialType": "Materials/Types/StandardPBR.materialtype",
"parentMaterial": "",
"propertyLayoutVersion": 3,
"materialTypeVersion": 3,
"properties": {
"emissive": {
"color": [
+8 -3
View File
@@ -4,14 +4,19 @@
"license": "Apache-2.0 Or MIT",
"license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt",
"origin": "Open 3D Engine - o3de.org",
"origin_url": "https://github.com/o3de/o3de",
"type": "Asset",
"summary": "A standard test scene for Global Illumination (forked from crytek sponza scene)",
"canonical_tags": [
"Gem"
"Gem",
"Asset"
],
"user_tags": [
"Assets"
"Sponza"
],
"icon_path": "preview.png",
"requirements": "",
"dependencies": []
"documentation_url": "",
"dependencies": [
]
}
+11 -3
View File
@@ -3,13 +3,21 @@
"display_name": "AutomatedTesting",
"license": "Apache-2.0 Or MIT",
"license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt",
"origin": "Amazon Web Services, Inc.",
"origin": "Open 3D Engine - o3de.org",
"origin_url": "https://github.com/o3de/o3de",
"type": "Code",
"summary": "Project Gem for customizing the AutomatedTesting project functionality.",
"canonical_tags": [
"Gem"
],
"user_tags": [],
"user_tags": [
"AutomatedTesting"
],
"icon_path": "preview.png",
"requirements": ""
"requirements": "",
"documentation_url": "",
"dependencies": [],
"external_subdirectories": [
"PythonCoverage"
]
}
@@ -1474,9 +1474,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{1FD47684-2E9E-5525-BBCA-251795F9033C}"
"guid": "{12B5A321-3D64-5DF6-9E15-D8F447229EC1}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m00_r00.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m00_r00.azmaterial"
}
}
}
@@ -1569,9 +1569,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{B5660D78-818E-5273-AF3D-EC8189E2E6CB}"
"guid": "{EB8B9C49-D6F4-5098-AC97-543381E2554A}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m00_r01.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m00_r01.azmaterial"
}
}
}
@@ -1824,9 +1824,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{512443BD-9511-5F13-A84A-3ED5DB9E9B5A}"
"guid": "{CAA9CAFC-8A48-5406-BE26-448E5AA1A5B0}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m00_r02.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m00_r02.azmaterial"
}
}
}
@@ -1926,9 +1926,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{E28A5CC5-4B8B-5B90-877A-3D92C75DC75A}"
"guid": "{2F338C0B-EF86-5AC4-AEE6-28A26BB9E97E}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m00_r03.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m00_r03.azmaterial"
}
}
}
@@ -2028,9 +2028,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{1495BCCF-3F96-5D0B-8176-228DB22CEC82}"
"guid": "{9BF4E656-0D4F-5746-A256-32740742712B}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m00_r04.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m00_r04.azmaterial"
}
}
}
@@ -2130,9 +2130,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{40494612-0ABF-55B5-9C56-E968763FCFDE}"
"guid": "{850398D7-386A-56C6-AEB2-95E4F64368B1}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m00_r05.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m00_r05.azmaterial"
}
}
}
@@ -2232,9 +2232,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{76CF9D4A-009F-5494-83AB-6E3D4D1B4A36}"
"guid": "{74784C2A-A713-5C6A-8B3D-B66CAE3DD055}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m00_r06.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m00_r06.azmaterial"
}
}
}
@@ -2334,9 +2334,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{8431B792-E6CC-51DD-B82E-F3E4A12FCB4A}"
"guid": "{4F9F91F7-7E22-5A14-856D-194CC258E70D}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m00_r07.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m00_r07.azmaterial"
}
}
}
@@ -2436,9 +2436,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{4B1F29FF-7971-5524-AA1B-0DC2392A33C4}"
"guid": "{842AE870-802B-5934-997F-0965F960ECB9}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m00_r08.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m00_r08.azmaterial"
}
}
}
@@ -2538,9 +2538,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{785BE6DE-C0EB-5B47-9438-4F9ECFC34A96}"
"guid": "{0184CF10-E675-5C33-B1B9-009C383AB463}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m00_r09.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m00_r09.azmaterial"
}
}
}
@@ -2640,9 +2640,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{C40DE9AE-6756-57E7-B3B4-FB0542B5CD0F}"
"guid": "{6DDA0761-C165-58CC-B45E-03C29F0CF598}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m00_r10.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m00_r10.azmaterial"
}
}
}
@@ -2896,9 +2896,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{251C4C29-4ECD-5763-AF4F-20675EAC048B}"
"guid": "{101AB53A-3B3E-5ACF-841C-65DB2BFBF305}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m10_r04.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m10_r04.azmaterial"
}
}
}
@@ -2998,9 +2998,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{02D082C4-5032-57CC-A081-BC4D8518BCF0}"
"guid": "{B82B96D6-7511-5E22-A36E-FFF682B3236B}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m10_r05.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m10_r05.azmaterial"
}
}
}
@@ -3100,9 +3100,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{FA9D8842-95B2-5371-8352-CBEEEAABE676}"
"guid": "{DBED5292-3E17-5038-9974-80A8BB1F79E8}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m10_r06.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m10_r06.azmaterial"
}
}
}
@@ -3202,9 +3202,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{522A9626-FF4C-561A-A44A-64B68F7274D2}"
"guid": "{25F07733-365C-5826-AEE3-E92FBE807555}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m10_r07.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m10_r07.azmaterial"
}
}
}
@@ -3304,9 +3304,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{06DDFD66-D7F5-5D55-8972-6D61276E88F6}"
"guid": "{C9A7B916-CF71-5A34-B9B9-54FE8CB058DC}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m10_r00.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m10_r00.azmaterial"
}
}
}
@@ -3399,9 +3399,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{060EF1B7-1029-5227-B03B-1415C74E9D65}"
"guid": "{85C8DFC5-358D-579D-B922-14FA1B401571}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m10_r08.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m10_r08.azmaterial"
}
}
}
@@ -3501,9 +3501,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{7B7BC6F8-150A-518F-816E-2F7DBE786461}"
"guid": "{51924281-7A06-5654-B783-A4F5759063ED}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m10_r01.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m10_r01.azmaterial"
}
}
}
@@ -3603,9 +3603,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{270881B6-21E9-509D-A6CD-1046674FB0BE}"
"guid": "{7877F64E-26E3-558C-B6D9-B609ED6E43BF}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m10_r09.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m10_r09.azmaterial"
}
}
}
@@ -3705,9 +3705,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{C0538953-C56E-5C1A-BBE2-E6BE04764C20}"
"guid": "{6CC3C6B9-EE05-5A77-A12D-7085D93D89DB}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m10_r02.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m10_r02.azmaterial"
}
}
}
@@ -3874,9 +3874,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{5EA26E09-E3D6-5181-8E7A-F2E98A24247C}"
"guid": "{E6E15876-EEF3-555D-BD80-1B9D5A7ECC7D}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m10_r10.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m10_r10.azmaterial"
}
}
}
@@ -3976,9 +3976,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{E1A5D708-7A49-5CCA-81C3-4CB337C47703}"
"guid": "{83179EEC-BAC7-5D39-9788-37D33E9584B1}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m10_r03.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m10_r03.azmaterial"
}
}
}
@@ -1,6 +1,6 @@
{
"materialType": "Materials/Types/StandardPBR.materialtype",
"propertyLayoutVersion": 1,
"materialTypeVersion": 1,
"properties": {
"baseColor": {
"color": [ 1.0, 1.0, 1.0 ],
@@ -1,7 +1,7 @@
{
"parentMaterial": "./basic.material",
"materialType": "Materials/Types/StandardPBR.materialtype",
"propertyLayoutVersion": 1,
"materialTypeVersion": 1,
"properties": {
"metallic": {
"factor": 0.0
@@ -1,7 +1,7 @@
{
"parentMaterial": "./basic.material",
"materialType": "Materials/Types/StandardPBR.materialtype",
"propertyLayoutVersion": 1,
"materialTypeVersion": 1,
"properties": {
"metallic": {
"factor": 0.0
@@ -1,7 +1,7 @@
{
"parentMaterial": "./basic.material",
"materialType": "Materials/Types/StandardPBR.materialtype",
"propertyLayoutVersion": 1,
"materialTypeVersion": 1,
"properties": {
"metallic": {
"factor": 0.0
@@ -1,7 +1,7 @@
{
"parentMaterial": "./basic.material",
"materialType": "Materials/Types/StandardPBR.materialtype",
"propertyLayoutVersion": 1,
"materialTypeVersion": 1,
"properties": {
"metallic": {
"factor": 0.0
@@ -1,7 +1,7 @@
{
"parentMaterial": "./basic.material",
"materialType": "Materials/Types/StandardPBR.materialtype",
"propertyLayoutVersion": 1,
"materialTypeVersion": 1,
"properties": {
"metallic": {
"factor": 0.0
@@ -1,7 +1,7 @@
{
"parentMaterial": "./basic.material",
"materialType": "Materials/Types/StandardPBR.materialtype",
"propertyLayoutVersion": 1,
"materialTypeVersion": 1,
"properties": {
"metallic": {
"factor": 0.0
@@ -1,7 +1,7 @@
{
"parentMaterial": "./basic.material",
"materialType": "Materials/Types/StandardPBR.materialtype",
"propertyLayoutVersion": 1,
"materialTypeVersion": 1,
"properties": {
"metallic": {
"factor": 0.0
@@ -1,7 +1,7 @@
{
"parentMaterial": "./basic.material",
"materialType": "Materials/Types/StandardPBR.materialtype",
"propertyLayoutVersion": 1,
"materialTypeVersion": 1,
"properties": {
"metallic": {
"factor": 0.0
@@ -1,7 +1,7 @@
{
"parentMaterial": "./basic.material",
"materialType": "Materials/Types/StandardPBR.materialtype",
"propertyLayoutVersion": 1,
"materialTypeVersion": 1,
"properties": {
"metallic": {
"factor": 0.0
@@ -1,7 +1,7 @@
{
"parentMaterial": "./basic.material",
"materialType": "Materials/Types/StandardPBR.materialtype",
"propertyLayoutVersion": 1,
"materialTypeVersion": 1,
"properties": {
"metallic": {
"factor": 0.0
@@ -1,7 +1,7 @@
{
"parentMaterial": "./basic.material",
"materialType": "Materials/Types/StandardPBR.materialtype",
"propertyLayoutVersion": 1,
"materialTypeVersion": 1,
"properties": {
"metallic": {
"factor": 0.0
@@ -1,7 +1,7 @@
{
"parentMaterial": "./basic.material",
"materialType": "Materials/Types/StandardPBR.materialtype",
"propertyLayoutVersion": 1,
"materialTypeVersion": 1,
"properties": {
"metallic": {
"factor": 1.0
@@ -1,7 +1,7 @@
{
"parentMaterial": "./basic.material",
"materialType": "Materials/Types/StandardPBR.materialtype",
"propertyLayoutVersion": 1,
"materialTypeVersion": 1,
"properties": {
"metallic": {
"factor": 1.0
@@ -1,7 +1,7 @@
{
"parentMaterial": "./basic.material",
"materialType": "Materials/Types/StandardPBR.materialtype",
"propertyLayoutVersion": 1,
"materialTypeVersion": 1,
"properties": {
"metallic": {
"factor": 1.0
@@ -1,7 +1,7 @@
{
"parentMaterial": "./basic.material",
"materialType": "Materials/Types/StandardPBR.materialtype",
"propertyLayoutVersion": 1,
"materialTypeVersion": 1,
"properties": {
"metallic": {
"factor": 1.0
@@ -1,7 +1,7 @@
{
"parentMaterial": "./basic.material",
"materialType": "Materials/Types/StandardPBR.materialtype",
"propertyLayoutVersion": 1,
"materialTypeVersion": 1,
"properties": {
"metallic": {
"factor": 1.0
@@ -1,7 +1,7 @@
{
"parentMaterial": "./basic.material",
"materialType": "Materials/Types/StandardPBR.materialtype",
"propertyLayoutVersion": 1,
"materialTypeVersion": 1,
"properties": {
"metallic": {
"factor": 1.0
@@ -1,7 +1,7 @@
{
"parentMaterial": "./basic.material",
"materialType": "Materials/Types/StandardPBR.materialtype",
"propertyLayoutVersion": 1,
"materialTypeVersion": 1,
"properties": {
"metallic": {
"factor": 1.0
@@ -1,7 +1,7 @@
{
"parentMaterial": "./basic.material",
"materialType": "Materials/Types/StandardPBR.materialtype",
"propertyLayoutVersion": 1,
"materialTypeVersion": 1,
"properties": {
"metallic": {
"factor": 1.0
@@ -1,7 +1,7 @@
{
"parentMaterial": "./basic.material",
"materialType": "Materials/Types/StandardPBR.materialtype",
"propertyLayoutVersion": 1,
"materialTypeVersion": 1,
"properties": {
"metallic": {
"factor": 1.0
@@ -1,7 +1,7 @@
{
"parentMaterial": "./basic.material",
"materialType": "Materials/Types/StandardPBR.materialtype",
"propertyLayoutVersion": 1,
"materialTypeVersion": 1,
"properties": {
"metallic": {
"factor": 1.0
@@ -1,7 +1,7 @@
{
"parentMaterial": "./basic.material",
"materialType": "Materials/Types/StandardPBR.materialtype",
"propertyLayoutVersion": 1,
"materialTypeVersion": 1,
"properties": {
"metallic": {
"factor": 1.0
@@ -0,0 +1,566 @@
{
"ContainerEntity": {
"Id": "ContainerEntity",
"Name": "ShadowTest",
"Components": {
"Component_[10182366347512475253]": {
"$type": "EditorPrefabComponent",
"Id": 10182366347512475253
},
"Component_[12917798267488243668]": {
"$type": "EditorPendingCompositionComponent",
"Id": 12917798267488243668
},
"Component_[3261249813163778338]": {
"$type": "EditorOnlyEntityComponent",
"Id": 3261249813163778338
},
"Component_[3837204912784440039]": {
"$type": "EditorDisabledCompositionComponent",
"Id": 3837204912784440039
},
"Component_[4272963378099646759]": {
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
"Id": 4272963378099646759,
"Parent Entity": ""
},
"Component_[4848458548047175816]": {
"$type": "EditorVisibilityComponent",
"Id": 4848458548047175816
},
"Component_[5787060997243919943]": {
"$type": "EditorInspectorComponent",
"Id": 5787060997243919943
},
"Component_[7804170251266531779]": {
"$type": "EditorLockComponent",
"Id": 7804170251266531779
},
"Component_[7874177159288365422]": {
"$type": "EditorEntitySortComponent",
"Id": 7874177159288365422
},
"Component_[8018146290632383969]": {
"$type": "EditorEntityIconComponent",
"Id": 8018146290632383969
},
"Component_[8452360690590857075]": {
"$type": "SelectionComponent",
"Id": 8452360690590857075
}
}
},
"Entities": {
"Entity_[232650527119]": {
"Id": "Entity_[232650527119]",
"Name": "DirectionalLight",
"Components": {
"Component_[10660156197505313227]": {
"$type": "EditorLockComponent",
"Id": 10660156197505313227
},
"Component_[14184823757717157844]": {
"$type": "EditorInspectorComponent",
"Id": 14184823757717157844,
"ComponentOrderEntryArray": [
{
"ComponentId": 9854879901259791898
},
{
"ComponentId": 3968519938187714949,
"SortIndex": 1
}
]
},
"Component_[1495573908681275492]": {
"$type": "EditorEntitySortComponent",
"Id": 1495573908681275492
},
"Component_[15580233403487968826]": {
"$type": "EditorDisabledCompositionComponent",
"Id": 15580233403487968826
},
"Component_[3968519938187714949]": {
"$type": "AZ::Render::EditorDirectionalLightComponent",
"Id": 3968519938187714949,
"Controller": {
"Configuration": {
"Intensity": 0.0,
"CameraEntityId": "",
"ShadowmapSize": "Size2048"
}
}
},
"Component_[4961040003466069196]": {
"$type": "EditorEntityIconComponent",
"Id": 4961040003466069196
},
"Component_[7824884165323036147]": {
"$type": "EditorVisibilityComponent",
"Id": 7824884165323036147
},
"Component_[8741866916946672319]": {
"$type": "EditorPendingCompositionComponent",
"Id": 8741866916946672319
},
"Component_[9288966876314965560]": {
"$type": "EditorOnlyEntityComponent",
"Id": 9288966876314965560
},
"Component_[9313163355156975968]": {
"$type": "SelectionComponent",
"Id": 9313163355156975968
},
"Component_[9854879901259791898]": {
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
"Id": 9854879901259791898,
"Parent Entity": "ContainerEntity",
"Transform Data": {
"Translate": [
0.0,
0.0,
2.0
],
"Rotate": [
-32.05662536621094,
-26.103206634521484,
47.54806137084961
]
}
}
}
},
"Entity_[260824893221]": {
"Id": "Entity_[260824893221]",
"Name": "SpotLight",
"Components": {
"Component_[16098295228434057928]": {
"$type": "EditorDiskShapeComponent",
"Id": 16098295228434057928,
"ShapeColor": [
1.0,
1.0,
1.0,
1.0
],
"DiskShape": {
"Configuration": {
"Radius": 0.0
}
}
},
"Component_[16175995808158769171]": {
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
"Id": 16175995808158769171,
"Parent Entity": "ContainerEntity",
"Transform Data": {
"Translate": [
0.6417449712753296,
1.3211734294891357,
3.022759199142456
],
"Rotate": [
243.31329345703125,
0.0,
0.0
]
}
},
"Component_[17136787899581093377]": {
"$type": "EditorEntitySortComponent",
"Id": 17136787899581093377
},
"Component_[17938027566627202610]": {
"$type": "EditorPendingCompositionComponent",
"Id": 17938027566627202610
},
"Component_[190081405128299223]": {
"$type": "SelectionComponent",
"Id": 190081405128299223
},
"Component_[2181418147135573579]": {
"$type": "EditorEntityIconComponent",
"Id": 2181418147135573579
},
"Component_[2564149706319215342]": {
"$type": "EditorOnlyEntityComponent",
"Id": 2564149706319215342
},
"Component_[3716169383940064541]": {
"$type": "EditorInspectorComponent",
"Id": 3716169383940064541,
"ComponentOrderEntryArray": [
{
"ComponentId": 16175995808158769171
},
{
"ComponentId": 16665800442781289114,
"SortIndex": 1
}
]
},
"Component_[4143676462074671972]": {
"$type": "AZ::Render::EditorAreaLightComponent",
"Id": 4143676462074671972,
"Controller": {
"Configuration": {
"LightType": 2,
"AttenuationRadius": 31.62277603149414,
"EnableShutters": true,
"InnerShutterAngleDegrees": 22.5,
"OuterShutterAngleDegrees": 27.5,
"Enable Shadow": true,
"Shadowmap Max Size": "Size2048",
"Filtering Sample Count": 32
}
}
},
"Component_[6706371214647538019]": {
"$type": "EditorVisibilityComponent",
"Id": 6706371214647538019
},
"Component_[7493944209625718550]": {
"$type": "EditorLockComponent",
"Id": 7493944209625718550
},
"Component_[7614113482082939165]": {
"$type": "EditorDisabledCompositionComponent",
"Id": 7614113482082939165
}
}
},
"Entity_[269117486973]": {
"Id": "Entity_[269117486973]",
"Name": "Floor",
"Components": {
"Component_[10562678944594915756]": {
"$type": "EditorEntitySortComponent",
"Id": 10562678944594915756
},
"Component_[1175452962278157526]": {
"$type": "EditorEntityIconComponent",
"Id": 1175452962278157526
},
"Component_[13598353801231166887]": {
"$type": "EditorPendingCompositionComponent",
"Id": 13598353801231166887
},
"Component_[13735087293504923475]": {
"$type": "SelectionComponent",
"Id": 13735087293504923475
},
"Component_[13888244442459268363]": {
"$type": "AZ::Render::EditorMeshComponent",
"Id": 13888244442459268363,
"Controller": {
"Configuration": {
"ModelAsset": {
"assetId": {
"guid": "{E65E9ED3-3E38-5ABA-9E22-95E34DA4C3AE}",
"subId": 280178048
},
"assetHint": "objects/plane.azmodel"
},
"LodOverride": 255
}
}
},
"Component_[1525720357937234014]": {
"$type": "EditorMaterialComponent",
"Id": 1525720357937234014,
"materialSlotsByLodEnabled": true
},
"Component_[16568998871680422442]": {
"$type": "EditorDisabledCompositionComponent",
"Id": 16568998871680422442
},
"Component_[2147751093058990131]": {
"$type": "EditorInspectorComponent",
"Id": 2147751093058990131,
"ComponentOrderEntryArray": [
{
"ComponentId": 3266761149114817871
},
{
"ComponentId": 13888244442459268363,
"SortIndex": 1
},
{
"ComponentId": 1525720357937234014,
"SortIndex": 2
}
]
},
"Component_[3266761149114817871]": {
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
"Id": 3266761149114817871,
"Parent Entity": "ContainerEntity",
"Transform Data": {
"Scale": [
100.0,
100.0,
100.0
],
"UniformScale": 100.0
}
},
"Component_[4625895382416898670]": {
"$type": "EditorVisibilityComponent",
"Id": 4625895382416898670
},
"Component_[4856699190357614535]": {
"$type": "EditorLockComponent",
"Id": 4856699190357614535
},
"Component_[6466465153982575739]": {
"$type": "EditorOnlyEntityComponent",
"Id": 6466465153982575739
}
}
},
"Entity_[282757803856]": {
"Id": "Entity_[282757803856]",
"Name": "Cube",
"Components": {
"Component_[11189870094752260272]": {
"$type": "EditorEntitySortComponent",
"Id": 11189870094752260272
},
"Component_[11909086967677513257]": {
"$type": "AZ::Render::EditorMeshComponent",
"Id": 11909086967677513257,
"Controller": {
"Configuration": {
"ModelAsset": {
"assetId": {
"guid": "{593006BE-FE73-5A4B-A0A6-06C02EFFE458}",
"subId": 285127096
},
"loadBehavior": "PreLoad",
"assetHint": "objects/cube.azmodel"
},
"LodOverride": 255
}
}
},
"Component_[1443341568598731610]": {
"$type": "EditorVisibilityComponent",
"Id": 1443341568598731610
},
"Component_[18339772707807258951]": {
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
"Id": 18339772707807258951,
"Parent Entity": "ContainerEntity",
"Transform Data": {
"Translate": [
0.6083869934082031,
3.137901782989502,
0.5876787900924683
]
}
},
"Component_[2447207272572065708]": {
"$type": "EditorEntityIconComponent",
"Id": 2447207272572065708
},
"Component_[3281906807632213471]": {
"$type": "SelectionComponent",
"Id": 3281906807632213471
},
"Component_[3412442673858204671]": {
"$type": "EditorPendingCompositionComponent",
"Id": 3412442673858204671
},
"Component_[5382641380294287889]": {
"$type": "EditorDisabledCompositionComponent",
"Id": 5382641380294287889
},
"Component_[7221534636342494619]": {
"$type": "EditorInspectorComponent",
"Id": 7221534636342494619,
"ComponentOrderEntryArray": [
{
"ComponentId": 18339772707807258951
},
{
"ComponentId": 11909086967677513257,
"SortIndex": 1
}
]
},
"Component_[7701217952253676487]": {
"$type": "EditorLockComponent",
"Id": 7701217952253676487
},
"Component_[7758436981023123121]": {
"$type": "EditorOnlyEntityComponent",
"Id": 7758436981023123121
}
}
},
"Entity_[372196702077]": {
"Id": "Entity_[372196702077]",
"Name": "Bunny",
"Components": {
"Component_[11345914745205508221]": {
"$type": "EditorEntityIconComponent",
"Id": 11345914745205508221
},
"Component_[11507863983962969790]": {
"$type": "EditorMaterialComponent",
"Id": 11507863983962969790,
"materialSlotsByLodEnabled": true
},
"Component_[1342998773562921470]": {
"$type": "EditorPendingCompositionComponent",
"Id": 1342998773562921470
},
"Component_[14975835087235718844]": {
"$type": "EditorInspectorComponent",
"Id": 14975835087235718844,
"ComponentOrderEntryArray": [
{
"ComponentId": 5012565883129470759
},
{
"ComponentId": 7975043234993822905,
"SortIndex": 1
},
{
"ComponentId": 11507863983962969790,
"SortIndex": 2
}
]
},
"Component_[16460806723667032929]": {
"$type": "EditorOnlyEntityComponent",
"Id": 16460806723667032929
},
"Component_[18225690044585951363]": {
"$type": "EditorLockComponent",
"Id": 18225690044585951363
},
"Component_[18314752491697618927]": {
"$type": "EditorEntitySortComponent",
"Id": 18314752491697618927
},
"Component_[2431610550789583502]": {
"$type": "EditorVisibilityComponent",
"Id": 2431610550789583502
},
"Component_[5012565883129470759]": {
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
"Id": 5012565883129470759,
"Parent Entity": "ContainerEntity",
"Transform Data": {
"Translate": [
0.0,
0.0,
0.20401419699192047
]
}
},
"Component_[7975043234993822905]": {
"$type": "AZ::Render::EditorMeshComponent",
"Id": 7975043234993822905,
"Controller": {
"Configuration": {
"ModelAsset": {
"assetId": {
"guid": "{0C6BBB76-4EC2-583A-B8C6-1A4C4FD1FE9D}",
"subId": 283109893
},
"assetHint": "objects/bunny.azmodel"
},
"LodOverride": 255
}
}
},
"Component_[8510666363380501112]": {
"$type": "SelectionComponent",
"Id": 8510666363380501112
},
"Component_[9639060480533776634]": {
"$type": "EditorDisabledCompositionComponent",
"Id": 9639060480533776634
}
}
},
"Entity_[670308843764]": {
"Id": "Entity_[670308843764]",
"Name": "Camera1",
"Components": {
"Component_[12951260100632682169]": {
"$type": "GenericComponentWrapper",
"Id": 12951260100632682169,
"m_template": {
"$type": "FlyCameraInputComponent"
}
},
"Component_[14180723329646459524]": {
"$type": "EditorPendingCompositionComponent",
"Id": 14180723329646459524
},
"Component_[14996469885773917977]": {
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
"Id": 14996469885773917977,
"Parent Entity": "ContainerEntity",
"Transform Data": {
"Translate": [
4.563776969909668,
0.7667046785354614,
3.000542640686035
],
"Rotate": [
-9.740042686462402,
-20.20942497253418,
63.57760238647461
]
}
},
"Component_[17638492356673689530]": {
"$type": "EditorInspectorComponent",
"Id": 17638492356673689530
},
"Component_[2421853983468750254]": {
"$type": "{CA11DA46-29FF-4083-B5F6-E02C3A8C3A3D} EditorCameraComponent",
"Id": 2421853983468750254,
"Controller": {
"Configuration": {
"Field of View": 90.00020599365234,
"EditorEntityId": 666013876468
}
}
},
"Component_[2572028619185965684]": {
"$type": "EditorEntityIconComponent",
"Id": 2572028619185965684
},
"Component_[2782900516907042776]": {
"$type": "EditorDisabledCompositionComponent",
"Id": 2782900516907042776
},
"Component_[2849166119438883669]": {
"$type": "EditorVisibilityComponent",
"Id": 2849166119438883669
},
"Component_[4618311795498613781]": {
"$type": "EditorOnlyEntityComponent",
"Id": 4618311795498613781
},
"Component_[5402004894214413002]": {
"$type": "EditorEntitySortComponent",
"Id": 5402004894214413002
},
"Component_[6111028576371006514]": {
"$type": "SelectionComponent",
"Id": 6111028576371006514
},
"Component_[8203141294643544464]": {
"$type": "EditorLockComponent",
"Id": 8203141294643544464
}
}
}
}
}
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:60276c07b45a734e4f71d695278167ea61e884f8b513906168c9642078ad5954
size 6045
oid sha256:0d004c329a7c5044a8fe05b6dbbf9b19de29c60acec75f13fdbc344a55aab8c7
size 6404

Some files were not shown because too many files have changed in this diff Show More