Merge branch 'upstream/development' into LYN-6770_AutomatedTestNetInputs
This commit is contained in:
@@ -3,8 +3,6 @@ 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
|
||||
|
||||
Main suite tests for the Atom renderer.
|
||||
"""
|
||||
import logging
|
||||
import os
|
||||
@@ -25,21 +23,20 @@ TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "tests")
|
||||
class TestAtomEditorComponentsMain(object):
|
||||
"""Holds tests for Atom components."""
|
||||
|
||||
@pytest.mark.xfail(reason="This test is being marked xfail as it failed during an unrelated development run. See LYN-7530 for more details.")
|
||||
@pytest.mark.test_case_id("C32078118") # Decal
|
||||
@pytest.mark.test_case_id("C32078119") # DepthOfField
|
||||
@pytest.mark.test_case_id("C32078120") # Directional Light
|
||||
@pytest.mark.test_case_id("C32078121") # Exposure Control
|
||||
@pytest.mark.test_case_id("C32078115") # Global Skylight (IBL)
|
||||
@pytest.mark.test_case_id("C32078125") # Physical Sky
|
||||
@pytest.mark.test_case_id("C32078127") # PostFX Layer
|
||||
@pytest.mark.test_case_id("C32078131") # PostFX Radius Weight Modifier
|
||||
@pytest.mark.test_case_id("C32078117") # Light
|
||||
@pytest.mark.test_case_id("C36525660") # Display Mapper
|
||||
def test_AtomEditorComponents_AddedToEntity(self, request, editor, level, workspace, project, launcher_platform):
|
||||
"""
|
||||
Please review the hydra script run by this test for more specific test info.
|
||||
Tests the following Atom components and verifies all "expected_lines" appear in Editor.log:
|
||||
1. Display Mapper
|
||||
2. Light
|
||||
3. PostFX Radius Weight Modifier
|
||||
4. PostFX Layer
|
||||
5. Physical Sky
|
||||
6. Global Skylight (IBL)
|
||||
7. Exposure Control
|
||||
8. Directional Light
|
||||
9. DepthOfField
|
||||
10. Decal
|
||||
Tests the Atom components & verifies all "expected_lines" appear in Editor.log
|
||||
"""
|
||||
cfg_args = [level]
|
||||
|
||||
@@ -72,6 +69,18 @@ class TestAtomEditorComponentsMain(object):
|
||||
"DepthOfField_test: Entity deleted: True",
|
||||
"DepthOfField_test: UNDO entity deletion works: True",
|
||||
"DepthOfField_test: REDO entity deletion works: True",
|
||||
# Directional Light Component
|
||||
"Directional Light Entity successfully created",
|
||||
"Directional Light_test: Component added to the entity: True",
|
||||
"Directional Light_test: Component removed after UNDO: True",
|
||||
"Directional Light_test: Component added after REDO: True",
|
||||
"Directional Light_test: Entered game mode: True",
|
||||
"Directional Light_test: Exit game mode: True",
|
||||
"Directional Light_test: Entity is hidden: True",
|
||||
"Directional Light_test: Entity is shown: True",
|
||||
"Directional Light_test: Entity deleted: True",
|
||||
"Directional Light_test: UNDO entity deletion works: True",
|
||||
"Directional Light_test: REDO entity deletion works: True",
|
||||
# Exposure Control Component
|
||||
"Exposure Control Entity successfully created",
|
||||
"Exposure Control_test: Component added to the entity: True",
|
||||
@@ -162,21 +171,6 @@ class TestAtomEditorComponentsMain(object):
|
||||
"Display Mapper_test: Entity deleted: True",
|
||||
"Display Mapper_test: UNDO entity deletion works: True",
|
||||
"Display Mapper_test: REDO entity deletion works: True",
|
||||
# Reflection Probe Component
|
||||
"Reflection Probe Entity successfully created",
|
||||
"Reflection Probe_test: Component added to the entity: True",
|
||||
"Reflection Probe_test: Component removed after UNDO: True",
|
||||
"Reflection Probe_test: Component added after REDO: True",
|
||||
"Reflection Probe_test: Entered game mode: True",
|
||||
"Reflection Probe_test: Exit game mode: True",
|
||||
"Reflection Probe_test: Entity disabled initially: True",
|
||||
"Reflection Probe_test: Entity enabled after adding required components: True",
|
||||
"Reflection Probe_test: Cubemap is generated: True",
|
||||
"Reflection Probe_test: Entity is hidden: True",
|
||||
"Reflection Probe_test: Entity is shown: True",
|
||||
"Reflection Probe_test: Entity deleted: True",
|
||||
"Reflection Probe_test: UNDO entity deletion works: True",
|
||||
"Reflection Probe_test: REDO entity deletion works: True",
|
||||
]
|
||||
|
||||
unexpected_lines = [
|
||||
@@ -198,6 +192,7 @@ class TestAtomEditorComponentsMain(object):
|
||||
cfg_args=cfg_args,
|
||||
)
|
||||
|
||||
@pytest.mark.test_case_id("C34525095")
|
||||
def test_AtomEditorComponents_LightComponent(
|
||||
self, request, editor, workspace, project, launcher_platform, level):
|
||||
"""
|
||||
@@ -284,6 +279,15 @@ class TestMaterialEditorBasicTests(object):
|
||||
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):
|
||||
|
||||
|
||||
@@ -73,6 +73,7 @@ def create_screenshots_archive(screenshot_path):
|
||||
class TestAllComponentsIndepthTests(object):
|
||||
|
||||
@pytest.mark.parametrize("screenshot_name", ["AtomBasicLevelSetup.ppm"])
|
||||
@pytest.mark.test_case_id("C34603773")
|
||||
def test_BasicLevelSetup_SetsUpLevel(
|
||||
self, request, editor, workspace, project, launcher_platform, level, screenshot_name):
|
||||
"""
|
||||
@@ -115,6 +116,7 @@ class TestAllComponentsIndepthTests(object):
|
||||
|
||||
create_screenshots_archive(screenshot_directory)
|
||||
|
||||
@pytest.mark.test_case_id("C34525095")
|
||||
def test_LightComponent_ScreenshotMatchesGoldenImage(
|
||||
self, request, editor, workspace, project, launcher_platform, level):
|
||||
"""
|
||||
@@ -146,7 +148,7 @@ class TestAllComponentsIndepthTests(object):
|
||||
golden_image_path = os.path.join(golden_images_directory(), golden_image)
|
||||
golden_images.append(golden_image_path)
|
||||
|
||||
expected_lines = ["Light component tests completed."]
|
||||
expected_lines = ["spot_light Controller|Configuration|Shadows|Shadowmap size: SUCCESS"]
|
||||
unexpected_lines = [
|
||||
"Trace::Assert",
|
||||
"Trace::Error",
|
||||
@@ -220,20 +222,20 @@ class TestPerformanceBenchmarkSuite(object):
|
||||
@pytest.mark.system
|
||||
class TestMaterialEditor(object):
|
||||
|
||||
@pytest.mark.parametrize("cfg_args", ["-rhi=dx12", "-rhi=Vulkan"])
|
||||
@pytest.mark.parametrize("cfg_args,expected_lines", [
|
||||
pytest.param("-rhi=dx12", ["Registering dx12 RHI"]),
|
||||
pytest.param("-rhi=Vulkan", ["Registering vulkan RHI"])
|
||||
])
|
||||
@pytest.mark.parametrize("exe_file_name", ["MaterialEditor"])
|
||||
@pytest.mark.test_case_id("C30973986") # Material Editor Launching in Dx12
|
||||
@pytest.mark.test_case_id("C30973987") # Material Editor Launching in Vulkan
|
||||
def test_MaterialEditorLaunch_AllRHIOptionsSucceed(
|
||||
self, request, workspace, project, launcher_platform, generic_launcher, exe_file_name, cfg_args):
|
||||
self, request, workspace, project, launcher_platform, generic_launcher, exe_file_name, cfg_args,
|
||||
expected_lines):
|
||||
"""
|
||||
Tests each valid RHI option (Null RHI excluded) can be launched with the MaterialEditor.
|
||||
Checks for the "Finished loading viewport configurations." success message post launch.
|
||||
Checks for the specific expected_lines messaging for each RHI type.
|
||||
"""
|
||||
expected_lines = ["Finished loading viewport configurations."]
|
||||
unexpected_lines = [
|
||||
# "Trace::Assert",
|
||||
# "Trace::Error",
|
||||
"Traceback (most recent call last):",
|
||||
]
|
||||
|
||||
hydra.launch_and_validate_results(
|
||||
request,
|
||||
@@ -243,7 +245,7 @@ class TestMaterialEditor(object):
|
||||
run_python="--runpython",
|
||||
timeout=60,
|
||||
expected_lines=expected_lines,
|
||||
unexpected_lines=unexpected_lines,
|
||||
unexpected_lines=[],
|
||||
halt_on_unexpected=False,
|
||||
null_renderer=False,
|
||||
cfg_args=[cfg_args],
|
||||
|
||||
@@ -23,6 +23,7 @@ class TestAutomation(EditorTestSuite):
|
||||
# Remove -autotest_mode from global_extra_cmdline_args since we need rendering for these tests.
|
||||
global_extra_cmdline_args = ["-BatchMode"] # Default is ["-BatchMode", "-autotest_mode"]
|
||||
|
||||
@pytest.mark.test_case_id("C34603773")
|
||||
class AtomGPU_BasicLevelSetup_SetsUpLevel(EditorSharedTest):
|
||||
use_null_renderer = False # Default is True
|
||||
screenshot_name = "AtomBasicLevelSetup.ppm"
|
||||
|
||||
@@ -59,5 +59,17 @@ class TestAutomation(EditorTestSuite):
|
||||
class AtomEditorComponents_MeshAdded(EditorSharedTest):
|
||||
from Atom.tests import hydra_AtomEditorComponents_MeshAdded as test_module
|
||||
|
||||
@pytest.mark.test_case_id("C32078123")
|
||||
class AtomEditorComponents_MaterialAdded(EditorSharedTest):
|
||||
from Atom.tests import hydra_AtomEditorComponents_MaterialAdded as test_module
|
||||
|
||||
@pytest.mark.test_case_id("C32078127")
|
||||
class AtomEditorComponents_PostFXLayerAdded(EditorSharedTest):
|
||||
from Atom.tests import hydra_AtomEditorComponents_PostFXLayerAdded as test_module
|
||||
|
||||
@pytest.mark.test_case_id("C36525665")
|
||||
class AtomEditorComponents_PostFXShapeWeightModifierAdded(EditorSharedTest):
|
||||
from Atom.tests import hydra_AtomEditorComponents_PostFxShapeWeightModifierAdded as test_module
|
||||
|
||||
class ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges(EditorSharedTest):
|
||||
from Atom.tests import hydra_ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges as test_module
|
||||
|
||||
@@ -3,12 +3,17 @@ 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
|
||||
|
||||
Sandbox suite tests for the Atom renderer.
|
||||
"""
|
||||
import logging
|
||||
import os
|
||||
|
||||
import pytest
|
||||
|
||||
import editor_python_test_tools.hydra_test_utils as hydra
|
||||
|
||||
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'])
|
||||
@@ -18,3 +23,50 @@ class TestAtomEditorComponentsSandbox(object):
|
||||
# It requires at least one test
|
||||
def test_Dummy(self, request, editor, level, workspace, project, launcher_platform):
|
||||
pass
|
||||
|
||||
@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("C32078128")
|
||||
def test_AtomEditorComponents_ReflectionProbeAddedToEntity(
|
||||
self, request, editor, level, workspace, project, launcher_platform):
|
||||
"""
|
||||
Please review the hydra script run by this test for more specific test info.
|
||||
Tests the following Atom components and verifies all "expected_lines" appear in Editor.log:
|
||||
1. Reflection Probe
|
||||
"""
|
||||
cfg_args = [level]
|
||||
|
||||
expected_lines = [
|
||||
# Reflection Probe Component
|
||||
"Reflection Probe Entity successfully created",
|
||||
"Reflection Probe_test: Component added to the entity: True",
|
||||
"Reflection Probe_test: Component removed after UNDO: True",
|
||||
"Reflection Probe_test: Component added after REDO: True",
|
||||
"Reflection Probe_test: Entered game mode: True",
|
||||
"Reflection Probe_test: Exit game mode: True",
|
||||
"Reflection Probe_test: Entity disabled initially: True",
|
||||
"Reflection Probe_test: Entity enabled after adding required components: True",
|
||||
"Reflection Probe_test: Cubemap is generated: True",
|
||||
"Reflection Probe_test: Entity is hidden: True",
|
||||
"Reflection Probe_test: Entity is shown: True",
|
||||
"Reflection Probe_test: Entity deleted: True",
|
||||
"Reflection Probe_test: UNDO entity deletion works: True",
|
||||
"Reflection Probe_test: REDO entity deletion works: True",
|
||||
]
|
||||
|
||||
hydra.launch_and_validate_results(
|
||||
request,
|
||||
TEST_DIRECTORY,
|
||||
editor,
|
||||
"hydra_AtomEditorComponents_AddedToEntity.py",
|
||||
timeout=120,
|
||||
expected_lines=expected_lines,
|
||||
unexpected_lines=[],
|
||||
halt_on_unexpected=True,
|
||||
null_renderer=True,
|
||||
cfg_args=cfg_args,
|
||||
)
|
||||
|
||||
@@ -113,7 +113,6 @@ def create_basic_atom_level(level_name):
|
||||
general.close_pane("Error Log")
|
||||
general.idle_wait(1.0)
|
||||
general.run_console("r_displayInfo=0")
|
||||
general.run_console("r_antialiasingmode=0")
|
||||
general.idle_wait(1.0)
|
||||
|
||||
# Delete all existing entities & create default_level entity
|
||||
|
||||
+205
@@ -0,0 +1,205 @@
|
||||
"""
|
||||
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
|
||||
"""
|
||||
|
||||
class Tests:
|
||||
creation_undo = (
|
||||
"UNDO Entity creation success",
|
||||
"UNDO Entity creation failed")
|
||||
creation_redo = (
|
||||
"REDO Entity creation success",
|
||||
"REDO Entity creation failed")
|
||||
material_creation = (
|
||||
"Material Entity successfully created",
|
||||
"Material Entity failed to be created")
|
||||
material_component = (
|
||||
"Entity has a Material component",
|
||||
"Entity failed to find Material component")
|
||||
material_disabled = (
|
||||
"Material component disabled",
|
||||
"Material component was not disabled.")
|
||||
actor_component = (
|
||||
"Entity has an Actor component",
|
||||
"Entity did not have an Actor component")
|
||||
actor_undo = (
|
||||
"Entity Actor component gone",
|
||||
"Entity Actor component add failed to undo")
|
||||
mesh_component = (
|
||||
"Entity has a Mesh component",
|
||||
"Entity did not have a Mesh component")
|
||||
material_enabled = (
|
||||
"Material component enabled",
|
||||
"Material component was not enabled.")
|
||||
enter_game_mode = (
|
||||
"Entered game mode",
|
||||
"Failed to enter game mode")
|
||||
exit_game_mode = (
|
||||
"Exited game mode",
|
||||
"Couldn't exit game mode")
|
||||
is_visible = (
|
||||
"Entity is visible",
|
||||
"Entity was not visible")
|
||||
is_hidden = (
|
||||
"Entity is hidden",
|
||||
"Entity was not hidden")
|
||||
entity_deleted = (
|
||||
"Entity deleted",
|
||||
"Entity was not deleted")
|
||||
deletion_undo = (
|
||||
"UNDO deletion success",
|
||||
"UNDO deletion failed")
|
||||
deletion_redo = (
|
||||
"REDO deletion success",
|
||||
"REDO deletion failed")
|
||||
|
||||
|
||||
def AtomEditorComponents_Material_AddedToEntity():
|
||||
"""
|
||||
Summary:
|
||||
Tests the Material component can be added to an entity and has the expected functionality.
|
||||
|
||||
Test setup:
|
||||
- Wait for Editor idle loop.
|
||||
- Open the "Base" level.
|
||||
|
||||
Expected Behavior:
|
||||
The component can be added, used in game mode, hidden/shown, deleted, and has accurate required components.
|
||||
Creation and deletion undo/redo should also work.
|
||||
|
||||
Test Steps:
|
||||
1) Create a Material entity with no components.
|
||||
2) Add a Material component to Material entity.
|
||||
3) UNDO the entity creation and component addition.
|
||||
4) REDO the entity creation and component addition.
|
||||
5) Verify Material component not enabled.
|
||||
6) Add Actor component since it is required by the Material component.
|
||||
7) Verify Material component is enabled.
|
||||
8) UNDO add Actor component
|
||||
9) Verify Material component not enabled.
|
||||
10) Add Mesh component since it is required by the Material component.
|
||||
11) Verify Material component is enabled.
|
||||
12) Enter/Exit game mode.
|
||||
13) Test IsHidden.
|
||||
14) Test IsVisible.
|
||||
15) Delete Material entity.
|
||||
16) UNDO deletion.
|
||||
17) REDO deletion.
|
||||
18) Look for errors.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
|
||||
import azlmbr.legacy.general as general
|
||||
|
||||
from editor_python_test_tools.editor_entity_utils import EditorEntity
|
||||
from editor_python_test_tools.utils import Report, Tracer, TestHelper
|
||||
|
||||
with Tracer() as error_tracer:
|
||||
# Test setup begins.
|
||||
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
|
||||
TestHelper.init_idle()
|
||||
TestHelper.open_level("", "Base")
|
||||
|
||||
# Test steps begin.
|
||||
# 1. Create a Material entity with no components.
|
||||
material_name = "Material"
|
||||
material_entity = EditorEntity.create_editor_entity(material_name)
|
||||
Report.critical_result(Tests.material_creation, material_entity.exists())
|
||||
|
||||
# 2. Add a Material component to Material entity.
|
||||
material_component = material_entity.add_component(material_name)
|
||||
Report.critical_result(
|
||||
Tests.material_component,
|
||||
material_entity.has_component(material_name))
|
||||
|
||||
# 3. UNDO the entity creation and component addition.
|
||||
# -> UNDO component addition.
|
||||
general.undo()
|
||||
# -> UNDO naming entity.
|
||||
general.undo()
|
||||
# -> UNDO selecting entity.
|
||||
general.undo()
|
||||
# -> UNDO entity creation.
|
||||
general.undo()
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.creation_undo, not material_entity.exists())
|
||||
|
||||
# 4. REDO the entity creation and component addition.
|
||||
# -> REDO entity creation.
|
||||
general.redo()
|
||||
# -> REDO selecting entity.
|
||||
general.redo()
|
||||
# -> REDO naming entity.
|
||||
general.redo()
|
||||
# -> REDO component addition.
|
||||
general.redo()
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.creation_redo, material_entity.exists())
|
||||
|
||||
# 5. Verify Material component not enabled.
|
||||
Report.result(Tests.material_disabled, not material_component.is_enabled())
|
||||
|
||||
# 6. Add Actor component since it is required by the Material component.
|
||||
actor_name = "Actor"
|
||||
material_entity.add_component(actor_name)
|
||||
Report.result(Tests.actor_component, material_entity.has_component(actor_name))
|
||||
|
||||
# 7. Verify Material component is enabled.
|
||||
Report.result(Tests.material_enabled, material_component.is_enabled())
|
||||
|
||||
# 8. UNDO component addition.
|
||||
general.undo()
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.actor_undo, not material_entity.has_component(actor_name))
|
||||
|
||||
# 9. Verify Material component not enabled.
|
||||
Report.result(Tests.material_disabled, not material_component.is_enabled())
|
||||
|
||||
# 10. Add Mesh component since it is required by the Material component.
|
||||
mesh_name = "Mesh"
|
||||
material_entity.add_component(mesh_name)
|
||||
Report.result(Tests.mesh_component, material_entity.has_component(mesh_name))
|
||||
|
||||
# 11. Verify Material component is enabled.
|
||||
Report.result(Tests.material_enabled, material_component.is_enabled())
|
||||
|
||||
# 12. Enter/Exit game mode.
|
||||
TestHelper.enter_game_mode(Tests.enter_game_mode)
|
||||
general.idle_wait_frames(1)
|
||||
TestHelper.exit_game_mode(Tests.exit_game_mode)
|
||||
|
||||
# 13. Test IsHidden.
|
||||
material_entity.set_visibility_state(False)
|
||||
Report.result(Tests.is_hidden, material_entity.is_hidden() is True)
|
||||
|
||||
# 14. Test IsVisible.
|
||||
material_entity.set_visibility_state(True)
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.is_visible, material_entity.is_visible() is True)
|
||||
|
||||
# 15. Delete Material entity.
|
||||
material_entity.delete()
|
||||
Report.result(Tests.entity_deleted, not material_entity.exists())
|
||||
|
||||
# 16. UNDO deletion.
|
||||
general.undo()
|
||||
Report.result(Tests.deletion_undo, material_entity.exists())
|
||||
|
||||
# 17. REDO deletion.
|
||||
general.redo()
|
||||
Report.result(Tests.deletion_redo, not material_entity.exists())
|
||||
|
||||
# 18. Look for errors or asserts.
|
||||
TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
|
||||
for error_info in error_tracer.errors:
|
||||
Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
|
||||
for assert_info in error_tracer.asserts:
|
||||
Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(AtomEditorComponents_Material_AddedToEntity)
|
||||
+156
@@ -0,0 +1,156 @@
|
||||
"""
|
||||
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
|
||||
"""
|
||||
|
||||
class Tests:
|
||||
creation_undo = (
|
||||
"UNDO Entity creation success",
|
||||
"UNDO Entity creation failed")
|
||||
creation_redo = (
|
||||
"REDO Entity creation success",
|
||||
"REDO Entity creation failed")
|
||||
postfx_layer_entity_creation = (
|
||||
"PostFX Layer Entity successfully created",
|
||||
"PostFX Layer Entity failed to be created")
|
||||
postfx_layer_component_added = (
|
||||
"Entity has a PostFX Layer component",
|
||||
"Entity failed to find PostFX Layer component")
|
||||
enter_game_mode = (
|
||||
"Entered game mode",
|
||||
"Failed to enter game mode")
|
||||
exit_game_mode = (
|
||||
"Exited game mode",
|
||||
"Couldn't exit game mode")
|
||||
is_visible = (
|
||||
"Entity is visible",
|
||||
"Entity was not visible")
|
||||
is_hidden = (
|
||||
"Entity is hidden",
|
||||
"Entity was not hidden")
|
||||
entity_deleted = (
|
||||
"Entity deleted",
|
||||
"Entity was not deleted")
|
||||
deletion_undo = (
|
||||
"UNDO deletion success",
|
||||
"UNDO deletion failed")
|
||||
deletion_redo = (
|
||||
"REDO deletion success",
|
||||
"REDO deletion failed")
|
||||
|
||||
|
||||
def AtomEditorComponents_postfx_layer_AddedToEntity():
|
||||
"""
|
||||
Summary:
|
||||
Tests the PostFX Layer component can be added to an entity and has the expected functionality.
|
||||
|
||||
Test setup:
|
||||
- Wait for Editor idle loop.
|
||||
- Open the "Base" level.
|
||||
|
||||
Expected Behavior:
|
||||
The component can be added, used in game mode, hidden/shown, deleted, and has accurate required components.
|
||||
Creation and deletion undo/redo should also work.
|
||||
|
||||
Test Steps:
|
||||
1) Create a PostFX Layer entity with no components.
|
||||
2) Add a PostFX Layer component to PostFX Layer entity.
|
||||
3) UNDO the entity creation and component addition.
|
||||
4) REDO the entity creation and component addition.
|
||||
5) Enter/Exit game mode.
|
||||
6) Test IsHidden.
|
||||
7) Test IsVisible.
|
||||
8) Delete PostFX Layer entity.
|
||||
9) UNDO deletion.
|
||||
10) REDO deletion.
|
||||
11) Look for errors.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
import azlmbr.legacy.general as general
|
||||
|
||||
from editor_python_test_tools.editor_entity_utils import EditorEntity
|
||||
from editor_python_test_tools.utils import Report, Tracer, TestHelper
|
||||
|
||||
with Tracer() as error_tracer:
|
||||
# Test setup begins.
|
||||
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
|
||||
TestHelper.init_idle()
|
||||
TestHelper.open_level("", "Base")
|
||||
|
||||
# Test steps begin.
|
||||
# 1. Create a PostFX Layer entity with no components.
|
||||
postfx_layer_name = "PostFX Layer"
|
||||
postfx_layer_entity = EditorEntity.create_editor_entity(postfx_layer_name)
|
||||
Report.critical_result(Tests.postfx_layer_entity_creation, postfx_layer_entity.exists())
|
||||
|
||||
# 2. Add a PostFX Layer component to PostFX Layer entity.
|
||||
postfx_layer_component = postfx_layer_entity.add_component(postfx_layer_name)
|
||||
Report.critical_result(Tests.postfx_layer_component_added, postfx_layer_entity.has_component(postfx_layer_name))
|
||||
|
||||
# 3. UNDO the entity creation and component addition.
|
||||
# -> UNDO component addition.
|
||||
general.undo()
|
||||
# -> UNDO naming entity.
|
||||
general.undo()
|
||||
# -> UNDO selecting entity.
|
||||
general.undo()
|
||||
# -> UNDO entity creation.
|
||||
general.undo()
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.creation_undo, not postfx_layer_entity.exists())
|
||||
|
||||
# 4. REDO the entity creation and component addition.
|
||||
# -> REDO entity creation.
|
||||
general.redo()
|
||||
# -> REDO selecting entity.
|
||||
general.redo()
|
||||
# -> REDO naming entity.
|
||||
general.redo()
|
||||
# -> REDO component addition.
|
||||
general.redo()
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.creation_redo, postfx_layer_entity.exists())
|
||||
|
||||
# 5. Enter/Exit game mode.
|
||||
TestHelper.enter_game_mode(Tests.enter_game_mode)
|
||||
general.idle_wait_frames(1)
|
||||
TestHelper.exit_game_mode(Tests.exit_game_mode)
|
||||
|
||||
# 6. Test IsHidden.
|
||||
postfx_layer_entity.set_visibility_state(False)
|
||||
Report.result(Tests.is_hidden, postfx_layer_entity.is_hidden() is True)
|
||||
|
||||
# 7. Test IsVisible.
|
||||
postfx_layer_entity.set_visibility_state(True)
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.is_visible, postfx_layer_entity.is_visible() is True)
|
||||
|
||||
# 8. Delete PostFX Layer entity.
|
||||
postfx_layer_entity.delete()
|
||||
Report.result(Tests.entity_deleted, not postfx_layer_entity.exists())
|
||||
|
||||
# 9. UNDO deletion.
|
||||
general.undo()
|
||||
Report.result(Tests.deletion_undo, postfx_layer_entity.exists())
|
||||
|
||||
# 10. REDO deletion.
|
||||
general.redo()
|
||||
Report.result(Tests.deletion_redo, not postfx_layer_entity.exists())
|
||||
|
||||
# 11. Look for errors or asserts.
|
||||
TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
|
||||
for error_info in error_tracer.errors:
|
||||
Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
|
||||
for assert_info in error_tracer.asserts:
|
||||
Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(AtomEditorComponents_postfx_layer_AddedToEntity)
|
||||
+207
@@ -0,0 +1,207 @@
|
||||
"""
|
||||
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
|
||||
"""
|
||||
|
||||
class Tests:
|
||||
creation_undo = (
|
||||
"UNDO Entity creation success",
|
||||
"UNDO Entity creation failed")
|
||||
creation_redo = (
|
||||
"REDO Entity creation success",
|
||||
"REDO Entity creation failed")
|
||||
postfx_shape_weight_creation = (
|
||||
"PostFx Shape Weight Modifier Entity successfully created",
|
||||
"PostFx Shape Weight Modifier Entity failed to be created")
|
||||
postfx_shape_weight_component = (
|
||||
"Entity has a PostFx Shape Weight Modifier component",
|
||||
"Entity failed to find PostFx Shape Weight Modifier component")
|
||||
postfx_shape_weight_disabled = (
|
||||
"PostFx Shape Weight Modifier component disabled",
|
||||
"PostFx Shape Weight Modifier component was not disabled.")
|
||||
postfx_layer_component = (
|
||||
"Entity has a PostFX Layer component",
|
||||
"Entity did not have an PostFX Layer component")
|
||||
tube_shape_component = (
|
||||
"Entity has a Tube Shape component",
|
||||
"Entity did not have a Tube Shape component")
|
||||
postfx_shape_weight_enabled = (
|
||||
"PostFx Shape Weight Modifier component enabled",
|
||||
"PostFx Shape Weight Modifier component was not enabled.")
|
||||
enter_game_mode = (
|
||||
"Entered game mode",
|
||||
"Failed to enter game mode")
|
||||
exit_game_mode = (
|
||||
"Exited game mode",
|
||||
"Couldn't exit game mode")
|
||||
is_visible = (
|
||||
"Entity is visible",
|
||||
"Entity was not visible")
|
||||
is_hidden = (
|
||||
"Entity is hidden",
|
||||
"Entity was not hidden")
|
||||
entity_deleted = (
|
||||
"Entity deleted",
|
||||
"Entity was not deleted")
|
||||
deletion_undo = (
|
||||
"UNDO deletion success",
|
||||
"UNDO deletion failed")
|
||||
deletion_redo = (
|
||||
"REDO deletion success",
|
||||
"REDO deletion failed")
|
||||
|
||||
|
||||
def AtomEditorComponents_postfx_shape_weight_AddedToEntity():
|
||||
"""
|
||||
Summary:
|
||||
Tests the PostFx Shape Weight Modifier component can be added to an entity and has the expected functionality.
|
||||
|
||||
Test setup:
|
||||
- Wait for Editor idle loop.
|
||||
- Open the "Base" level.
|
||||
|
||||
Expected Behavior:
|
||||
The component can be added, used in game mode, hidden/shown, deleted, and has accurate required components.
|
||||
Creation and deletion undo/redo should also work.
|
||||
|
||||
Test Steps:
|
||||
1) Create a PostFx Shape Weight Modifier entity with no components.
|
||||
2) Add a PostFx Shape Weight Modifier component to PostFx Shape Weight Modifier entity.
|
||||
3) UNDO the entity creation and component addition.
|
||||
4) REDO the entity creation and component addition.
|
||||
5) Verify PostFx Shape Weight Modifier component not enabled.
|
||||
6) Add PostFX Layer component since it is required by the PostFx Shape Weight Modifier component.
|
||||
7) Verify PostFx Shape Weight Modifier component is NOT enabled since it also requires a shape.
|
||||
8) Add a required shape looping over a list and checking if it enables PostFX Shape Weight Modifier.
|
||||
9) Undo to remove each added shape and verify PostFX Shape Weight Modifier is not enabled.
|
||||
10) Verify PostFx Shape Weight Modifier component is enabled by adding Spline and Tube Shape component.
|
||||
11) Enter/Exit game mode.
|
||||
12) Test IsHidden.
|
||||
13) Test IsVisible.
|
||||
14) Delete PostFx Shape Weight Modifier entity.
|
||||
15) UNDO deletion.
|
||||
16) REDO deletion.
|
||||
17) Look for errors.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
|
||||
import azlmbr.legacy.general as general
|
||||
|
||||
from editor_python_test_tools.editor_entity_utils import EditorEntity
|
||||
from editor_python_test_tools.utils import Report, Tracer, TestHelper
|
||||
|
||||
with Tracer() as error_tracer:
|
||||
# Test setup begins.
|
||||
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
|
||||
TestHelper.init_idle()
|
||||
TestHelper.open_level("", "Base")
|
||||
|
||||
# Test steps begin.
|
||||
# 1. Create a PostFx Shape Weight Modifier entity with no components.
|
||||
postfx_shape_weight_name = "PostFX Shape Weight Modifier"
|
||||
postfx_shape_weight_entity = EditorEntity.create_editor_entity(postfx_shape_weight_name)
|
||||
Report.critical_result(Tests.postfx_shape_weight_creation, postfx_shape_weight_entity.exists())
|
||||
|
||||
# 2. Add a PostFx Shape Weight Modifier component to PostFx Shape Weight Modifier entity.
|
||||
postfx_shape_weight_component = postfx_shape_weight_entity.add_component(postfx_shape_weight_name)
|
||||
Report.critical_result(
|
||||
Tests.postfx_shape_weight_component,
|
||||
postfx_shape_weight_entity.has_component(postfx_shape_weight_name))
|
||||
|
||||
# 3. UNDO the entity creation and component addition.
|
||||
# -> UNDO component addition.
|
||||
general.undo()
|
||||
# -> UNDO naming entity.
|
||||
general.undo()
|
||||
# -> UNDO selecting entity.
|
||||
general.undo()
|
||||
# -> UNDO entity creation.
|
||||
general.undo()
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.creation_undo, not postfx_shape_weight_entity.exists())
|
||||
|
||||
# 4. REDO the entity creation and component addition.
|
||||
# -> REDO entity creation.
|
||||
general.redo()
|
||||
# -> REDO selecting entity.
|
||||
general.redo()
|
||||
# -> REDO naming entity.
|
||||
general.redo()
|
||||
# -> REDO component addition.
|
||||
general.redo()
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.creation_redo, postfx_shape_weight_entity.exists())
|
||||
|
||||
# 5. Verify PostFx Shape Weight Modifier component not enabled.
|
||||
Report.result(Tests.postfx_shape_weight_disabled, not postfx_shape_weight_component.is_enabled())
|
||||
|
||||
# 6. Add PostFX Layer component since it is required by the PostFx Shape Weight Modifier component.
|
||||
postfx_layer_name = "PostFX Layer"
|
||||
postfx_shape_weight_entity.add_component(postfx_layer_name)
|
||||
Report.result(Tests.postfx_layer_component, postfx_shape_weight_entity.has_component(postfx_layer_name))
|
||||
|
||||
# 7. Verify PostFx Shape Weight Modifier component is NOT enabled since it also requires a shape.
|
||||
Report.result(Tests.postfx_shape_weight_disabled, not postfx_shape_weight_component.is_enabled())
|
||||
|
||||
# 8. Add a required shape looping over a list and checking if it enables PostFX Shape Weight Modifier.
|
||||
for shape in ['Axis Aligned Box Shape', 'Box Shape', 'Capsule Shape', 'Compound Shape', 'Cylinder Shape',
|
||||
'Disk Shape', 'Polygon Prism Shape', 'Quad Shape', 'Sphere Shape', 'Vegetation Reference Shape']:
|
||||
postfx_shape_weight_entity.add_component(shape)
|
||||
test_shape = (
|
||||
f"Entity has a {shape} component",
|
||||
f"Entity did not have a {shape} component")
|
||||
Report.result(test_shape, postfx_shape_weight_entity.has_component(shape))
|
||||
|
||||
# Check if required shape allows PostFX Shape Weight Modifier to be enabled
|
||||
Report.result(Tests.postfx_shape_weight_enabled, postfx_shape_weight_component.is_enabled())
|
||||
|
||||
# 9. Undo to remove each added shape and verify PostFX Shape Weight Modifier is not enabled.
|
||||
general.undo()
|
||||
TestHelper.wait_for_condition(lambda: not postfx_shape_weight_entity.has_component(shape), 1.0)
|
||||
Report.result(Tests.postfx_shape_weight_disabled, not postfx_shape_weight_component.is_enabled())
|
||||
|
||||
# 10. Verify PostFx Shape Weight Modifier component is enabled by adding Spline and Tube Shape component.
|
||||
postfx_shape_weight_entity.add_components(['Spline', 'Tube Shape'])
|
||||
Report.result(Tests.tube_shape_component, postfx_shape_weight_entity.has_component('Tube Shape'))
|
||||
Report.result(Tests.postfx_shape_weight_enabled, postfx_shape_weight_component.is_enabled())
|
||||
|
||||
# 11. Enter/Exit game mode.
|
||||
TestHelper.enter_game_mode(Tests.enter_game_mode)
|
||||
general.idle_wait_frames(1)
|
||||
TestHelper.exit_game_mode(Tests.exit_game_mode)
|
||||
|
||||
# 12. Test IsHidden.
|
||||
postfx_shape_weight_entity.set_visibility_state(False)
|
||||
Report.result(Tests.is_hidden, postfx_shape_weight_entity.is_hidden() is True)
|
||||
|
||||
# 13. Test IsVisible.
|
||||
postfx_shape_weight_entity.set_visibility_state(True)
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.is_visible, postfx_shape_weight_entity.is_visible() is True)
|
||||
|
||||
# 14. Delete PostFx Shape Weight Modifier entity.
|
||||
postfx_shape_weight_entity.delete()
|
||||
Report.result(Tests.entity_deleted, not postfx_shape_weight_entity.exists())
|
||||
|
||||
# 15. UNDO deletion.
|
||||
general.undo()
|
||||
Report.result(Tests.deletion_undo, postfx_shape_weight_entity.exists())
|
||||
|
||||
# 16. REDO deletion.
|
||||
general.redo()
|
||||
Report.result(Tests.deletion_redo, not postfx_shape_weight_entity.exists())
|
||||
|
||||
# 17. Look for errors or asserts.
|
||||
TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
|
||||
for error_info in error_tracer.errors:
|
||||
Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
|
||||
for assert_info in error_tracer.asserts:
|
||||
Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(AtomEditorComponents_postfx_shape_weight_AddedToEntity)
|
||||
-1
@@ -66,7 +66,6 @@ def run():
|
||||
general.close_pane("Error Log")
|
||||
general.idle_wait(1.0)
|
||||
general.run_console("r_displayInfo=0")
|
||||
general.run_console("r_antialiasingmode=0")
|
||||
general.idle_wait(1.0)
|
||||
|
||||
return True
|
||||
|
||||
@@ -82,7 +82,6 @@ def run():
|
||||
general.close_pane("Error Log")
|
||||
general.idle_wait(1.0)
|
||||
general.run_console("r_displayInfo=0")
|
||||
general.run_console("r_antialiasingmode=0")
|
||||
general.idle_wait(1.0)
|
||||
|
||||
return True
|
||||
|
||||
-1
@@ -149,7 +149,6 @@ class TestHelper:
|
||||
general.idle_wait(1.0)
|
||||
general.idle_wait(1.0)
|
||||
general.run_console("r_displayInfo=0")
|
||||
general.run_console("r_antialiasingmode=0")
|
||||
general.idle_wait(1.0)
|
||||
|
||||
|
||||
|
||||
@@ -525,10 +525,6 @@ class TestAutomation(TestAutomationBase):
|
||||
from .tests.joints import Joints_BallNoLimitsConstrained as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_Joints_FixedLeadFollowerCollide(self, request, workspace, editor, launcher_platform):
|
||||
from .tests.joints import Joints_FixedLeadFollowerCollide as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_Joints_GlobalFrameConstrained(self, request, workspace, editor, launcher_platform):
|
||||
from .tests.joints import Joints_GlobalFrameConstrained as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
+1
-1
@@ -82,7 +82,7 @@ def ForceRegion_SplineRegionWithModifiedTransform():
|
||||
import azlmbr.bus as bus
|
||||
|
||||
# region Constants
|
||||
TIMEOUT = 5.0
|
||||
TIMEOUT = 10.0
|
||||
MIN_TRIGGER_DISTANCE = 2.0
|
||||
# endregion
|
||||
|
||||
|
||||
+1
-1
@@ -77,7 +77,7 @@ def ForceRegion_ZeroPointForceDoesNothing():
|
||||
|
||||
helper.init_idle()
|
||||
|
||||
TIMEOUT_SECONDS = 3.0
|
||||
TIMEOUT_SECONDS = 5.0
|
||||
X_Y_Z_TOLERANCE = 1.5
|
||||
REGION_HEIGHT = 3.0
|
||||
TERRAIN_HEIGHT = 32.0
|
||||
|
||||
@@ -45,8 +45,13 @@ class JointEntity:
|
||||
# Entity class that sets a flag when an instance receives collision events.
|
||||
class JointEntityCollisionAware(JointEntity):
|
||||
def on_collision_begin(self, args):
|
||||
if not self.collided:
|
||||
self.collided = True
|
||||
self.collided = True
|
||||
|
||||
def on_collision_persist(self, args):
|
||||
self.collided = True
|
||||
|
||||
def on_collision_end(self, args):
|
||||
self.collided = True
|
||||
|
||||
def __init__(self, name):
|
||||
self.id = general.find_game_entity(name)
|
||||
@@ -58,3 +63,5 @@ class JointEntityCollisionAware(JointEntity):
|
||||
self.handler = azlmbr.physics.CollisionNotificationBusHandler()
|
||||
self.handler.connect(self.id)
|
||||
self.handler.add_callback("OnCollisionBegin", self.on_collision_begin)
|
||||
self.handler.add_callback("OnCollisionPresist", self.on_collision_persist)
|
||||
self.handler.add_callback("OnCollisionEnd", self.on_collision_end)
|
||||
|
||||
+3
-11
@@ -52,9 +52,6 @@ def Joints_BallLeadFollowerCollide():
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.bus
|
||||
|
||||
from JointsHelper import JointEntityCollisionAware
|
||||
|
||||
# Helper Entity class - self.collided flag is set when instance receives collision event.
|
||||
@@ -75,17 +72,12 @@ def Joints_BallLeadFollowerCollide():
|
||||
lead = Entity("lead")
|
||||
follower = Entity("follower")
|
||||
|
||||
# 4) Wait for several seconds
|
||||
general.idle_wait(2.0) # wait for lead and follower to move
|
||||
# 4) Wait for collision between lead and follower or timeout
|
||||
Report.critical_result(Tests.check_collision_happened, helper.wait_for_condition(lambda: lead.collided and follower.collided, 10.0))
|
||||
|
||||
# 5) Check to see if lead and follower behaved as expected
|
||||
Report.critical_result(Tests.check_collision_happened, lead.collided and follower.collided)
|
||||
|
||||
# 6) Exit Game Mode
|
||||
# 5) Exit Game Mode
|
||||
helper.exit_game_mode(Tests.exit_game_mode)
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(Joints_BallLeadFollowerCollide)
|
||||
|
||||
-92
@@ -1,92 +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 ID : C18243582
|
||||
# Test Case Title : Check that fixed joint allows lead-follower collision
|
||||
|
||||
|
||||
# fmt: off
|
||||
class Tests:
|
||||
enter_game_mode = ("Entered game mode", "Failed to enter game mode")
|
||||
exit_game_mode = ("Exited game mode", "Couldn't exit game mode")
|
||||
lead_found = ("Found lead", "Did not find lead")
|
||||
follower_found = ("Found follower", "Did not find follower")
|
||||
check_collision_happened = ("Lead and follower collided", "Lead and follower did not collide")
|
||||
# fmt: on
|
||||
|
||||
|
||||
def Joints_FixedLeadFollowerCollide():
|
||||
"""
|
||||
Summary: Check that fixed joint allows lead-follower collision
|
||||
|
||||
Level Description:
|
||||
lead - Starts above follower entity
|
||||
follower - Starts below lead entity. Constrained to lead entity with fixed joint. Starts with initial velocity of (5, 0, 0) in positive X direction.
|
||||
|
||||
Expected Behavior:
|
||||
The follower entity moves in the positive X direction and the lead entity is dragged along towards the positive X direction.
|
||||
The x position of the lead entity is incremented from its original.
|
||||
The lead and follower entities are kept apart at a distance of approximately 1.0 due to collision.
|
||||
|
||||
Test Steps:
|
||||
1) Open Level
|
||||
2) Enter Game Mode
|
||||
3) Create and Validate Entities
|
||||
4) Wait for several seconds
|
||||
5) Check to see if lead and follower behaved as expected.
|
||||
6) Exit Game Mode
|
||||
7) Close Editor
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.bus
|
||||
|
||||
from JointsHelper import JointEntityCollisionAware
|
||||
|
||||
# Helper Entity class - self.collided flag is set when instance receives collision event.
|
||||
class Entity(JointEntityCollisionAware):
|
||||
def criticalEntityFound(self): # Override function to use local Test dictionary
|
||||
Report.critical_result(Tests.__dict__[self.name + "_found"], self.id.isValid())
|
||||
|
||||
# Main Script
|
||||
helper.init_idle()
|
||||
|
||||
# 1) Open Level
|
||||
helper.open_level("Physics", "Joints_FixedLeadFollowerCollide")
|
||||
|
||||
# 2) Enter Game Mode
|
||||
helper.enter_game_mode(Tests.enter_game_mode)
|
||||
|
||||
# 3) Create and Validate Entities
|
||||
lead = Entity("lead")
|
||||
follower = Entity("follower")
|
||||
|
||||
# 4) Wait for several seconds
|
||||
general.idle_wait(2.0) # wait for lead and follower to move
|
||||
|
||||
# 5) Check to see if lead entity and follower collided
|
||||
Report.critical_result(Tests.check_collision_happened, lead.collided and follower.collided)
|
||||
|
||||
# 6) Exit Game Mode
|
||||
helper.exit_game_mode(Tests.exit_game_mode)
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(Joints_FixedLeadFollowerCollide)
|
||||
+49
-10
@@ -52,11 +52,13 @@ def Joints_HingeNoLimitsConstrained():
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import math
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.bus
|
||||
import azlmbr.math as azmath
|
||||
|
||||
import JointsHelper
|
||||
from JointsHelper import JointEntity
|
||||
@@ -84,28 +86,65 @@ def Joints_HingeNoLimitsConstrained():
|
||||
Report.info_vector3(lead.position, "lead initial position:")
|
||||
Report.info_vector3(follower.position, "follower initial position:")
|
||||
leadInitialPosition = lead.position
|
||||
followerInitialPosition = follower.position
|
||||
|
||||
# 4) Wait for several seconds
|
||||
general.idle_wait(4.0) # wait for lead and follower to move
|
||||
# 4) Wait for the follower to move above and over the lead or Timeout
|
||||
normalizedStartPos = JointsHelper.getRelativeVector(lead.position, follower.position)
|
||||
normalizedStartPos = normalizedStartPos.GetNormalizedSafe()
|
||||
|
||||
class WaitCondition:
|
||||
ANGLE_CHECKPOINT_1 = math.radians(90)
|
||||
ANGLE_CHECKPOINT_2 = math.radians(200)
|
||||
|
||||
angleAchieved = 0.0
|
||||
followerMovedAbove90Deg = False #this is expected to be true to pass the test
|
||||
followerMovedAbove200Deg = False #this is expected to be true to pass the test
|
||||
|
||||
jointNormal = azmath.Vector3(0.0, -1.0, 0.0) # the joint rotates around the y axis
|
||||
def checkConditionMet(self):
|
||||
#calculate the current follower-lead vector
|
||||
normalVec = JointsHelper.getRelativeVector(lead.position, follower.position)
|
||||
normalVec = normalVec.GetNormalizedSafe()
|
||||
|
||||
#triple product and get the angle
|
||||
tripleProduct = normalizedStartPos.dot(normalVec.cross(self.jointNormal))
|
||||
currentAngle = math.acos(normalizedStartPos.Dot(normalVec))
|
||||
if tripleProduct < 0:
|
||||
currentAngle = (2*math.pi) - currentAngle
|
||||
|
||||
#if the angle is now less then last time, it is no longer rising, so end the test.
|
||||
if currentAngle < self.angleAchieved:
|
||||
return True
|
||||
|
||||
#once we're passed the final check point, end the test
|
||||
if currentAngle > self.ANGLE_CHECKPOINT_2:
|
||||
self.followerMovedAbove200Deg = True
|
||||
return True
|
||||
|
||||
self.angleAchieved = currentAngle
|
||||
self.followerMovedAbove90Deg = currentAngle > self.ANGLE_CHECKPOINT_1
|
||||
return False
|
||||
|
||||
def isFollowerPositionCorrect(self):
|
||||
return self.followerMovedAbove90Deg and self.followerMovedAbove200Deg
|
||||
|
||||
waitCondition = WaitCondition()
|
||||
|
||||
MAX_WAIT_TIME = 10.0 #seconds
|
||||
conditionMet = helper.wait_for_condition(lambda: waitCondition.checkConditionMet(), MAX_WAIT_TIME)
|
||||
|
||||
# 5) Check to see if lead and follower behaved as expected
|
||||
Report.info_vector3(lead.position, "lead position after 1 second:")
|
||||
Report.info_vector3(follower.position, "follower position after 1 second:")
|
||||
Report.info_vector3(lead.position, "lead position after test run:")
|
||||
Report.info_vector3(follower.position, "follower position after test run:")
|
||||
|
||||
leadPositionDelta = lead.position.Subtract(leadInitialPosition)
|
||||
leadRemainedStill = JointsHelper.vector3SmallerThanScalar(leadPositionDelta, FLOAT_EPSILON)
|
||||
Report.critical_result(Tests.check_lead_position, leadRemainedStill)
|
||||
|
||||
followerSwingedOverLead = (follower.position.x < leadInitialPosition.x and
|
||||
follower.position.z > leadInitialPosition.z)
|
||||
Report.critical_result(Tests.check_follower_position, followerSwingedOverLead)
|
||||
Report.critical_result(Tests.check_follower_position, conditionMet and waitCondition.isFollowerPositionCorrect())
|
||||
|
||||
# 6) Exit Game Mode
|
||||
helper.exit_game_mode(Tests.exit_game_mode)
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(Joints_HingeNoLimitsConstrained)
|
||||
|
||||
+15
-15
@@ -80,6 +80,20 @@ def RigidBody_KinematicModeWorks():
|
||||
ramp_id = general.find_game_entity("Ramp")
|
||||
Report.result(Tests.find_ramp, ramp_id.IsValid())
|
||||
|
||||
# 2.1) setup collision handler
|
||||
class RampTouched:
|
||||
value = False
|
||||
|
||||
def on_collision_begin(args):
|
||||
other_id = args[0]
|
||||
if other_id.Equal(ramp_id):
|
||||
Report.info("Box touched ramp")
|
||||
RampTouched.value = True
|
||||
|
||||
handler = azlmbr.physics.CollisionNotificationBusHandler()
|
||||
handler.connect(box_id)
|
||||
handler.add_callback("OnCollisionBegin", on_collision_begin)
|
||||
|
||||
# 3) Check for kinematic ramp and not kinematic box
|
||||
box_kinematic = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "IsKinematic", box_id)
|
||||
Report.result(Tests.box_is_not_kinematic, not box_kinematic)
|
||||
@@ -98,21 +112,7 @@ def RigidBody_KinematicModeWorks():
|
||||
ramp_pos_start = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", ramp_id)
|
||||
Report.info("Ramp's initial position: {}".format(ramp_pos_start))
|
||||
|
||||
# 6) Check to see that the box hits the ramp
|
||||
class RampTouched:
|
||||
value = False
|
||||
|
||||
def on_collision_begin(args):
|
||||
other_id = args[0]
|
||||
if other_id.Equal(ramp_id):
|
||||
Report.info("Box touched ramp")
|
||||
RampTouched.value = True
|
||||
|
||||
handler = azlmbr.physics.CollisionNotificationBusHandler()
|
||||
handler.connect(box_id)
|
||||
handler.add_callback("OnCollisionBegin", on_collision_begin)
|
||||
|
||||
# 6.5) Wait for the box to touch the ramp or timeout
|
||||
# 6) Wait for the box to touch the ramp or timeout
|
||||
helper.wait_for_condition(lambda: RampTouched.value, TIME_OUT)
|
||||
Report.result(Tests.box_touched_ramp, RampTouched.value)
|
||||
|
||||
|
||||
-1
@@ -1 +0,0 @@
|
||||
/autooptimizefile=0 /preset=Terrain_Albedo_HighPassed /reduce=0
|
||||
@@ -187,7 +187,3 @@ def prepare_for_screenshot_compare(remote_console_instance):
|
||||
"""
|
||||
wait_for(lambda: _retry_command(remote_console_instance, 'r_displayinfo 0',
|
||||
'$3r_DisplayInfo = $60 $5[DUMPTODISK, RESTRICTEDMODE]$4'))
|
||||
wait_for(lambda: _retry_command(remote_console_instance, 'r_antialiasingmode 0',
|
||||
'$3r_AntialiasingMode = $60 $5[]$4'))
|
||||
wait_for(lambda: _retry_command(remote_console_instance, 'e_WaterOcean 0',
|
||||
'$3e_WaterOcean = $60 $5[]$4'))
|
||||
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
"""
|
||||
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
|
||||
"""
|
||||
|
||||
|
||||
class Tests:
|
||||
load_level = (
|
||||
"Level loaded successfully",
|
||||
"Failed to load the level"
|
||||
)
|
||||
create_entity = (
|
||||
"Parent entity created successfully",
|
||||
"Failed to create a parent entity"
|
||||
)
|
||||
set_entity_name = (
|
||||
"Entity name set successfully",
|
||||
"Failed to set entity name"
|
||||
)
|
||||
delete_entity = (
|
||||
"Parent Entity deleted successfully",
|
||||
"Failed to delete parent entity"
|
||||
)
|
||||
create_child_entity = (
|
||||
"Child entity created successfully",
|
||||
"Failed to create a child entity"
|
||||
)
|
||||
delete_child_entity = (
|
||||
"Child entity deleted successfully",
|
||||
"Failed to delete child entity"
|
||||
)
|
||||
add_mesh_component = (
|
||||
"Mesh component added successfully",
|
||||
"Failed to add mesh component"
|
||||
)
|
||||
found_component_typeId = (
|
||||
"Found component typeId",
|
||||
"Unable to find component TypeId"
|
||||
)
|
||||
remove_mesh_component = (
|
||||
"Mesh component removed successfully",
|
||||
"Failed to remove mesh component"
|
||||
)
|
||||
|
||||
|
||||
def BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD():
|
||||
"""
|
||||
Performing basic test in editor
|
||||
01. Load exiting level
|
||||
02. create parent entity and set name
|
||||
03. create child entity and set a name
|
||||
04. delete child entity
|
||||
05. add mesh component to parent entity
|
||||
06. delete parent entity
|
||||
"""
|
||||
|
||||
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)
|
||||
|
||||
# 02. create parent entity and set name
|
||||
# Delete any exiting entity and Create a new Entity at the root level
|
||||
search_filter = azlmbr.entity.SearchFilter()
|
||||
all_entities = entity.SearchBus(azlmbr.bus.Broadcast, "SearchEntities", search_filter)
|
||||
editor.ToolsApplicationRequestBus(bus.Broadcast, "DeleteEntities", all_entities)
|
||||
parent_entity = EditorEntity.create_editor_entity("Parent_1")
|
||||
Report.result(Tests.create_entity, parent_entity.exists())
|
||||
|
||||
# 03. Create child Entity to above created parent entity and set a name
|
||||
child_1_entity = EditorEntity.create_editor_entity("Child_1", parent_entity.id )
|
||||
Report.result(Tests.create_child_entity, child_1_entity.exists())
|
||||
|
||||
# 04. delete_Child_entity
|
||||
child_1_entity.delete()
|
||||
Report.result(Tests.delete_child_entity, not child_1_entity.exists())
|
||||
|
||||
# 05. add mesh component to parent entity
|
||||
parent_entity.add_component("Mesh")
|
||||
Report.result(Tests.add_mesh_component, parent_entity.has_component("Mesh"))
|
||||
|
||||
# 06. delete parent entity
|
||||
parent_entity.delete()
|
||||
Report.result(Tests.delete_entity, not parent_entity.exists())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from editor_python_test_tools.utils import Report
|
||||
|
||||
Report.start_test(BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD)
|
||||
@@ -73,3 +73,7 @@ class TestAutomationAutoTestMode(EditorTestSuite):
|
||||
@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
|
||||
|
||||
@@ -55,32 +55,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
|
||||
## LandscapeCanvas ##
|
||||
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::LandscapeCanvasTests_Main
|
||||
TEST_SERIAL
|
||||
TEST_SUITE main
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/landscape_canvas/TestSuite_Main.py
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
LargeWorlds
|
||||
)
|
||||
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::LandscapeCanvasTests_Periodic
|
||||
TEST_SERIAL
|
||||
TEST_SUITE periodic
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/landscape_canvas/TestSuite_Periodic.py
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
LargeWorlds
|
||||
)
|
||||
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::LandscapeCanvasTests_Main_Optimized
|
||||
TEST_SERIAL
|
||||
|
||||
-1
@@ -12,7 +12,6 @@ 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_periodic
|
||||
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
|
||||
@pytest.mark.parametrize("project", ["AutomatedTesting"])
|
||||
|
||||
Reference in New Issue
Block a user