Merge branch 'development' of https://github.com/o3de/o3de into cgalvan/RemovedUnusedViewPaneClass

monroegm-disable-blank-issue-2
Chris Galvan 4 years ago
commit cc6f687359

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:bfc2ef8c6dbf2fba078e27e4e94384099e090468e679327dd826a5cbf22b04ed
size 1019

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:708b12d41229afab78e0f7d59097ae3de855fea8525a920c5c214fc0ce79f1bd
size 1209

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:fab63af9b50790dca25330058e70517987ea8bf11c00f9353dd951ebdbd1dbe5
size 5008

File diff suppressed because it is too large Load Diff

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3789abdf439a6d70438fd4bb1e06881ae6686a4699209c6bc371d22d161e5347
size 26476

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c987d7d79685fda83efcffb7e1afbcd356c37fc68ec5c663a89b02d4df10caea
size 46412

@ -0,0 +1,15 @@
<?xml version="1.0"?>
<Component
Name="NetworkTestLevelEntityComponent"
Namespace="AutomatedTesting"
OverrideComponent="false"
OverrideController="false"
OverrideInclude=""
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ComponentRelation Constraint="Required" HasController="true" Name="NetworkTransformComponent" Namespace="Multiplayer" Include="Multiplayer/Components/NetworkTransformComponent.h" />
<RemoteProcedure Name="AuthorityToClientNoParams_PlayFx" InvokeFrom="Authority" HandleOn="Client" IsPublic="false" IsReliable="true" GenerateEventBindings="true" Description="" />
</Component>

@ -29,8 +29,6 @@
<Param Type="float" Name="SomeFloat" /> <Param Type="float" Name="SomeFloat" />
</RemoteProcedure> </RemoteProcedure>
<RemoteProcedure Name="AuthorityToClientNoParams_PlayFx" InvokeFrom="Authority" HandleOn="Client" IsPublic="false" IsReliable="true" GenerateEventBindings="true" Description="" />
<RemoteProcedure Name="ServerToAuthority_DealDamage" InvokeFrom="Server" HandleOn="Authority" IsPublic="false" IsReliable="true" GenerateEventBindings="true" Description="" > <RemoteProcedure Name="ServerToAuthority_DealDamage" InvokeFrom="Server" HandleOn="Authority" IsPublic="false" IsReliable="true" GenerateEventBindings="true" Description="" >
<Param Type="float" Name="damage" /> <Param Type="float" Name="damage" />
</RemoteProcedure> </RemoteProcedure>

@ -12,4 +12,5 @@ set(FILES
Source/AutomatedTestingSystemComponent.cpp Source/AutomatedTestingSystemComponent.cpp
Source/AutomatedTestingSystemComponent.h Source/AutomatedTestingSystemComponent.h
Source/AutoGen/NetworkTestPlayerComponent.AutoComponent.xml Source/AutoGen/NetworkTestPlayerComponent.AutoComponent.xml
Source/AutoGen/NetworkTestLevelEntityComponent.AutoComponent.xml
) )

@ -12,12 +12,6 @@
################################################################################ ################################################################################
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
# Only enable AWS automated tests on Windows
set(SUPPORTED_PLATFORMS "Windows" "Linux")
if (NOT "${PAL_PLATFORM_NAME}" IN_LIST SUPPORTED_PLATFORMS)
return()
endif()
ly_add_pytest( ly_add_pytest(
NAME AutomatedTesting::AWSTests NAME AutomatedTesting::AWSTests
TEST_SUITE awsi TEST_SUITE awsi

@ -3,7 +3,7 @@
## Prerequisites ## Prerequisites
1. Build the O3DE Editor and AutomatedTesting.GameLauncher in Profile. 1. Build the O3DE Editor and AutomatedTesting.GameLauncher in Profile.
2. Install the latest version of NodeJs. 2. Install the latest version of NodeJs.
3. AWS CLI is installed and configured following [Configuration and Credential File Settings](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html). 3. AWS CLI is installed and AWS crendentials are configured via [environment variables](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html) or [default profile](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html).
4. [AWS Cloud Development Kit (CDK)](https://docs.aws.amazon.com/cdk/latest/guide/getting_started.html#getting_started_install) is installed. 4. [AWS Cloud Development Kit (CDK)](https://docs.aws.amazon.com/cdk/latest/guide/getting_started.html#getting_started_install) is installed.
## Deploy CDK Applications ## Deploy CDK Applications

@ -69,6 +69,10 @@ class AwsCredentials:
os.remove(self._credentials_path) os.remove(self._credentials_path)
return return
credentials_file_dir = os.path.dirname(self._credentials_path)
if not os.path.isdir(credentials_file_dir):
os.makedirs(credentials_file_dir)
with open(self._credentials_path, 'w+') as credential_file: with open(self._credentials_path, 'w+') as credential_file:
self._credentials.write(credential_file) self._credentials.write(credential_file)

@ -16,7 +16,7 @@ logging.getLogger('nose').setLevel(logging.WARNING)
class AwsUtils: class AwsUtils:
def __init__(self, arn: str, session_name: str, region_name: str): def __init__(self, arn: str, session_name: str, region_name: str):
local_session = boto3.Session(profile_name='default') local_session = boto3.Session()
local_sts_client = local_session.client('sts') local_sts_client = local_session.client('sts')
self._local_account_id = local_sts_client.get_caller_identity()["Account"] self._local_account_id = local_sts_client.get_caller_identity()["Account"]
logger.info(f'Local Account Id: {self._local_account_id}') logger.info(f'Local Account Id: {self._local_account_id}')

@ -6,11 +6,13 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
""" """
import os import os
import platform
# ARN of the IAM role to assume for retrieving temporary AWS credentials # ARN of the IAM role to assume for retrieving temporary AWS credentials
ASSUME_ROLE_ARN = os.environ.get('ASSUME_ROLE_ARN', 'arn:aws:iam::645075835648:role/o3de-automation-tests') ASSUME_ROLE_ARN = os.environ.get('ASSUME_ROLE_ARN', 'arn:aws:iam::645075835648:role/o3de-automation-tests')
# Name of the AWS project deployed by the CDK applications # Name of the AWS project deployed by the CDK applications
AWS_PROJECT_NAME = os.environ.get('O3DE_AWS_PROJECT_NAME', 'AWSAUTO') AWS_PROJECT_NAME = os.environ.get('O3DE_AWS_PROJECT_NAME').upper() if os.environ.get('O3DE_AWS_PROJECT_NAME') else \
(os.environ.get('BRANCH_NAME', '') + '-' + os.environ.get('PIPELINE_NAME', '') + '-' + platform.system()).upper()
# Region for the existing CloudFormation stacks used by the automation tests # Region for the existing CloudFormation stacks used by the automation tests
AWS_REGION = os.environ.get('O3DE_AWS_DEPLOY_REGION', 'us-east-1') AWS_REGION = os.environ.get('O3DE_AWS_DEPLOY_REGION', 'us-east-1')
# Name of the default resource mapping config file used by the automation tests # Name of the default resource mapping config file used by the automation tests

@ -21,7 +21,11 @@ TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "tests")
@pytest.mark.parametrize("launcher_platform", ['windows_editor']) @pytest.mark.parametrize("launcher_platform", ['windows_editor'])
class TestAutomation(EditorTestSuite): class TestAutomation(EditorTestSuite):
enable_prefab_system = False enable_prefab_system = True
@pytest.mark.test_case_id("C36529679")
class AtomLevelLoadTest_Editor(EditorSharedTest):
from Atom.tests import hydra_Atom_LevelLoadTest as test_module
@pytest.mark.test_case_id("C36525657") @pytest.mark.test_case_id("C36525657")
class AtomEditorComponents_BloomAdded(EditorSharedTest): class AtomEditorComponents_BloomAdded(EditorSharedTest):
@ -120,6 +124,14 @@ class TestAutomation(EditorTestSuite):
class AtomEditorComponents_SSAOAdded(EditorSharedTest): class AtomEditorComponents_SSAOAdded(EditorSharedTest):
from Atom.tests import hydra_AtomEditorComponents_SSAOAdded as test_module from Atom.tests import hydra_AtomEditorComponents_SSAOAdded as test_module
@pytest.mark.test_case_id("C36529666")
class AtomEditorComponentsLevel_DiffuseGlobalIlluminationAdded(EditorSharedTest):
from Atom.tests import hydra_AtomEditorComponentsLevel_DiffuseGlobalIlluminationAdded as test_module
@pytest.mark.test_case_id("C36525660")
class AtomEditorComponentsLevel_DisplayMapperAdded(EditorSharedTest):
from Atom.tests import hydra_AtomEditorComponentsLevel_DisplayMapperAdded as test_module
class ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges(EditorSharedTest): class ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges(EditorSharedTest):
from Atom.tests import hydra_ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges as test_module from Atom.tests import hydra_ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges as test_module

@ -26,13 +26,3 @@ class TestAutomation(EditorTestSuite):
@pytest.mark.test_case_id("C36525660") @pytest.mark.test_case_id("C36525660")
class AtomEditorComponents_DisplayMapperAdded(EditorSharedTest): class AtomEditorComponents_DisplayMapperAdded(EditorSharedTest):
from Atom.tests import hydra_AtomEditorComponents_DisplayMapperAdded as test_module from Atom.tests import hydra_AtomEditorComponents_DisplayMapperAdded as test_module
# this test causes editor to crash when using slices. once automation transitions to prefabs it should pass
@pytest.mark.test_case_id("C36529666")
class AtomEditorComponentsLevel_DiffuseGlobalIlluminationAdded(EditorSharedTest):
from Atom.tests import hydra_AtomEditorComponentsLevel_DiffuseGlobalIlluminationAdded as test_module
# this test causes editor to crash when using slices. once automation transitions to prefabs it should pass
@pytest.mark.test_case_id("C36525660")
class AtomEditorComponentsLevel_DisplayMapperAdded(EditorSharedTest):
from Atom.tests import hydra_AtomEditorComponentsLevel_DisplayMapperAdded as test_module

@ -32,6 +32,8 @@ GLOBAL_ILLUMINATION_QUALITY = {
'High': 2, 'High': 2,
} }
# Level list used in Editor Level Load Test
LEVEL_LIST = ["hermanubis", "hermanubis_high", "macbeth_shaderballs", "PbrMaterialChart", "ShadowTest", "Sponza"]
class AtomComponentProperties: class AtomComponentProperties:
""" """
@ -195,11 +197,13 @@ class AtomComponentProperties:
def entity_reference(property: str = 'name') -> str: def entity_reference(property: str = 'name') -> str:
""" """
Entity Reference component properties. Entity Reference component properties.
- 'EntityIdReferences' component container of entityId references. Initially empty.
:param property: From the last element of the property tree path. Default 'name' for component name string. :param property: From the last element of the property tree path. Default 'name' for component name string.
:return: Full property path OR component name if no property specified. :return: Full property path OR component name if no property specified.
""" """
properties = { properties = {
'name': 'Entity Reference', 'name': 'Entity Reference',
'EntityIdReferences': 'Controller|Configuration|EntityIdReferences',
} }
return properties[property] return properties[property]

@ -60,7 +60,7 @@ def AtomEditorComponentsLevel_DiffuseGlobalIllumination_AddedToEntity():
# Test setup begins. # Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level. # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
TestHelper.init_idle() TestHelper.init_idle()
TestHelper.open_level("", "Base") TestHelper.open_level("Graphics", "base_empty")
# Test steps begin. # Test steps begin.
# 1. Add Diffuse Global Illumination level component to the level entity. # 1. Add Diffuse Global Illumination level component to the level entity.
@ -86,10 +86,10 @@ def AtomEditorComponentsLevel_DiffuseGlobalIllumination_AddedToEntity():
# 4. Set Quality Level property to Low # 4. Set Quality Level property to Low
diffuse_global_illumination_component.set_component_property_value( diffuse_global_illumination_component.set_component_property_value(
AtomComponentProperties.diffuse_global_illumination('Quality Level', GLOBAL_ILLUMINATION_QUALITY['Low'])) AtomComponentProperties.diffuse_global_illumination('Quality Level'), GLOBAL_ILLUMINATION_QUALITY['Low'])
quality = diffuse_global_illumination_component.get_component_property_value( quality = diffuse_global_illumination_component.get_component_property_value(
AtomComponentProperties.diffuse_global_illumination('Quality Level')) AtomComponentProperties.diffuse_global_illumination('Quality Level'))
Report.result(diffuse_global_illumination_quality, quality == GLOBAL_ILLUMINATION_QUALITY['Low']) Report.result(Tests.diffuse_global_illumination_quality, quality == GLOBAL_ILLUMINATION_QUALITY['Low'])
# 5. Enter/Exit game mode. # 5. Enter/Exit game mode.
TestHelper.enter_game_mode(Tests.enter_game_mode) TestHelper.enter_game_mode(Tests.enter_game_mode)

@ -67,7 +67,7 @@ def AtomEditorComponentsLevel_DisplayMapper_AddedToEntity():
# Test setup begins. # Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level. # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
TestHelper.init_idle() TestHelper.init_idle()
TestHelper.open_level("", "Base") TestHelper.open_level("Graphics", "base_empty")
# Test steps begin. # Test steps begin.
# 1. Add Display Mapper level component to the level entity. # 1. Add Display Mapper level component to the level entity.
@ -102,7 +102,7 @@ def AtomEditorComponentsLevel_DisplayMapper_AddedToEntity():
display_mapper_component.set_component_property_value( display_mapper_component.set_component_property_value(
AtomComponentProperties.display_mapper('Enable LDR color grading LUT'), True) AtomComponentProperties.display_mapper('Enable LDR color grading LUT'), True)
Report.result( Report.result(
Test.enable_ldr_color_grading_lut, Tests.enable_ldr_color_grading_lut,
display_mapper_component.get_component_property_value( display_mapper_component.get_component_property_value(
AtomComponentProperties.display_mapper('Enable LDR color grading LUT')) is True) AtomComponentProperties.display_mapper('Enable LDR color grading LUT')) is True)

@ -97,7 +97,7 @@ def AtomEditorComponents_Bloom_AddedToEntity():
# Test setup begins. # Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level. # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
TestHelper.init_idle() TestHelper.init_idle()
TestHelper.open_level("", "Base") TestHelper.open_level("Graphics", "base_empty")
# Test steps begin. # Test steps begin.
# 1. Create an Bloom entity with no components. # 1. Create an Bloom entity with no components.
@ -170,10 +170,12 @@ def AtomEditorComponents_Bloom_AddedToEntity():
# 13. UNDO deletion. # 13. UNDO deletion.
general.undo() general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, bloom_entity.exists()) Report.result(Tests.deletion_undo, bloom_entity.exists())
# 14. REDO deletion. # 14. REDO deletion.
general.redo() general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not bloom_entity.exists()) Report.result(Tests.deletion_redo, not bloom_entity.exists())
# 15. Look for errors and asserts. # 15. Look for errors and asserts.

@ -95,7 +95,7 @@ def AtomEditorComponents_Decal_AddedToEntity():
# Test setup begins. # Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level. # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
TestHelper.init_idle() TestHelper.init_idle()
TestHelper.open_level("", "Base") TestHelper.open_level("Graphics", "base_empty")
# Test steps begin. # Test steps begin.
# 1. Create a Decal entity with no components. # 1. Create a Decal entity with no components.
@ -162,6 +162,7 @@ def AtomEditorComponents_Decal_AddedToEntity():
# 11. REDO deletion. # 11. REDO deletion.
general.redo() general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not decal_entity.exists()) Report.result(Tests.deletion_redo, not decal_entity.exists())
# 12. Look for errors and asserts. # 12. Look for errors and asserts.

@ -97,7 +97,7 @@ def AtomEditorComponents_DeferredFog_AddedToEntity():
# Test setup begins. # Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level. # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
TestHelper.init_idle() TestHelper.init_idle()
TestHelper.open_level("", "Base") TestHelper.open_level("Graphics", "base_empty")
# Test steps begin. # Test steps begin.
# 1. Create an Deferred Fog entity with no components. # 1. Create an Deferred Fog entity with no components.
@ -174,10 +174,12 @@ def AtomEditorComponents_DeferredFog_AddedToEntity():
# 13. UNDO deletion. # 13. UNDO deletion.
general.undo() general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, deferred_fog_entity.exists()) Report.result(Tests.deletion_undo, deferred_fog_entity.exists())
# 14. REDO deletion. # 14. REDO deletion.
general.redo() general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not deferred_fog_entity.exists()) Report.result(Tests.deletion_redo, not deferred_fog_entity.exists())
# 15. Look for errors and asserts. # 15. Look for errors and asserts.

@ -107,7 +107,7 @@ def AtomEditorComponents_DepthOfField_AddedToEntity():
# Test setup begins. # Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level. # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
TestHelper.init_idle() TestHelper.init_idle()
TestHelper.open_level("", "Base") TestHelper.open_level("Graphics", "base_empty")
# Test steps begin. # Test steps begin.
# 1. Create a DepthOfField entity with no components. # 1. Create a DepthOfField entity with no components.
@ -189,10 +189,12 @@ def AtomEditorComponents_DepthOfField_AddedToEntity():
# 15. UNDO deletion. # 15. UNDO deletion.
general.undo() general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, depth_of_field_entity.exists()) Report.result(Tests.deletion_undo, depth_of_field_entity.exists())
# 16. REDO deletion. # 16. REDO deletion.
general.redo() general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not depth_of_field_entity.exists()) Report.result(Tests.deletion_redo, not depth_of_field_entity.exists())
# 17. Look for errors and asserts. # 17. Look for errors and asserts.

@ -90,7 +90,7 @@ def AtomEditorComponents_DiffuseProbeGrid_AddedToEntity():
# Test setup begins. # Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level. # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
TestHelper.init_idle() TestHelper.init_idle()
TestHelper.open_level("", "Base") TestHelper.open_level("Graphics", "base_empty")
# Test steps begin. # Test steps begin.
# 1. Create a Diffuse Probe Grid entity with no components. # 1. Create a Diffuse Probe Grid entity with no components.
@ -168,10 +168,12 @@ def AtomEditorComponents_DiffuseProbeGrid_AddedToEntity():
# 12. UNDO deletion. # 12. UNDO deletion.
general.undo() general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, diffuse_probe_grid_entity.exists()) Report.result(Tests.deletion_undo, diffuse_probe_grid_entity.exists())
# 13. REDO deletion. # 13. REDO deletion.
general.redo() general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not diffuse_probe_grid_entity.exists()) Report.result(Tests.deletion_redo, not diffuse_probe_grid_entity.exists())
# 14. Look for errors or asserts. # 14. Look for errors or asserts.

@ -95,7 +95,7 @@ def AtomEditorComponents_DirectionalLight_AddedToEntity():
# Test setup begins. # Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level. # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
TestHelper.init_idle() TestHelper.init_idle()
TestHelper.open_level("", "Base") TestHelper.open_level("Graphics", "base_empty")
# Test steps begin. # Test steps begin.
# 1. Create a Directional Light entity with no components. # 1. Create a Directional Light entity with no components.
@ -168,10 +168,12 @@ def AtomEditorComponents_DirectionalLight_AddedToEntity():
# 12. UNDO deletion. # 12. UNDO deletion.
general.undo() general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, directional_light_entity.exists()) Report.result(Tests.deletion_undo, directional_light_entity.exists())
# 13. REDO deletion. # 13. REDO deletion.
general.redo() general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not directional_light_entity.exists()) Report.result(Tests.deletion_redo, not directional_light_entity.exists())
# 14. Look for errors and asserts. # 14. Look for errors and asserts.

@ -91,7 +91,7 @@ def AtomEditorComponents_DisplayMapper_AddedToEntity():
# Test setup begins. # Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level. # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
TestHelper.init_idle() TestHelper.init_idle()
TestHelper.open_level("", "Base") TestHelper.open_level("Graphics", "base_empty")
# Test steps begin. # Test steps begin.
# 1. Create a Display Mapper entity with no components. # 1. Create a Display Mapper entity with no components.
@ -166,10 +166,12 @@ def AtomEditorComponents_DisplayMapper_AddedToEntity():
# 11. UNDO deletion. # 11. UNDO deletion.
general.undo() general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, display_mapper_entity.exists()) Report.result(Tests.deletion_undo, display_mapper_entity.exists())
# 12. REDO deletion. # 12. REDO deletion.
general.redo() general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not display_mapper_entity.exists()) Report.result(Tests.deletion_redo, not display_mapper_entity.exists())
# 13. Look for errors and asserts. # 13. Look for errors and asserts.

@ -9,37 +9,58 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
class Tests: class Tests:
creation_undo = ( creation_undo = (
"UNDO Entity creation success", "UNDO Entity creation success",
"UNDO Entity creation failed") "P0: UNDO Entity creation failed")
creation_redo = ( creation_redo = (
"REDO Entity creation success", "REDO Entity creation success",
"REDO Entity creation failed") "P0: REDO Entity creation failed")
entity_reference_creation = ( entity_reference_creation = (
"Entity Reference Entity successfully created", "Entity Reference Entity successfully created",
"Entity Reference Entity failed to be created") "P0: Entity Reference Entity failed to be created")
entity_reference_component = ( entity_reference_component = (
"Entity has an Entity Reference component", "Entity has an Entity Reference component",
"Entity failed to find Entity Reference component") "P0: Entity failed to find Entity Reference component")
enter_game_mode = ( enter_game_mode = (
"Entered game mode", "Entered game mode",
"Failed to enter game mode") "P0: Failed to enter game mode")
exit_game_mode = ( exit_game_mode = (
"Exited game mode", "Exited game mode",
"Couldn't exit game mode") "P0: Couldn't exit game mode")
is_visible = ( is_visible = (
"Entity is visible", "Entity is visible",
"Entity was not visible") "P0: Entity was not visible")
is_hidden = ( is_hidden = (
"Entity is hidden", "Entity is hidden",
"Entity was not hidden") "P0: Entity was not hidden")
entity_deleted = ( entity_deleted = (
"Entity deleted", "Entity deleted",
"Entity was not deleted") "P0: Entity was not deleted")
deletion_undo = ( deletion_undo = (
"UNDO deletion success", "UNDO deletion success",
"UNDO deletion failed") "P0: UNDO deletion failed")
deletion_redo = ( deletion_redo = (
"REDO deletion success", "REDO deletion success",
"REDO deletion failed") "P0: REDO deletion failed")
entity_id_references_is_container = (
"EntityIdReferences is a container property",
"P1: EntityIdReferences is NOT a container property")
container_append = (
"EntityIdReferences append succeeded",
"P1: EntityIdReferences append did not succeed")
container_add = (
"EntityIdReferences add succeeded",
"P1: EntityIdReferences add did not succeed")
container_update = (
"EntityIdReferences update succeeded",
"P1: EntityIdReferences update did not succeed")
container_remove = (
"EntityIdReferences remove succeeded",
"P1: EntityIdReferences remove did not succeed")
container_reset = (
"EntityIdReferences reset succeeded",
"P1: EntityIdReferences reset did not succeed")
entity_reference_component_removed = (
"Entity Reference component removed from entity",
"P1: Entity Reference component NOT removed from entity")
def AtomEditorComponents_EntityReference_AddedToEntity(): def AtomEditorComponents_EntityReference_AddedToEntity():
@ -60,13 +81,21 @@ def AtomEditorComponents_EntityReference_AddedToEntity():
2) Add Entity Reference component to Entity Reference entity. 2) Add Entity Reference component to Entity Reference entity.
3) UNDO the entity creation and component addition. 3) UNDO the entity creation and component addition.
4) REDO the entity creation and component addition. 4) REDO the entity creation and component addition.
5) Enter/Exit game mode. 5) 'EntityIdReferences' is a container property
6) Test IsHidden. 6) Append item to 'EntityIdReferences'
7) Test IsVisible. 7) Add item to 'EntityIdReferences'
8) Delete Entity Reference entity. 8) Update item in 'EntityIdReferences'
9) UNDO deletion. 9) Remove item from 'EntityIdReferences'
10) REDO deletion. 10) Reset the container property then put one entity reference back for further tests
11) Look for errors. 11) Remove component
12) UNDO component remove
13) Enter/Exit game mode.
14) Test IsHidden.
15) Test IsVisible.
16) Delete Entity Reference entity.
17) UNDO deletion.
18) REDO deletion.
19) Look for errors.
:return: None :return: None
""" """
@ -81,7 +110,7 @@ def AtomEditorComponents_EntityReference_AddedToEntity():
# Test setup begins. # Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level. # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
TestHelper.init_idle() TestHelper.init_idle()
TestHelper.open_level("", "Base") TestHelper.open_level("Graphics", "base_empty")
# Test steps begin. # Test steps begin.
# 1. Create an Entity Reference entity with no components. # 1. Create an Entity Reference entity with no components.
@ -119,33 +148,107 @@ def AtomEditorComponents_EntityReference_AddedToEntity():
general.idle_wait_frames(1) general.idle_wait_frames(1)
Report.result(Tests.creation_redo, entity_reference_entity.exists()) Report.result(Tests.creation_redo, entity_reference_entity.exists())
# 5. Enter/Exit game mode. # Entities for EntityIdReferences tests
test_1 = EditorEntity.create_editor_entity('test_1')
test_2 = EditorEntity.create_editor_entity('test_2')
test_3 = EditorEntity.create_editor_entity('test_3')
# 5. 'EntityIdReferences' is a container property
Report.result(
Tests.entity_id_references_is_container,
entity_reference_component.is_property_container(
AtomComponentProperties.entity_reference('EntityIdReferences')))
# 6. Append item to 'EntityIdReferences'
entity_reference_component.append_container_item(
AtomComponentProperties.entity_reference('EntityIdReferences'), test_1.id)
Report.result(
Tests.container_append,
entity_reference_component.get_container_item(
AtomComponentProperties.entity_reference('EntityIdReferences'), 0) == test_1.id)
# 7. Add item to 'EntityIdReferences'
entity_reference_component.add_container_item(
AtomComponentProperties.entity_reference('EntityIdReferences'), 1, test_1.id)
Report.result(
Tests.container_add,
entity_reference_component.get_container_count(
AtomComponentProperties.entity_reference('EntityIdReferences')) == 2)
# 8. Update item in 'EntityIdReferences'
entity_reference_component.update_container_item(
AtomComponentProperties.entity_reference('EntityIdReferences'), 1, test_2.id)
Report.result(
Tests.container_update,
entity_reference_component.get_container_item(
AtomComponentProperties.entity_reference('EntityIdReferences'), 1) == test_2.id)
# 9. Remove item from 'EntityIdReferences'
entity_reference_component.append_container_item(
AtomComponentProperties.entity_reference('EntityIdReferences'), test_3.id)
count_before = entity_reference_component.get_container_count(
AtomComponentProperties.entity_reference('EntityIdReferences'))
entity_reference_component.remove_container_item(
AtomComponentProperties.entity_reference('EntityIdReferences'), 1)
count_after = entity_reference_component.get_container_count(
AtomComponentProperties.entity_reference('EntityIdReferences'))
Report.result(
Tests.container_remove,
((count_before == 3) and (count_after == 2) and
(entity_reference_component.get_container_item(
AtomComponentProperties.entity_reference('EntityIdReferences'), 1) == test_3.id)))
# 10. Reset the container property then put one entity reference back for further tests
entity_reference_component.reset_container(AtomComponentProperties.entity_reference('EntityIdReferences'))
general.idle_wait_frames(1)
Report.result(
Tests.container_reset,
entity_reference_component.get_container_count(
AtomComponentProperties.entity_reference('EntityIdReferences')) == 0)
entity_reference_component.append_container_item(
AtomComponentProperties.entity_reference('EntityIdReferences'), test_1.id)
# 11. Remove component
entity_reference_entity.remove_component(AtomComponentProperties.entity_reference())
general.idle_wait_frames(1)
Report.result(Tests.entity_reference_component_removed, not entity_reference_entity.has_component(
AtomComponentProperties.entity_reference()))
# 12. UNDO component remove
general.undo()
general.idle_wait_frames(1)
Report.result(Tests.entity_reference_component, entity_reference_entity.has_component(
AtomComponentProperties.entity_reference()))
# 13. Enter/Exit game mode.
TestHelper.enter_game_mode(Tests.enter_game_mode) TestHelper.enter_game_mode(Tests.enter_game_mode)
general.idle_wait_frames(1) general.idle_wait_frames(1)
TestHelper.exit_game_mode(Tests.exit_game_mode) TestHelper.exit_game_mode(Tests.exit_game_mode)
# 6. Test IsHidden. # 14. Test IsHidden.
entity_reference_entity.set_visibility_state(False) entity_reference_entity.set_visibility_state(False)
Report.result(Tests.is_hidden, entity_reference_entity.is_hidden() is True) Report.result(Tests.is_hidden, entity_reference_entity.is_hidden() is True)
# 7. Test IsVisible. # 15. Test IsVisible.
entity_reference_entity.set_visibility_state(True) entity_reference_entity.set_visibility_state(True)
general.idle_wait_frames(1) general.idle_wait_frames(1)
Report.result(Tests.is_visible, entity_reference_entity.is_visible() is True) Report.result(Tests.is_visible, entity_reference_entity.is_visible() is True)
# 8. Delete Entity Reference entity. # 16. Delete Entity Reference entity.
entity_reference_entity.delete() entity_reference_entity.delete()
Report.result(Tests.entity_deleted, not entity_reference_entity.exists()) Report.result(Tests.entity_deleted, not entity_reference_entity.exists())
# 9. UNDO deletion. # 17. UNDO deletion.
general.undo() general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, entity_reference_entity.exists()) Report.result(Tests.deletion_undo, entity_reference_entity.exists())
# 10. REDO deletion. # 18. REDO deletion.
general.redo() general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not entity_reference_entity.exists()) Report.result(Tests.deletion_redo, not entity_reference_entity.exists())
# 11. Look for errors and asserts. # 19. Look for errors and asserts.
TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0) TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
for error_info in error_tracer.errors: for error_info in error_tracer.errors:
Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}") Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")

@ -101,7 +101,7 @@ def AtomEditorComponents_ExposureControl_AddedToEntity():
# Test setup begins. # Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level. # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
TestHelper.init_idle() TestHelper.init_idle()
TestHelper.open_level("", "Base") TestHelper.open_level("Graphics", "base_empty")
# Test steps begin. # Test steps begin.
# 1. Creation of Exposure Control entity with no components. # 1. Creation of Exposure Control entity with no components.
@ -169,10 +169,12 @@ def AtomEditorComponents_ExposureControl_AddedToEntity():
# 12. UNDO deletion. # 12. UNDO deletion.
general.undo() general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, exposure_control_entity.exists()) Report.result(Tests.deletion_undo, exposure_control_entity.exists())
# 13. REDO deletion. # 13. REDO deletion.
general.redo() general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not exposure_control_entity.exists()) Report.result(Tests.deletion_redo, not exposure_control_entity.exists())
# 14. Look for errors and asserts. # 14. Look for errors and asserts.

@ -99,7 +99,7 @@ def AtomEditorComponents_GlobalSkylightIBL_AddedToEntity():
# Test setup begins. # Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level. # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
TestHelper.init_idle() TestHelper.init_idle()
TestHelper.open_level("", "Base") TestHelper.open_level("Graphics", "base_empty")
# Test steps begin. # Test steps begin.
# 1. Create a Global Skylight (IBL) entity with no components. # 1. Create a Global Skylight (IBL) entity with no components.
@ -176,10 +176,12 @@ def AtomEditorComponents_GlobalSkylightIBL_AddedToEntity():
# 11. UNDO deletion. # 11. UNDO deletion.
general.undo() general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, global_skylight_entity.exists()) Report.result(Tests.deletion_undo, global_skylight_entity.exists())
# 12. REDO deletion. # 12. REDO deletion.
general.redo() general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not global_skylight_entity.exists()) Report.result(Tests.deletion_redo, not global_skylight_entity.exists())
# 13. Look for errors and asserts. # 13. Look for errors and asserts.

@ -82,7 +82,7 @@ def AtomEditorComponents_Grid_AddedToEntity():
# Test setup begins. # Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level. # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
TestHelper.init_idle() TestHelper.init_idle()
TestHelper.open_level("", "Base") TestHelper.open_level("Graphics", "base_empty")
# Test steps begin. # Test steps begin.
# 1. Create a Grid entity with no components. # 1. Create a Grid entity with no components.
@ -139,10 +139,12 @@ def AtomEditorComponents_Grid_AddedToEntity():
# 9. UNDO deletion. # 9. UNDO deletion.
general.undo() general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, grid_entity.exists()) Report.result(Tests.deletion_undo, grid_entity.exists())
# 10. REDO deletion. # 10. REDO deletion.
general.redo() general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not grid_entity.exists()) Report.result(Tests.deletion_redo, not grid_entity.exists())
# 11. Look for errors or asserts. # 11. Look for errors or asserts.

@ -96,7 +96,7 @@ def AtomEditorComponents_HDRColorGrading_AddedToEntity():
# Test setup begins. # Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level. # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
TestHelper.init_idle() TestHelper.init_idle()
TestHelper.open_level("", "Base") TestHelper.open_level("Graphics", "base_empty")
# Test steps begin. # Test steps begin.
# 1. Create an HDR Color Grading entity with no components. # 1. Create an HDR Color Grading entity with no components.
@ -173,10 +173,12 @@ def AtomEditorComponents_HDRColorGrading_AddedToEntity():
# 13. UNDO deletion. # 13. UNDO deletion.
general.undo() general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, hdr_color_grading_entity.exists()) Report.result(Tests.deletion_undo, hdr_color_grading_entity.exists())
# 14. REDO deletion. # 14. REDO deletion.
general.redo() general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not hdr_color_grading_entity.exists()) Report.result(Tests.deletion_redo, not hdr_color_grading_entity.exists())
# 15. Look for errors and asserts. # 15. Look for errors and asserts.

@ -87,7 +87,7 @@ def AtomEditorComponents_HDRiSkybox_AddedToEntity():
# Test setup begins. # Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level. # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
TestHelper.init_idle() TestHelper.init_idle()
TestHelper.open_level("", "Base") TestHelper.open_level("Graphics", "base_empty")
# Test steps begin. # Test steps begin.
# 1. Create an HDRi Skybox with no components. # 1. Create an HDRi Skybox with no components.
@ -158,10 +158,12 @@ def AtomEditorComponents_HDRiSkybox_AddedToEntity():
# 10. UNDO deletion. # 10. UNDO deletion.
general.undo() general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, hdri_skybox_entity.exists()) Report.result(Tests.deletion_undo, hdri_skybox_entity.exists())
# 11. REDO deletion. # 11. REDO deletion.
general.redo() general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not hdri_skybox_entity.exists()) Report.result(Tests.deletion_redo, not hdri_skybox_entity.exists())
# 12. Look for errors or asserts. # 12. Look for errors or asserts.

@ -89,7 +89,7 @@ def AtomEditorComponents_Light_AddedToEntity():
# Test setup begins. # Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level. # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
TestHelper.init_idle() TestHelper.init_idle()
TestHelper.open_level("", "Base") TestHelper.open_level("Graphics", "base_empty")
# Test steps begin. # Test steps begin.
# 1. Create a Light entity with no components. # 1. Create a Light entity with no components.
@ -144,10 +144,12 @@ def AtomEditorComponents_Light_AddedToEntity():
# 9. UNDO deletion. # 9. UNDO deletion.
general.undo() general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, light_entity.exists()) Report.result(Tests.deletion_undo, light_entity.exists())
# 10. REDO deletion. # 10. REDO deletion.
general.redo() general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not light_entity.exists()) Report.result(Tests.deletion_redo, not light_entity.exists())
# 11. Look for errors asserts. # 11. Look for errors asserts.

@ -104,7 +104,7 @@ def AtomEditorComponents_LookModification_AddedToEntity():
# Test setup begins. # Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level. # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
TestHelper.init_idle() TestHelper.init_idle()
TestHelper.open_level("", "Base") TestHelper.open_level("Graphics", "base_empty")
# Test steps begin. # Test steps begin.
# 1. Create an Look Modification entity with no components. # 1. Create an Look Modification entity with no components.
@ -192,10 +192,12 @@ def AtomEditorComponents_LookModification_AddedToEntity():
# 14. UNDO deletion. # 14. UNDO deletion.
general.undo() general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, look_modification_entity.exists()) Report.result(Tests.deletion_undo, look_modification_entity.exists())
# 15. REDO deletion. # 15. REDO deletion.
general.redo() general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not look_modification_entity.exists()) Report.result(Tests.deletion_redo, not look_modification_entity.exists())
# 16. Look for errors and asserts. # 16. Look for errors and asserts.

@ -102,7 +102,7 @@ def AtomEditorComponents_Material_AddedToEntity():
# Test setup begins. # Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level. # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
TestHelper.init_idle() TestHelper.init_idle()
TestHelper.open_level("", "Base") TestHelper.open_level("Graphics", "base_empty")
# Test steps begin. # Test steps begin.
# 1. Create a Material entity with no components. # 1. Create a Material entity with no components.
@ -184,10 +184,12 @@ def AtomEditorComponents_Material_AddedToEntity():
# 16. UNDO deletion. # 16. UNDO deletion.
general.undo() general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, material_entity.exists()) Report.result(Tests.deletion_undo, material_entity.exists())
# 17. REDO deletion. # 17. REDO deletion.
general.redo() general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not material_entity.exists()) Report.result(Tests.deletion_redo, not material_entity.exists())
# 18. Look for errors or asserts. # 18. Look for errors or asserts.

@ -87,7 +87,7 @@ def AtomEditorComponents_Mesh_AddedToEntity():
# Test setup begins. # Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level. # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
TestHelper.init_idle() TestHelper.init_idle()
TestHelper.open_level("", "Base") TestHelper.open_level("Graphics", "base_empty")
# Test steps begin. # Test steps begin.
# 1. Create a Mesh entity with no components. # 1. Create a Mesh entity with no components.
@ -151,10 +151,12 @@ def AtomEditorComponents_Mesh_AddedToEntity():
# 10. UNDO deletion. # 10. UNDO deletion.
general.undo() general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, mesh_entity.exists()) Report.result(Tests.deletion_undo, mesh_entity.exists())
# 11. REDO deletion. # 11. REDO deletion.
general.redo() general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not mesh_entity.exists()) Report.result(Tests.deletion_redo, not mesh_entity.exists())
# 12. Look for errors or asserts. # 12. Look for errors or asserts.

@ -80,7 +80,7 @@ def AtomEditorComponents_OcclusionCullingPlane_AddedToEntity():
# Test setup begins. # Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level. # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
TestHelper.init_idle() TestHelper.init_idle()
TestHelper.open_level("", "Base") TestHelper.open_level("Graphics", "base_empty")
# Test steps begin. # Test steps begin.
# 1. Create a occlusion culling plane entity with no components. # 1. Create a occlusion culling plane entity with no components.
@ -140,10 +140,12 @@ def AtomEditorComponents_OcclusionCullingPlane_AddedToEntity():
# 9. UNDO deletion. # 9. UNDO deletion.
general.undo() general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, occlusion_culling_plane_entity.exists()) Report.result(Tests.deletion_undo, occlusion_culling_plane_entity.exists())
# 10. REDO deletion. # 10. REDO deletion.
general.redo() general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not occlusion_culling_plane_entity.exists()) Report.result(Tests.deletion_redo, not occlusion_culling_plane_entity.exists())
# 11. Look for errors or asserts. # 11. Look for errors or asserts.

@ -89,7 +89,7 @@ def AtomEditorComponents_PhysicalSky_AddedToEntity():
# Test setup begins. # Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level. # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
TestHelper.init_idle() TestHelper.init_idle()
TestHelper.open_level("", "Base") TestHelper.open_level("Graphics", "base_empty")
# Test steps begin. # Test steps begin.
# 1. Create a Physical Sky entity with no components. # 1. Create a Physical Sky entity with no components.
@ -146,10 +146,12 @@ def AtomEditorComponents_PhysicalSky_AddedToEntity():
# 9. UNDO deletion. # 9. UNDO deletion.
general.undo() general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, physical_sky_entity.exists()) Report.result(Tests.deletion_undo, physical_sky_entity.exists())
# 10. REDO deletion. # 10. REDO deletion.
general.redo() general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not physical_sky_entity.exists()) Report.result(Tests.deletion_redo, not physical_sky_entity.exists())
# 11. Look for errors and asserts. # 11. Look for errors and asserts.

@ -92,7 +92,7 @@ def AtomEditorComponents_PostFXGradientWeightModifier_AddedToEntity():
# Test setup begins. # Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level. # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
TestHelper.init_idle() TestHelper.init_idle()
TestHelper.open_level("", "Base") TestHelper.open_level("Graphics", "base_empty")
# Test steps begin. # Test steps begin.
# 1. Create a PostFX Gradient Weight Modifier entity with no components. # 1. Create a PostFX Gradient Weight Modifier entity with no components.
@ -162,10 +162,12 @@ def AtomEditorComponents_PostFXGradientWeightModifier_AddedToEntity():
# 12. UNDO deletion. # 12. UNDO deletion.
general.undo() general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, postfx_gradient_weight_entity.exists()) Report.result(Tests.deletion_undo, postfx_gradient_weight_entity.exists())
# 13. REDO deletion. # 13. REDO deletion.
general.redo() general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not postfx_gradient_weight_entity.exists()) Report.result(Tests.deletion_redo, not postfx_gradient_weight_entity.exists())
# 14. Look for errors or asserts. # 14. Look for errors or asserts.

@ -80,7 +80,7 @@ def AtomEditorComponents_postfx_layer_AddedToEntity():
# Test setup begins. # Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level. # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
TestHelper.init_idle() TestHelper.init_idle()
TestHelper.open_level("", "Base") TestHelper.open_level("Graphics", "base_empty")
# Test steps begin. # Test steps begin.
# 1. Create a PostFX Layer entity with no components. # 1. Create a PostFX Layer entity with no components.
@ -137,10 +137,12 @@ def AtomEditorComponents_postfx_layer_AddedToEntity():
# 9. UNDO deletion. # 9. UNDO deletion.
general.undo() general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, postfx_layer_entity.exists()) Report.result(Tests.deletion_undo, postfx_layer_entity.exists())
# 10. REDO deletion. # 10. REDO deletion.
general.redo() general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not postfx_layer_entity.exists()) Report.result(Tests.deletion_redo, not postfx_layer_entity.exists())
# 11. Look for errors or asserts. # 11. Look for errors or asserts.

@ -92,7 +92,7 @@ def AtomEditorComponents_PostFXRadiusWeightModifier_AddedToEntity():
# Test setup begins. # Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level. # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
TestHelper.init_idle() TestHelper.init_idle()
TestHelper.open_level("", "Base") TestHelper.open_level("Graphics", "base_empty")
# Test steps begin. # Test steps begin.
# 1. Create a Post FX Radius Weight Modifier entity with no components. # 1. Create a Post FX Radius Weight Modifier entity with no components.
@ -161,10 +161,12 @@ def AtomEditorComponents_PostFXRadiusWeightModifier_AddedToEntity():
# 12. UNDO deletion. # 12. UNDO deletion.
general.undo() general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, postfx_radius_weight_entity.exists()) Report.result(Tests.deletion_undo, postfx_radius_weight_entity.exists())
# 13. REDO deletion. # 13. REDO deletion.
general.redo() general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not postfx_radius_weight_entity.exists()) Report.result(Tests.deletion_redo, not postfx_radius_weight_entity.exists())
# 14. Look for errors and asserts. # 14. Look for errors and asserts.

@ -98,7 +98,7 @@ def AtomEditorComponents_postfx_shape_weight_AddedToEntity():
# Test setup begins. # Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level. # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
TestHelper.init_idle() TestHelper.init_idle()
TestHelper.open_level("", "Base") TestHelper.open_level("Graphics", "base_empty")
# Test steps begin. # Test steps begin.
# 1. Create a PostFx Shape Weight Modifier entity with no components. # 1. Create a PostFx Shape Weight Modifier entity with no components.
@ -188,10 +188,12 @@ def AtomEditorComponents_postfx_shape_weight_AddedToEntity():
# 15. UNDO deletion. # 15. UNDO deletion.
general.undo() general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, postfx_shape_weight_entity.exists()) Report.result(Tests.deletion_undo, postfx_shape_weight_entity.exists())
# 16. REDO deletion. # 16. REDO deletion.
general.redo() general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not postfx_shape_weight_entity.exists()) Report.result(Tests.deletion_redo, not postfx_shape_weight_entity.exists())
# 17. Look for errors or asserts. # 17. Look for errors or asserts.

@ -97,7 +97,7 @@ def AtomEditorComponents_ReflectionProbe_AddedToEntity():
# Test setup begins. # Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level. # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
TestHelper.init_idle() TestHelper.init_idle()
TestHelper.open_level("", "Base") TestHelper.open_level("Graphics", "base_empty")
# Test steps begin. # Test steps begin.
# 1. Create a Reflection Probe entity with no components. # 1. Create a Reflection Probe entity with no components.
@ -183,10 +183,12 @@ def AtomEditorComponents_ReflectionProbe_AddedToEntity():
# 13. UNDO deletion. # 13. UNDO deletion.
general.undo() general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, reflection_probe_entity.exists()) Report.result(Tests.deletion_undo, reflection_probe_entity.exists())
# 14. REDO deletion. # 14. REDO deletion.
general.redo() general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not reflection_probe_entity.exists()) Report.result(Tests.deletion_redo, not reflection_probe_entity.exists())
# 15. Look for errors or asserts. # 15. Look for errors or asserts.

@ -94,7 +94,7 @@ def AtomEditorComponents_SSAO_AddedToEntity():
# Test setup begins. # Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level. # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
TestHelper.init_idle() TestHelper.init_idle()
TestHelper.open_level("", "Base") TestHelper.open_level("Graphics", "base_empty")
# Test steps begin. # Test steps begin.
# 1. Create a SSAO entity with no components. # 1. Create a SSAO entity with no components.
@ -163,10 +163,12 @@ def AtomEditorComponents_SSAO_AddedToEntity():
# 12. UNDO deletion. # 12. UNDO deletion.
general.undo() general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, ssao_entity.exists()) Report.result(Tests.deletion_undo, ssao_entity.exists())
# 13. REDO deletion. # 13. REDO deletion.
general.redo() general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not ssao_entity.exists()) Report.result(Tests.deletion_redo, not ssao_entity.exists())
# 14. Look for errors and asserts. # 14. Look for errors and asserts.

@ -0,0 +1,72 @@
"""
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
"""
def Atom_LevelLoadTest():
"""
Summary:
Loads all graphics levels within the AutomatedTesting project in editor. For each level this script will verify that
the level loads, and can enter/exit gameplay without crashing the editor.
Test setup:
- Store all available levels in a list.
- Set up a for loop to run all checks for each level.
Expected Behavior:
Test verifies that each level loads, enters/exits game mode, and reports success for all test actions.
Test Steps for each level:
1) Create tuple with level load success and failure messages
2) Open the level using the python test tools command
3) Verify level is loaded using a separate command, and report success/failure
4) Enter gameplay and report result using a tuple
5) Exit Gameplay and report result using a tuple
6) Look for errors or asserts.
:return: None
"""
import azlmbr.legacy.general as general
from editor_python_test_tools.utils import Report, Tracer, TestHelper
from Atom.atom_utils.atom_constants import LEVEL_LIST
with Tracer() as error_tracer:
for level in LEVEL_LIST:
# 1. Create tuple with level load success and failure messages
level_check_tuple = (f"loaded {level}", f"failed to load {level}")
# 2. Open the level using the python test tools command
TestHelper.init_idle()
TestHelper.open_level("Graphics", level)
# 3. Verify level is loaded using a separate command, and report success/failure
Report.result(level_check_tuple, level == general.get_current_level_name())
# 4. Enter gameplay and report result using a tuple
enter_game_mode_tuple = (f"{level} entered gameplay successfully ", f"{level} failed to enter gameplay")
TestHelper.enter_game_mode(enter_game_mode_tuple)
general.idle_wait_frames(1)
# 5. Exit gameplay and report result using a tuple
exit_game_mode_tuple = (f"{level} exited gameplay successfully ", f"{level} failed to exit gameplay")
TestHelper.exit_game_mode(exit_game_mode_tuple)
# 6. 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(Atom_LevelLoadTest)

@ -473,12 +473,11 @@ class EditorEntity:
:param component_names: List of component names to remove :param component_names: List of component names to remove
:return: None :return: None
""" """
type_ids = EditorComponent.get_type_ids(component_names, EditorEntityType.GAME) component_ids = [component.id for component in self.get_components_of_type(component_names)]
for type_id in type_ids: remove_success = editor.EditorComponentAPIBus(bus.Broadcast, "RemoveComponents", component_ids)
remove_outcome = editor.EditorComponentAPIBus(bus.Broadcast, "RemoveComponents", self.id, [type_id])
assert ( assert (
remove_outcome.IsSuccess() remove_success
), f"Failure: could not remove component from '{self.get_name()}'" ), f"Failure: could not remove component from entity '{self.get_name()}'"
def get_components_of_type(self, component_names: list) -> List[EditorComponent]: def get_components_of_type(self, component_names: list) -> List[EditorComponent]:
""" """

@ -48,8 +48,8 @@ def wait_for_propagation():
# This is a helper class which contains some of the useful information about a prefab instance. # This is a helper class which contains some of the useful information about a prefab instance.
class PrefabInstance: class PrefabInstance:
def __init__(self, prefab_file_name: str = None, container_entity: EditorEntity = None): def __init__(self, prefab_file_path: str = None, container_entity: EditorEntity = None):
self.prefab_file_name: str = prefab_file_name self.prefab_file_path: str = prefab_file_path
self.container_entity: EditorEntity = container_entity self.container_entity: EditorEntity = container_entity
def __eq__(self, other): def __eq__(self, other):
@ -66,7 +66,7 @@ class PrefabInstance:
See if this instance is valid to be used with other prefab operations. See if this instance is valid to be used with other prefab operations.
:return: Whether the target instance is valid or not. :return: Whether the target instance is valid or not.
""" """
return self.container_entity.id.IsValid() and self.prefab_file_name in Prefab.existing_prefabs return self.container_entity.id.IsValid() and self.prefab_file_path in Prefab.existing_prefabs
def has_editor_prefab_component(self) -> bool: def has_editor_prefab_component(self) -> bool:
""" """
@ -131,7 +131,7 @@ class PrefabInstance:
has_correct_parent = reparented_container_entity_parent_id.ToString() == parent_entity_id.ToString() has_correct_parent = reparented_container_entity_parent_id.ToString() == parent_entity_id.ToString()
assert has_correct_parent, "Prefab Instance reparented is *not* under the expected parent entity" assert has_correct_parent, "Prefab Instance reparented is *not* under the expected parent entity"
current_instance_prefab = Prefab.get_prefab(self.prefab_file_name) current_instance_prefab = Prefab.get_prefab(self.prefab_file_path)
current_instance_prefab.instances.remove(self) current_instance_prefab.instances.remove(self)
self.container_entity = reparented_container_entity self.container_entity = reparented_container_entity
@ -161,46 +161,48 @@ class Prefab:
:param file_path: A unique file path of the target prefab. :param file_path: A unique file path of the target prefab.
:return: Whether the target prefab is loaded or not. :return: Whether the target prefab is loaded or not.
""" """
return file_path in Prefab.existing_prefabs for entry in Prefab.existing_prefabs:
Report.info(f"PrefabPath: '{entry}'")
return get_prefab_file_path(file_path) in Prefab.existing_prefabs
@classmethod @classmethod
def prefab_exists(cls, file_path: str) -> bool: def prefab_exists(cls, file_path: str) -> bool:
""" """
Check if a prefab exists in the directory for files of prefab tests. Check if a prefab exists in the directory for files of prefab tests.
:param file_name: A unique file name of the target prefab. :param file_path: A unique file path of the target prefab.
:return: Whether the target prefab exists or not. :return: Whether the target prefab exists or not.
""" """
return path.exists(get_prefab_file_path(file_path)) return path.exists(get_prefab_file_path(file_path))
@classmethod @classmethod
def get_prefab(cls, file_name: str) -> Prefab: def get_prefab(cls, file_path: str) -> Prefab:
""" """
Return a prefab which can be used immediately. Return a prefab which can be used immediately.
:param file_name: A unique file name of the target prefab. :param file_path: A unique file path of the target prefab.
:return: The prefab with given file name. :return: The prefab with given file name.
""" """
assert file_name, "Received an empty file_name" assert file_path, "Received an empty file_path"
if Prefab.is_prefab_loaded(file_name): if Prefab.is_prefab_loaded(file_path):
return Prefab.existing_prefabs[file_name] return Prefab.existing_prefabs[get_prefab_file_path(file_path)]
else: else:
assert Prefab.prefab_exists(file_name), f"Attempted to get a prefab \"{file_name}\" that doesn't exist" assert Prefab.prefab_exists(file_path), f"Attempted to get a prefab \"{file_path}\" that doesn't exist"
new_prefab = Prefab(file_name) new_prefab = Prefab(file_path)
Prefab.existing_prefabs[file_name] = Prefab(file_name) Prefab.existing_prefabs[new_prefab.file_path] = new_prefab
return new_prefab return new_prefab
@classmethod @classmethod
def create_prefab(cls, entities: list[EditorEntity], file_name: str, prefab_instance_name: str=None) -> tuple(Prefab, PrefabInstance): def create_prefab(cls, entities: list[EditorEntity], file_path: str, prefab_instance_name: str=None) -> tuple(Prefab, PrefabInstance):
""" """
Create a prefab in memory and return it. The very first instance of this prefab will also be created. Create a prefab in memory and return it. The very first instance of this prefab will also be created.
:param entities: The entities that should form the new prefab (along with their descendants). :param entities: The entities that should form the new prefab (along with their descendants).
:param file_name: A unique file name of new prefab. :param file_path: A unique file path for new prefab.
:param prefab_instance_name: A name for the very first instance generated while prefab creation. The default instance name is the same as file_name. :param prefab_instance_name: A name for the very first instance generated while prefab creation. The default instance name is the same as the file name in file_path.
:return: Created Prefab object and the very first PrefabInstance object owned by the prefab. :return: Created Prefab object and the very first PrefabInstance object owned by the prefab.
""" """
assert not Prefab.is_prefab_loaded(file_name), f"Can't create Prefab '{file_name}' since the prefab already exists" assert not Prefab.is_prefab_loaded(file_path), f"Can't create Prefab '{file_path}' since the prefab already exists"
new_prefab = Prefab(file_name) new_prefab = Prefab(file_path)
entity_ids = [entity.id for entity in entities] entity_ids = [entity.id for entity in entities]
create_prefab_result = prefab.PrefabPublicRequestBus(bus.Broadcast, 'CreatePrefabInMemory', entity_ids, new_prefab.file_path) create_prefab_result = prefab.PrefabPublicRequestBus(bus.Broadcast, 'CreatePrefabInMemory', entity_ids, new_prefab.file_path)
assert create_prefab_result.IsSuccess(), f"Prefab operation 'CreatePrefab' failed. Error: {create_prefab_result.GetError()}" assert create_prefab_result.IsSuccess(), f"Prefab operation 'CreatePrefab' failed. Error: {create_prefab_result.GetError()}"
@ -211,14 +213,13 @@ class Prefab:
assert len(children_entity_ids) == len(entities), f"Entity count of created prefab instance does *not* match the count of given entities." assert len(children_entity_ids) == len(entities), f"Entity count of created prefab instance does *not* match the count of given entities."
if prefab_instance_name:
container_entity.set_name(prefab_instance_name)
wait_for_propagation() wait_for_propagation()
new_prefab_instance = PrefabInstance(file_name, EditorEntity(container_entity_id)) new_prefab_instance = PrefabInstance(new_prefab.file_path, EditorEntity(container_entity_id))
if prefab_instance_name:
new_prefab_instance.container_entity.set_name(prefab_instance_name)
new_prefab.instances.add(new_prefab_instance) new_prefab.instances.add(new_prefab_instance)
Prefab.existing_prefabs[file_name] = new_prefab Prefab.existing_prefabs[new_prefab.file_path] = new_prefab
return new_prefab, new_prefab_instance return new_prefab, new_prefab_instance
@classmethod @classmethod
@ -250,7 +251,7 @@ class Prefab:
assert False, "Not all entities and descendants in target prefabs are deleted." assert False, "Not all entities and descendants in target prefabs are deleted."
for instance in prefab_instances: for instance in prefab_instances:
instance_deleted_prefab = Prefab.get_prefab(instance.prefab_file_name) instance_deleted_prefab = Prefab.get_prefab(instance.prefab_file_path)
instance_deleted_prefab.instances.remove(instance) instance_deleted_prefab.instances.remove(instance)
instance = PrefabInstance() instance = PrefabInstance()
@ -290,8 +291,7 @@ class Prefab:
prefab_file_path = prefab.PrefabPublicRequestBus(bus.Broadcast, 'GetOwningInstancePrefabPath', duplicate_container_entity_id) prefab_file_path = prefab.PrefabPublicRequestBus(bus.Broadcast, 'GetOwningInstancePrefabPath', duplicate_container_entity_id)
assert prefab_file_path, "Returned file path should *not* be empty." assert prefab_file_path, "Returned file path should *not* be empty."
prefab_file_name = Path(prefab_file_path).stem duplicate_instance_prefab = Prefab.get_prefab(prefab_file_path)
duplicate_instance_prefab = Prefab.get_prefab(prefab_file_name)
duplicate_instance = PrefabInstance(prefab_file_path, EditorEntity(duplicate_container_entity_id)) duplicate_instance = PrefabInstance(prefab_file_path, EditorEntity(duplicate_container_entity_id))
duplicate_instance_prefab.instances.add(duplicate_instance) duplicate_instance_prefab.instances.add(duplicate_instance)
duplicate_instances.append(duplicate_instance) duplicate_instances.append(duplicate_instance)
@ -324,7 +324,7 @@ class Prefab:
wait_for_propagation() wait_for_propagation()
instance_owner_prefab = Prefab.get_prefab(prefab_instance.prefab_file_name) instance_owner_prefab = Prefab.get_prefab(prefab_instance.prefab_file_path)
instance_owner_prefab.instances.remove(prefab_instance) instance_owner_prefab.instances.remove(prefab_instance)
prefab_instance = PrefabInstance() prefab_instance = PrefabInstance()
@ -346,13 +346,13 @@ class Prefab:
container_entity_id = instantiate_prefab_result.GetValue() container_entity_id = instantiate_prefab_result.GetValue()
container_entity = EditorEntity(container_entity_id) container_entity = EditorEntity(container_entity_id)
if name:
container_entity.set_name(name)
wait_for_propagation() wait_for_propagation()
new_prefab_instance = PrefabInstance(self.file_path, EditorEntity(container_entity_id)) new_prefab_instance = PrefabInstance(self.file_path, EditorEntity(container_entity_id))
assert not new_prefab_instance in self.instances, "This prefab instance is already existed before this instantiation." assert not new_prefab_instance in self.instances, "This prefab instance already existed before this instantiation."
if name:
new_prefab_instance.container_entity.set_name(name)
self.instances.add(new_prefab_instance) self.instances.add(new_prefab_instance)
assert new_prefab_instance.is_at_position(prefab_position), "This prefab instance is *not* at expected position." assert new_prefab_instance.is_at_position(prefab_position), "This prefab instance is *not* at expected position."

@ -35,3 +35,7 @@ class TestAutomation(TestAutomationBase):
def test_Multiplayer_AutoComponent_RPC(self, request, workspace, editor, launcher_platform): def test_Multiplayer_AutoComponent_RPC(self, request, workspace, editor, launcher_platform):
from .tests import Multiplayer_AutoComponent_RPC as test_module from .tests import Multiplayer_AutoComponent_RPC as test_module
self._run_prefab_test(request, workspace, editor, test_module) self._run_prefab_test(request, workspace, editor, test_module)
def test_Multiplayer_SimpleNetworkLevelEntity(self, request, workspace, editor, launcher_platform):
from .tests import Multiplayer_SimpleNetworkLevelEntity as test_module
self._run_prefab_test(request, workspace, editor, test_module)

@ -0,0 +1,76 @@
"""
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 : Check that level entities with network bindings are properly replicated.
# Note: This test should be ran on a fresh editor run; some bugs with spawnables occur only on the first editor play-mode.
# fmt: off
class TestSuccessFailTuples():
enter_game_mode = ("Entered game mode", "Failed to enter game mode")
exit_game_mode = ("Exited game mode", "Couldn't exit game mode")
find_network_player = ("Found network player", "Couldn't find network player")
# fmt: on
def Multiplayer_SimpleNetworkLevelEntity():
r"""
Summary:
Test to make sure that network entities in a level function and are replicated to clients as expected
Level Description:
- Static
1. NetLevelEntity. This is a networked entity which has a script attached which prints logs to ensure it's replicated.
Expected Outcome:
We should see logs stating that the net-sync'd level entity exists on both server and client.
:return:
"""
import azlmbr.legacy.general as general
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import Tracer
from editor_python_test_tools.utils import TestHelper as helper
from ly_remote_console.remote_console_commands import RemoteConsole as RemoteConsole
level_name = "SimpleNetworkLevelEntity"
player_prefab_name = "Player"
player_prefab_path = f"levels/multiplayer/{level_name}/{player_prefab_name}.network.spawnable"
helper.init_idle()
# 1) Open Level
helper.open_level("Multiplayer", level_name)
with Tracer() as section_tracer:
# 2) Enter game mode
helper.multiplayer_enter_game_mode(TestSuccessFailTuples.enter_game_mode, player_prefab_path.lower())
# 3) Make sure the network player was spawned
player_id = general.find_game_entity(player_prefab_name)
Report.critical_result(TestSuccessFailTuples.find_network_player, player_id.IsValid())
# 4) Check the editor logs for network spawnable errors
ATTEMPTING_INVALID_NETSPAWN_WAIT_TIME_SECONDS = 0.0 # The editor will try to net-spawn its networked level entity before it's even a client. Make sure this didn't happen.
helper.fail_if_log_line_found('NetworkEntityManager', "RequestNetSpawnableInstantiation: Requested spawnable Root.network.spawnable doesn't exist in the NetworkSpawnableLibrary. Please make sure it is a network spawnable", section_tracer.errors, ATTEMPTING_INVALID_NETSPAWN_WAIT_TIME_SECONDS)
# 5) Ensure the script graph attached to the level entity is running on the server
SCRIPTGRAPH_ENABLED_WAIT_TIME_SECONDS = 0.25
helper.succeed_if_log_line_found('EditorServer', "Script: SimpleNetworkLevelEntity: On Graph Start", section_tracer.prints, SCRIPTGRAPH_ENABLED_WAIT_TIME_SECONDS)
# Exit game mode
helper.exit_game_mode(TestSuccessFailTuples.exit_game_mode)
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(Multiplayer_SimpleNetworkLevelEntity)

@ -38,6 +38,10 @@ class TestAutomation(TestAutomationBase):
from Prefab.tests.instantiate_prefab import InstantiatePrefab_ContainingASingleEntity as test_module from Prefab.tests.instantiate_prefab import InstantiatePrefab_ContainingASingleEntity as test_module
self._run_prefab_test(request, workspace, editor, test_module) self._run_prefab_test(request, workspace, editor, test_module)
def test_InstantiatePrefab_FromCreatedPrefabWithSingleEntity(self, request, workspace, editor, launcher_platform):
from Prefab.tests.instantiate_prefab import InstantiatePrefab_FromCreatedPrefabWithSingleEntity as test_module
self._run_prefab_test(request, workspace, editor, test_module)
def test_DeletePrefab_ContainingASingleEntity(self, request, workspace, editor, launcher_platform): def test_DeletePrefab_ContainingASingleEntity(self, request, workspace, editor, launcher_platform):
from Prefab.tests.delete_prefab import DeletePrefab_ContainingASingleEntity as test_module from Prefab.tests.delete_prefab import DeletePrefab_ContainingASingleEntity as test_module
self._run_prefab_test(request, workspace, editor, test_module) self._run_prefab_test(request, workspace, editor, test_module)

@ -45,8 +45,12 @@ class TestAutomationNoAutoTestMode(EditorTestSuite):
class test_InstantiatePrefab_ContainingASingleEntity(EditorSharedTest): class test_InstantiatePrefab_ContainingASingleEntity(EditorSharedTest):
from .tests.instantiate_prefab import InstantiatePrefab_ContainingASingleEntity as test_module from .tests.instantiate_prefab import InstantiatePrefab_ContainingASingleEntity as test_module
class test_InstantiatePrefab_FromCreatedPrefabWithSingleEntity(EditorSharedTest):
from .tests.instantiate_prefab import InstantiatePrefab_FromCreatedPrefabWithSingleEntity as test_module
class test_DeletePrefab_ContainingASingleEntity(EditorSharedTest): class test_DeletePrefab_ContainingASingleEntity(EditorSharedTest):
from .tests.delete_prefab import DeletePrefab_ContainingASingleEntity as test_module from .tests.delete_prefab import DeletePrefab_ContainingASingleEntity as test_module
class test_DuplicatePrefab_ContainingASingleEntity(EditorSharedTest): class test_DuplicatePrefab_ContainingASingleEntity(EditorSharedTest):
from .tests.duplicate_prefab import DuplicatePrefab_ContainingASingleEntity as test_module from .tests.duplicate_prefab import DuplicatePrefab_ContainingASingleEntity as test_module

@ -13,7 +13,8 @@ def CreatePrefab_UnderAnEntity():
Test is successful if the new instanced prefab of the child has the parent entity id Test is successful if the new instanced prefab of the child has the parent entity id
""" """
CAR_PREFAB_FILE_NAME = 'car_prefab' from pathlib import Path
CAR_PREFAB_FILE_NAME = Path(__file__).stem + 'car_prefab'
from editor_python_test_tools.editor_entity_utils import EditorEntity from editor_python_test_tools.editor_entity_utils import EditorEntity
from editor_python_test_tools.prefab_utils import Prefab from editor_python_test_tools.prefab_utils import Prefab

@ -7,7 +7,8 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
def CreatePrefab_WithSingleEntity(): def CreatePrefab_WithSingleEntity():
CAR_PREFAB_FILE_NAME = 'car_prefab' from pathlib import Path
CAR_PREFAB_FILE_NAME = Path(__file__).stem + 'car_prefab'
from editor_python_test_tools.editor_entity_utils import EditorEntity from editor_python_test_tools.editor_entity_utils import EditorEntity
from editor_python_test_tools.utils import Report from editor_python_test_tools.utils import Report

@ -7,7 +7,8 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
def DeletePrefab_ContainingASingleEntity(): def DeletePrefab_ContainingASingleEntity():
CAR_PREFAB_FILE_NAME = 'car_prefab' from pathlib import Path
CAR_PREFAB_FILE_NAME = Path(__file__).stem + 'car_prefab'
from editor_python_test_tools.editor_entity_utils import EditorEntity from editor_python_test_tools.editor_entity_utils import EditorEntity
from editor_python_test_tools.prefab_utils import Prefab from editor_python_test_tools.prefab_utils import Prefab

@ -7,8 +7,9 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
def DetachPrefab_UnderAnotherPrefab(): def DetachPrefab_UnderAnotherPrefab():
CAR_PREFAB_FILE_NAME = 'car_prefab2' from pathlib import Path
WHEEL_PREFAB_FILE_NAME = 'wheel_prefab2' CAR_PREFAB_FILE_NAME = Path(__file__).stem + 'car_prefab'
WHEEL_PREFAB_FILE_NAME = Path(__file__).stem + 'wheel_prefab'
import editor_python_test_tools.pyside_utils as pyside_utils import editor_python_test_tools.pyside_utils as pyside_utils

@ -7,7 +7,8 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
def DuplicatePrefab_ContainingASingleEntity(): def DuplicatePrefab_ContainingASingleEntity():
CAR_PREFAB_FILE_NAME = 'car_prefab' from pathlib import Path
CAR_PREFAB_FILE_NAME = Path(__file__).stem + 'car_prefab'
from editor_python_test_tools.editor_entity_utils import EditorEntity from editor_python_test_tools.editor_entity_utils import EditorEntity
from editor_python_test_tools.prefab_utils import Prefab from editor_python_test_tools.prefab_utils import Prefab

@ -0,0 +1,34 @@
"""
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
"""
def InstantiatePrefab_FromCreatedPrefabWithSingleEntity():
from pathlib import Path
CAR_PREFAB_FILE_NAME = Path(__file__).stem + 'car_prefab'
from editor_python_test_tools.editor_entity_utils import EditorEntity
from editor_python_test_tools.utils import Report
from editor_python_test_tools.prefab_utils import Prefab
import Prefab.tests.PrefabTestUtils as prefab_test_utils
prefab_test_utils.open_base_tests_level()
# Creates a new entity at the root level
car_entity = EditorEntity.create_editor_entity()
car_prefab_entities = [car_entity]
# Creates a prefab from the new entity
car_prefab, car_prefab_instance = Prefab.create_prefab(car_prefab_entities, CAR_PREFAB_FILE_NAME)
# Instantiate another instance and verify
car_prefab_instance_2 = car_prefab.instantiate()
assert car_prefab_instance_2.is_valid(), "Failed to instantiate prefab"
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(InstantiatePrefab_FromCreatedPrefabWithSingleEntity)

@ -7,8 +7,9 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
def ReparentPrefab_UnderAnotherPrefab(): def ReparentPrefab_UnderAnotherPrefab():
CAR_PREFAB_FILE_NAME = 'car_prefab' from pathlib import Path
WHEEL_PREFAB_FILE_NAME = 'wheel_prefab' CAR_PREFAB_FILE_NAME = Path(__file__).stem + 'car_prefab'
WHEEL_PREFAB_FILE_NAME = Path(__file__).stem + 'wheel_prefab'
import editor_python_test_tools.pyside_utils as pyside_utils import editor_python_test_tools.pyside_utils as pyside_utils

@ -19,12 +19,16 @@ def find_nodes_matching_entity_component(component_name, entity_id):
:param entity_id: The entity ID to search for the given component node on :param entity_id: The entity ID to search for the given component node on
:return List of matching nodes :return List of matching nodes
""" """
component_type_id = hydra.get_component_type_id(component_name)
component = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', entity_id, component = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', entity_id,
hydra.get_component_type_id(component_name)) component_type_id)
if component.IsSuccess(): if component.IsSuccess():
component_id = component.GetValue() component_id = component.GetValue()
component_node = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'GetAllNodesMatchingEntityComponent', component_node = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'GetAllNodesMatchingEntityComponent',
component_id) component_id)
if component_node: if component_node:
print(f"{component_name} node found on entity {entity_id.ToString()}") print(f"{component_name} node found on entity {entity_id.ToString()}")
else:
print(f"Failed to find {component_name} node on entity {entity_id.ToString()}")
return component_node return component_node

@ -32,10 +32,10 @@ def Menus_FileMenuOptions_Work():
file_menu_options = [ file_menu_options = [
("New Level",), ("New Level",),
#("Open Level",), Temporarily disabled due to https://github.com/o3de/o3de/issues/6605 ("Open Level",),
#("Import",), Temporarily disabled due to https://github.com/o3de/o3de/issues/6746 #("Import",), #Temporarily disabled due to https://github.com/o3de/o3de/issues/6746
("Save",), ("Save",),
#("Save As",), Temporarily disabled due to https://github.com/o3de/o3de/issues/6605 ("Save As",),
("Save Level Statistics",), ("Save Level Statistics",),
("Edit Project Settings",), ("Edit Project Settings",),
#("Edit Platform Settings",), Temporarily disabled due to https://github.com/o3de/o3de/issues/6604 #("Edit Platform Settings",), Temporarily disabled due to https://github.com/o3de/o3de/issues/6604

@ -43,7 +43,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
NAME AutomatedTesting::LandscapeCanvasTests_Main_Optimized NAME AutomatedTesting::LandscapeCanvasTests_Main_Optimized
TEST_SERIAL TEST_SERIAL
TEST_SUITE main TEST_SUITE main
PATH ${CMAKE_CURRENT_LIST_DIR}/landscape_canvas/TestSuite_Main_Optimized.py PATH ${CMAKE_CURRENT_LIST_DIR}/landscape_canvas/TestSuite_Main.py
RUNTIME_DEPENDENCIES RUNTIME_DEPENDENCIES
AZ::AssetProcessor AZ::AssetProcessor
Legacy::Editor Legacy::Editor

@ -68,8 +68,7 @@ def AreaNodes_DependentComponentsAdded():
newEntityId = parameters[0] newEntityId = parameters[0]
# Open an existing simple level # Open an existing simple level
helper.init_idle() hydra.open_base_level()
helper.open_level("", "Base")
# Open Landscape Canvas tool and verify # Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas') general.open_pane('Landscape Canvas')

@ -58,7 +58,6 @@ def AreaNodes_EntityCreatedOnNodeAdd():
import editor_python_test_tools.hydra_editor_utils as hydra 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 Report
from editor_python_test_tools.utils import TestHelper as helper
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
@ -67,8 +66,7 @@ def AreaNodes_EntityCreatedOnNodeAdd():
newEntityId = parameters[0] newEntityId = parameters[0]
# Open an existing simple level # Open an existing simple level
helper.init_idle() hydra.open_base_level()
helper.open_level("Physics", "Base")
# Open Landscape Canvas tool and verify # Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas') general.open_pane('Landscape Canvas')

@ -59,8 +59,8 @@ def AreaNodes_EntityRemovedOnNodeDelete():
import azlmbr.math as math import azlmbr.math as math
import azlmbr.paths import azlmbr.paths
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 Report
from editor_python_test_tools.utils import TestHelper as helper
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
@ -73,8 +73,7 @@ def AreaNodes_EntityRemovedOnNodeDelete():
deletedEntityId = parameters[0] deletedEntityId = parameters[0]
# Open an existing simple level # Open an existing simple level
helper.init_idle() hydra.open_base_level()
helper.open_level("Physics", "Base")
# Open Landscape Canvas tool and verify # Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas') general.open_pane('Landscape Canvas')

@ -1,15 +1,14 @@
""" """
Copyright (c) Contributors to the Open 3D Engine Project. 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. For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT SPDX-License-Identifier: Apache-2.0 OR MIT
""" """
class Tests: class Tests:
slice_instantiated = ( prefab_instantiated = (
"Slice instantiated successfully", "Prefab instantiated successfully",
"Failed to instantiate slice" "Failed to instantiate prefab"
) )
lc_entity_found = ( lc_entity_found = (
"LandscapeCanvas entity found", "LandscapeCanvas entity found",
@ -24,7 +23,7 @@ class Tests:
"Failed to find Distribution Filter component on BushSpawner entity" "Failed to find Distribution Filter component on BushSpawner entity"
) )
existing_graph_opened = ( existing_graph_opened = (
"Opened existing graph from slice", "Opened existing graph from prefab",
"Failed to open existing graph" "Failed to open existing graph"
) )
dist_filter_node_found = ( dist_filter_node_found = (
@ -66,10 +65,8 @@ def ComponentUpdates_UpdateGraph():
Summary: Summary:
This test verifies that the Landscape Canvas graphs update properly when components are added/removed outside of This test verifies that the Landscape Canvas graphs update properly when components are added/removed outside of
Landscape Canvas. Landscape Canvas.
Expected Behavior: Expected Behavior:
Graphs properly reflect component changes made to entities outside of Landscape Canvas. Graphs properly reflect component changes made to entities outside of Landscape Canvas.
Test Steps: Test Steps:
1. Open Level 1. Open Level
2. Find LandscapeCanvas named entity 2. Find LandscapeCanvas named entity
@ -83,41 +80,36 @@ def ComponentUpdates_UpdateGraph():
9. Add a new entity with unique name as a child of the Landscape Canvas entity 9. Add a new entity with unique name as a child of the Landscape Canvas entity
10. Add a Box Shape component to the new child entity 10. Add a Box Shape component to the new child entity
11. Ensure Box Shape node is present on the open graph 11. Ensure Box Shape node is present on the open graph
Note: Note:
- This test file must be called from the Open 3D Engine Editor command terminal - 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. - 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. Parsing the file or running a log_monitor are required to observe the test results.
:return: None :return: None
""" """
import os import os
import azlmbr.asset as asset
import azlmbr.bus as bus import azlmbr.bus as bus
import azlmbr.editor as editor import azlmbr.editor as editor
import azlmbr.entity as entity import azlmbr.entity as entity
import azlmbr.legacy.general as general import azlmbr.legacy.general as general
import azlmbr.landscapecanvas as landscapecanvas import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.math as math import azlmbr.math as math
import azlmbr.slice as slice import azlmbr.prefab as prefab
import editor_python_test_tools.hydra_editor_utils as hydra 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 Report
from editor_python_test_tools.utils import TestHelper as helper from editor_python_test_tools.utils import TestHelper as helper
# Open a simple level and instantiate LC_BushFlowerBlender.slice # Open a simple level and instantiate BushFlowerBlender.prefab
helper.init_idle() hydra.open_base_level()
helper.open_level("Physics", "Base")
transform = math.Transform_CreateIdentity() transform = math.Transform_CreateIdentity()
position = math.Vector3(64.0, 64.0, 32.0) position = math.Vector3(64.0, 64.0, 32.0)
transform.invoke('SetPosition', position) transform.invoke('SetPosition', position)
test_slice_path = os.path.join("Slices", "LC_BushFlowerBlender.slice") test_prefab_path = os.path.join("Assets", "Prefabs", "BushFlowerBlender.prefab")
test_slice_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", test_slice_path, math.Uuid(), prefab_result = prefab.PrefabPublicRequestBus(bus.Broadcast, 'InstantiatePrefab', test_prefab_path,
False) entity.EntityId(), position)
test_slice = slice.SliceRequestBus(bus.Broadcast, 'InstantiateSliceFromAssetId', test_slice_id, transform) Report.critical_result(Tests.prefab_instantiated, prefab_result.IsSuccess())
Report.critical_result(Tests.slice_instantiated, test_slice.IsValid())
# Find root entity in the loaded level # Find root entity in the loaded level
search_filter = entity.SearchFilter() search_filter = entity.SearchFilter()
@ -126,8 +118,8 @@ def ComponentUpdates_UpdateGraph():
# Allow a few seconds for matching entity to be found # Allow a few seconds for matching entity to be found
helper.wait_for_condition(lambda: len(entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)) > 0, 5.0) helper.wait_for_condition(lambda: len(entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)) > 0, 5.0)
lc_matching_entities = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter) lc_matching_entities = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)
slice_root_id = lc_matching_entities[0] #Entity with Landscape Canvas component prefab_root_id = lc_matching_entities[0] #Entity with Landscape Canvas component
Report.critical_result(Tests.lc_entity_found, slice_root_id.IsValid()) Report.critical_result(Tests.lc_entity_found, prefab_root_id.IsValid())
# Find the BushSpawner entity # Find the BushSpawner entity
search_filter.names = ["BushSpawner"] search_filter.names = ["BushSpawner"]
@ -147,7 +139,7 @@ def ComponentUpdates_UpdateGraph():
# Open Landscape Canvas and the existing graph # Open Landscape Canvas and the existing graph
general.open_pane('Landscape Canvas') general.open_pane('Landscape Canvas')
open_graph = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'OnGraphEntity', slice_root_id) open_graph = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'OnGraphEntity', prefab_root_id)
Report.critical_result(Tests.existing_graph_opened, open_graph.IsValid()) Report.critical_result(Tests.existing_graph_opened, open_graph.IsValid())
# Verify that Distribution Filter node is present on the graph # Verify that Distribution Filter node is present on the graph

@ -45,11 +45,9 @@ def Component_AddedRemoved():
import editor_python_test_tools.hydra_editor_utils as hydra 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 Report
from editor_python_test_tools.utils import TestHelper as helper
# Open an existing simple level # Open an existing simple level
helper.init_idle() hydra.open_base_level()
helper.open_level("Physics", "Base")
# Create an Entity at the root of the level # Create an Entity at the root of the level
newEntityId = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', entity.EntityId()) newEntityId = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', entity.EntityId())

@ -59,8 +59,7 @@ def Edit_DisabledNodeDuplication():
newEntityId = parameters[0] newEntityId = parameters[0]
# Open an existing simple level # Open an existing simple level
helper.init_idle() hydra.open_base_level()
helper.open_level("Physics", "Base")
# Open Landscape Canvas tool and verify # Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas') general.open_pane('Landscape Canvas')

@ -1,15 +1,14 @@
""" """
Copyright (c) Contributors to the Open 3D Engine Project. 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. For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT SPDX-License-Identifier: Apache-2.0 OR MIT
""" """
class Tests: class Tests:
slice_spawned = ( prefab_instantiated = (
"Slice instantiated successfully", "Prefab instantiated successfully",
"Failed to instantiate slice" "Failed to instantiate prefab"
) )
lc_entity_found = ( lc_entity_found = (
"Landscape Canvas entity found", "Landscape Canvas entity found",
@ -31,31 +30,28 @@ class Tests:
"Vegetation Layer Spawner node was successfully removed", "Vegetation Layer Spawner node was successfully removed",
"Failed to remove Vegetation Layer Spawner node" "Failed to remove Vegetation Layer Spawner node"
) )
def Edit_UndoNodeDelete_SliceEntity():
def Edit_UndoNodeDelete_PrefabEntity():
""" """
Summary: Summary:
This test verifies Editor stability after undoing the deletion of nodes on a slice entity. This test verifies Editor stability after undoing the deletion of nodes on a prefab entity.
Expected Behavior: Expected Behavior:
Editor remains stable and free of crashes. Editor remains stable and free of crashes.
Test Steps: Test Steps:
1) Open a simple level 1) Open a simple level
2) Instantiate a slice with a Landscape Canvas setup 2) Instantiate a prefab with a Landscape Canvas setup
3) Find a specific node on the graph, and delete it 3) Find a specific node on the graph, and delete it
4) Restore the node with Undo 4) Restore the node with Undo
Note: Note:
- This test file must be called from the Open 3D Engine Editor command terminal - 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. - 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. Parsing the file or running a log_monitor are required to observe the test results.
:return: None :return: None
""" """
import os import os
import azlmbr.asset as asset
import azlmbr.bus as bus import azlmbr.bus as bus
import azlmbr.editor as editor import azlmbr.editor as editor
import azlmbr.entity as entity import azlmbr.entity as entity
@ -63,25 +59,23 @@ def Edit_UndoNodeDelete_SliceEntity():
import azlmbr.editor.graph as graph import azlmbr.editor.graph as graph
import azlmbr.landscapecanvas as landscapecanvas import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.math as math import azlmbr.math as math
import azlmbr.slice as slice import azlmbr.prefab as prefab
import editor_python_test_tools.hydra_editor_utils as hydra 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 Report
from editor_python_test_tools.utils import TestHelper as helper from editor_python_test_tools.utils import TestHelper as helper
# Open an existing simple level # Open an existing simple level
helper.init_idle() hydra.open_base_level()
helper.open_level("Physics", "Base")
# Instantiate slice # Instantiate slice
transform = math.Transform_CreateIdentity() transform = math.Transform_CreateIdentity()
position = math.Vector3(64.0, 64.0, 32.0) position = math.Vector3(64.0, 64.0, 32.0)
transform.invoke('SetPosition', position) transform.invoke('SetPosition', position)
test_slice_path = os.path.join("Slices", "LC_BushFlowerBlender.slice") test_prefab_path = os.path.join("Assets", "Prefabs", "BushFlowerBlender.prefab")
test_slice_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", test_slice_path, math.Uuid(), prefab_result = prefab.PrefabPublicRequestBus(bus.Broadcast, 'InstantiatePrefab', test_prefab_path,
False) entity.EntityId(), position)
test_slice = slice.SliceRequestBus(bus.Broadcast, 'InstantiateSliceFromAssetId', test_slice_id, transform) Report.critical_result(Tests.prefab_instantiated, prefab_result.IsSuccess())
Report.result(Tests.slice_spawned, test_slice.IsValid())
# Find root entity in the loaded level # Find root entity in the loaded level
search_filter = entity.SearchFilter() search_filter = entity.SearchFilter()
@ -134,5 +128,4 @@ def Edit_UndoNodeDelete_SliceEntity():
if __name__ == "__main__": if __name__ == "__main__":
from editor_python_test_tools.utils import Report from editor_python_test_tools.utils import Report
Report.start_test(Edit_UndoNodeDelete_SliceEntity) Report.start_test(Edit_UndoNodeDelete_PrefabEntity)

@ -76,7 +76,6 @@ def GradientMixer_NodeConstruction():
import editor_python_test_tools.hydra_editor_utils as hydra 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 Report
from editor_python_test_tools.utils import TestHelper as helper
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
@ -85,8 +84,7 @@ def GradientMixer_NodeConstruction():
newEntityId = parameters[0] newEntityId = parameters[0]
# Open an existing simple level # Open an existing simple level
helper.init_idle() hydra.open_base_level()
helper.open_level("Physics", "Base")
# Open Landscape Canvas tool and verify # Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas') general.open_pane('Landscape Canvas')

@ -58,7 +58,6 @@ def GradientModifierNodes_EntityCreatedOnNodeAdd():
import editor_python_test_tools.hydra_editor_utils as hydra 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 Report
from editor_python_test_tools.utils import TestHelper as helper
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
@ -67,8 +66,7 @@ def GradientModifierNodes_EntityCreatedOnNodeAdd():
newEntityId = parameters[0] newEntityId = parameters[0]
# Open an existing simple level # Open an existing simple level
helper.init_idle() hydra.open_base_level()
helper.open_level("Physics", "Base")
# Open Landscape Canvas tool and verify # Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas') general.open_pane('Landscape Canvas')

@ -58,8 +58,8 @@ def GradientModifierNodes_EntityRemovedOnNodeDelete():
import azlmbr.legacy.general as general import azlmbr.legacy.general as general
import azlmbr.math as math import azlmbr.math as math
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.utils import Report from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
@ -72,8 +72,7 @@ def GradientModifierNodes_EntityRemovedOnNodeDelete():
deletedEntityId = parameters[0] deletedEntityId = parameters[0]
# Open an existing simple level # Open an existing simple level
helper.init_idle() hydra.open_base_level()
helper.open_level("Physics", "Base")
# Open Landscape Canvas tool and verify # Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas') general.open_pane('Landscape Canvas')

@ -60,7 +60,6 @@ def GradientNodes_DependentComponentsAdded():
import editor_python_test_tools.hydra_editor_utils as hydra 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 Report
from editor_python_test_tools.utils import TestHelper as helper
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
@ -69,8 +68,7 @@ def GradientNodes_DependentComponentsAdded():
newEntityId = parameters[0] newEntityId = parameters[0]
# Open an existing simple level # Open an existing simple level
helper.init_idle() hydra.open_base_level()
helper.open_level("Physics", "Base")
# Open Landscape Canvas tool and verify # Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas') general.open_pane('Landscape Canvas')

@ -58,7 +58,6 @@ def GradientNodes_EntityCreatedOnNodeAdd():
import editor_python_test_tools.hydra_editor_utils as hydra 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 Report
from editor_python_test_tools.utils import TestHelper as helper
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
@ -67,8 +66,7 @@ def GradientNodes_EntityCreatedOnNodeAdd():
newEntityId = parameters[0] newEntityId = parameters[0]
# Open an existing simple level # Open an existing simple level
helper.init_idle() hydra.open_base_level()
helper.open_level("Physics", "Base")
# Open Landscape Canvas tool and verify # Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas') general.open_pane('Landscape Canvas')

@ -58,8 +58,8 @@ def GradientNodes_EntityRemovedOnNodeDelete():
import azlmbr.legacy.general as general import azlmbr.legacy.general as general
import azlmbr.math as math import azlmbr.math as math
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.utils import Report from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
@ -72,8 +72,7 @@ def GradientNodes_EntityRemovedOnNodeDelete():
deletedEntityId = parameters[0] deletedEntityId = parameters[0]
# Open an existing simple level # Open an existing simple level
helper.init_idle() hydra.open_base_level()
helper.open_level("Physics", "Base")
# Open Landscape Canvas tool and verify # Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas') general.open_pane('Landscape Canvas')

@ -51,8 +51,8 @@ def GraphClosed_OnEntityDelete():
import azlmbr.editor.graph as graph import azlmbr.editor.graph as graph
import azlmbr.legacy.general as general 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 Report
from editor_python_test_tools.utils import TestHelper as helper
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
@ -61,8 +61,7 @@ def GraphClosed_OnEntityDelete():
newRootEntityId = parameters[0] newRootEntityId = parameters[0]
# Open an existing simple level # Open an existing simple level
helper.init_idle() hydra.open_base_level()
helper.open_level("Physics", "Base")
# Open Landscape Canvas tool and verify # Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas') general.open_pane('Landscape Canvas')

@ -51,14 +51,13 @@ def GraphClosed_OnLevelChange():
import azlmbr.editor.graph as graph import azlmbr.editor.graph as graph
import azlmbr.legacy.general as general 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 Report
from editor_python_test_tools.utils import TestHelper as helper
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
# Open an existing simple level # Open an existing simple level
helper.init_idle() hydra.open_base_level()
helper.open_level("Physics", "Base")
# Open Landscape Canvas tool and verify # Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas') general.open_pane('Landscape Canvas')
@ -73,7 +72,7 @@ def GraphClosed_OnLevelChange():
Report.result(Tests.graph_registered, graph_registered) Report.result(Tests.graph_registered, graph_registered)
# Open a different level, which should close any open Landscape Canvas graphs # Open a different level, which should close any open Landscape Canvas graphs
general.open_level_no_prompt('WhiteBox/EmptyLevel') general.open_level_no_prompt('Base')
# Make sure the graph we created is now closed # Make sure the graph we created is now closed
graphIsOpen = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId) graphIsOpen = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)

@ -51,8 +51,8 @@ def GraphClosed_TabbedGraphClosesIndependently():
import azlmbr.editor.graph as graph import azlmbr.editor.graph as graph
import azlmbr.legacy.general as general 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 Report
from editor_python_test_tools.utils import TestHelper as helper
editor_id = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID editor_id = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
@ -65,8 +65,7 @@ def GraphClosed_TabbedGraphClosesIndependently():
return graph_open return graph_open
# Open an existing simple level # Open an existing simple level
helper.init_idle() hydra.open_base_level()
helper.open_level("Physics", "Base")
# Open Landscape Canvas tool and verify # Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas') general.open_pane('Landscape Canvas')

@ -1,18 +1,17 @@
""" """
Copyright (c) Contributors to the Open 3D Engine Project. 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. For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT SPDX-License-Identifier: Apache-2.0 OR MIT
""" """
class Tests: class Tests:
slice_instantiated = ( prefab_instantiated = (
"Slice instantiated successfully", "Prefab instantiated successfully",
"Failed to instantiate slice" "Failed to instantiate prefab"
) )
existing_graph_opened = ( existing_graph_opened = (
"Opened existing graph from slice", "Opened existing graph from prefab",
"Failed to open existing graph" "Failed to open existing graph"
) )
node_removed = ( node_removed = (
@ -37,13 +36,11 @@ def GraphUpdates_UpdateComponent():
""" """
Summary: Summary:
This test verifies that components are properly updated as nodes are added/removed/updated. This test verifies that components are properly updated as nodes are added/removed/updated.
Expected Behavior: Expected Behavior:
Landscape Canvas node CRUD properly updates component entities. Landscape Canvas node CRUD properly updates component entities.
Test Steps: Test Steps:
1. Open Level. 1. Open Level.
2. Open the graph on LC_BushFlowerBlender.slice 2. Open the graph on BushFlowerBlender.prefab
3. Find the Rotation Modifier node on the BushSpawner entity 3. Find the Rotation Modifier node on the BushSpawner entity
4. Delete the Rotation Modifier node 4. Delete the Rotation Modifier node
5. Ensure the Vegetation Rotation Modifier component is removed from the BushSpawner entity 5. Ensure the Vegetation Rotation Modifier component is removed from the BushSpawner entity
@ -51,18 +48,15 @@ def GraphUpdates_UpdateComponent():
7. Ensure BushSpawner entity is deleted 7. Ensure BushSpawner entity is deleted
8. Change connection from second Rotation Modifier node to a different Gradient 8. Change connection from second Rotation Modifier node to a different Gradient
9. Ensure Gradient reference on component is updated 9. Ensure Gradient reference on component is updated
Note: Note:
- This test file must be called from the Open 3D Engine Editor command terminal - 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. - 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. Parsing the file or running a log_monitor are required to observe the test results.
:return: None :return: None
""" """
import os import os
import azlmbr.asset as asset
import azlmbr.bus as bus import azlmbr.bus as bus
import azlmbr.editor as editor import azlmbr.editor as editor
import azlmbr.entity as entity import azlmbr.entity as entity
@ -70,39 +64,37 @@ def GraphUpdates_UpdateComponent():
import azlmbr.editor.graph as graph import azlmbr.editor.graph as graph
import azlmbr.landscapecanvas as landscapecanvas import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.math as math import azlmbr.math as math
import azlmbr.slice as slice import azlmbr.prefab as prefab
import automatedtesting_shared.landscape_canvas_utils as lc import automatedtesting_shared.landscape_canvas_utils as lc
import editor_python_test_tools.hydra_editor_utils as hydra 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 Report
from editor_python_test_tools.utils import TestHelper as helper from editor_python_test_tools.utils import TestHelper as helper
# Open a simple level and instantiate LC_BushFlowerBlender.slice # Open a simple level and instantiate BushFlowerBlender.prefab
helper.init_idle() hydra.open_base_level()
helper.open_level("Physics", "Base")
transform = math.Transform_CreateIdentity() transform = math.Transform_CreateIdentity()
position = math.Vector3(64.0, 64.0, 32.0) position = math.Vector3(64.0, 64.0, 32.0)
transform.invoke('SetPosition', position) transform.invoke('SetPosition', position)
test_slice_path = os.path.join("Slices", "LC_BushFlowerBlender.slice") test_prefab_path = os.path.join("Assets", "Prefabs", "BushFlowerBlender.prefab")
test_slice_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", test_slice_path, math.Uuid(), prefab_result = prefab.PrefabPublicRequestBus(bus.Broadcast, 'InstantiatePrefab', test_prefab_path,
False) entity.EntityId(), position)
test_slice = slice.SliceRequestBus(bus.Broadcast, 'InstantiateSliceFromAssetId', test_slice_id, transform) Report.critical_result(Tests.prefab_instantiated, prefab_result.IsSuccess())
Report.critical_result(Tests.slice_instantiated, test_slice.IsValid())
# Search for root entity to ensure slice is loaded # Search for root entity to ensure prefab is loaded
search_filter = entity.SearchFilter() search_filter = entity.SearchFilter()
search_filter.names = ["LandscapeCanvas"] search_filter.names = ["LandscapeCanvas"]
helper.wait_for_condition(lambda: len(entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)) > 0, 5.0) helper.wait_for_condition(lambda: len(entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)) > 0, 5.0)
prefab_lc_root = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)[0]
# Find needed entities in the loaded level # Find needed entities in the loaded level
slice_root_id = hydra.find_entity_by_name('LandscapeCanvas')
bush_spawner_id = hydra.find_entity_by_name('BushSpawner') bush_spawner_id = hydra.find_entity_by_name('BushSpawner')
flower_spawner_id = hydra.find_entity_by_name('FlowerSpawner') flower_spawner_id = hydra.find_entity_by_name('FlowerSpawner')
inverted_perlin_noise_id = hydra.find_entity_by_name('Invert') inverted_perlin_noise_id = hydra.find_entity_by_name('Invert')
# Open Landscape Canvas and the existing graph # Open Landscape Canvas and the existing graph
general.open_pane('Landscape Canvas') general.open_pane('Landscape Canvas')
open_graph_id = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'OnGraphEntity', slice_root_id) open_graph_id = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'OnGraphEntity', prefab_lc_root)
Report.critical_result(Tests.existing_graph_opened, open_graph_id.IsValid()) Report.critical_result(Tests.existing_graph_opened, open_graph_id.IsValid())
# Find the Rotation Modifier node on the BushSpawner entity # Find the Rotation Modifier node on the BushSpawner entity
@ -110,6 +102,7 @@ def GraphUpdates_UpdateComponent():
# Remove the Rotation Modifier node # Remove the Rotation Modifier node
graph.GraphControllerRequestBus(bus.Event, 'RemoveNode', open_graph_id, rotation_modifier_node[0]) graph.GraphControllerRequestBus(bus.Event, 'RemoveNode', open_graph_id, rotation_modifier_node[0])
general.idle_wait_frames(2)
# Verify node was removed # Verify node was removed
rotation_modifier_node = lc.find_nodes_matching_entity_component('Vegetation Rotation Modifier', bush_spawner_id) rotation_modifier_node = lc.find_nodes_matching_entity_component('Vegetation Rotation Modifier', bush_spawner_id)
@ -121,14 +114,18 @@ def GraphUpdates_UpdateComponent():
Report.result(Tests.component_removed, not has_rotation_modifier) Report.result(Tests.component_removed, not has_rotation_modifier)
# Find the Vegetation Layer Spawner node on the BushSpawner entity # Find the Vegetation Layer Spawner node on the BushSpawner entity
open_graph_id = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'OnGraphEntity', prefab_lc_root)
layer_spawner_node = lc.find_nodes_matching_entity_component('Vegetation Layer Spawner', bush_spawner_id) layer_spawner_node = lc.find_nodes_matching_entity_component('Vegetation Layer Spawner', bush_spawner_id)
# Remove the Vegetation Layer Spawner node and verify the corresponding entity is deleted # Remove the Vegetation Layer Spawner node and verify the corresponding entity is deleted
graph.GraphControllerRequestBus(bus.Event, 'RemoveNode', open_graph_id, layer_spawner_node[0]) graph.GraphControllerRequestBus(bus.Event, 'RemoveNode', open_graph_id, layer_spawner_node[0])
general.idle_wait_frames(2)
layer_spawner_node = lc.find_nodes_matching_entity_component('Vegetation Layer Spawner', bush_spawner_id)
bush_spawner_id = hydra.find_entity_by_name('BushSpawner') bush_spawner_id = hydra.find_entity_by_name('BushSpawner')
Report.result(Tests.entity_deleted, not bush_spawner_id) Report.result(Tests.entity_deleted, not layer_spawner_node and not bush_spawner_id)
# Connect the FlowerSpawner's Rotation Modifier node to the Invert Gradient Modifier node # Connect the FlowerSpawner's Rotation Modifier node to the Invert Gradient Modifier node
open_graph_id = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'OnGraphEntity', prefab_lc_root)
rotation_modifier_node = lc.find_nodes_matching_entity_component('Vegetation Rotation Modifier', flower_spawner_id) rotation_modifier_node = lc.find_nodes_matching_entity_component('Vegetation Rotation Modifier', flower_spawner_id)
invert_node = lc.find_nodes_matching_entity_component('Invert Gradient Modifier', inverted_perlin_noise_id) invert_node = lc.find_nodes_matching_entity_component('Invert Gradient Modifier', inverted_perlin_noise_id)
@ -137,7 +134,7 @@ def GraphUpdates_UpdateComponent():
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', open_graph_id, invert_node[0], graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', open_graph_id, invert_node[0],
outbound_gradient_slot, rotation_modifier_node[0], inbound_gradient_z_slot) outbound_gradient_slot, rotation_modifier_node[0], inbound_gradient_z_slot)
general.idle_wait(1.0) # Add a small wait to ensure component property has time to update general.idle_wait_frames(2) # Add a small wait to ensure component property has time to update
# Verify the Gradient Entity Id reference on the Rotation Modifier component was properly set # Verify the Gradient Entity Id reference on the Rotation Modifier component was properly set
rotation_type_id = hydra.get_component_type_id('Vegetation Rotation Modifier') rotation_type_id = hydra.get_component_type_id('Vegetation Rotation Modifier')

@ -64,7 +64,6 @@ def LayerBlender_NodeConstruction():
import editor_python_test_tools.hydra_editor_utils as hydra 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 Report
from editor_python_test_tools.utils import TestHelper as helper
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
@ -73,8 +72,7 @@ def LayerBlender_NodeConstruction():
newEntityId = parameters[0] newEntityId = parameters[0]
# Open an existing simple level # Open an existing simple level
helper.init_idle() hydra.open_base_level()
helper.open_level("Physics", "Base")
# Open Landscape Canvas tool and verify # Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas') general.open_pane('Landscape Canvas')

@ -63,7 +63,6 @@ def LayerExtenderNodes_ComponentEntitySync():
import editor_python_test_tools.hydra_editor_utils as hydra 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 Report
from editor_python_test_tools.utils import TestHelper as helper
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
@ -72,8 +71,7 @@ def LayerExtenderNodes_ComponentEntitySync():
newEntityId = parameters[0] newEntityId = parameters[0]
# Open an existing simple level # Open an existing simple level
helper.init_idle() hydra.open_base_level()
helper.open_level("Physics", "Base")
# Open Landscape Canvas tool and verify # Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas') general.open_pane('Landscape Canvas')

@ -60,7 +60,6 @@ def NewGraph_CreatedSuccessfully():
import editor_python_test_tools.hydra_editor_utils as hydra 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 Report
from editor_python_test_tools.utils import TestHelper as helper
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
@ -69,8 +68,7 @@ def NewGraph_CreatedSuccessfully():
new_root_entity_id = parameters[0] new_root_entity_id = parameters[0]
# Open an existing simple level # Open an existing simple level
helper.init_idle() hydra.open_base_level()
helper.open_level("Physics", "Base")
# Listen for entity creation notifications so we can check if the entity created # Listen for entity creation notifications so we can check if the entity created
# with the new graph has our Landscape Canvas component automatically added # with the new graph has our Landscape Canvas component automatically added

@ -0,0 +1,69 @@
"""
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:
prefab_created = (
"Prefab created successfully",
"Failed to create prefab"
)
prefab_instantiated = (
"Prefab instantiated successfully",
"Failed to instantiate prefab"
)
def Prefab_CreateInstantiate():
"""
Summary:
A prefab containing the LandscapeCanvas component can be created/instantiated.
Expected Result:
Prefab is created/processed/instantiated successfully and free of errors/warnings.
Test Steps:
1) Open a simple level
2) Create a new entity with a Landscape Canvas component
3) Create a prefab of the new entity
4) Instantiate a new copy of the prefab
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 azlmbr.math as math
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
from editor_python_test_tools.prefab_utils import Prefab
# Open an existing simple level
hydra.open_base_level()
# Create entity with Landscape Canvas component
position = math.Vector3(512.0, 512.0, 32.0)
landscape_canvas = hydra.Entity("landscape_canvas_entity")
landscape_canvas.create_entity(position, ["Landscape Canvas"])
# Create in-memory prefab from the created entity
lc_prefab_filename = "LC_PrefabTest"
lc_prefab, lc_prefab_instance = Prefab.create_prefab([landscape_canvas], lc_prefab_filename)
# Verify if prefab is created
helper.wait_for_condition(lambda: lc_prefab.is_prefab_loaded(lc_prefab_filename), 5.0)
Report.result(Tests.prefab_created, lc_prefab.is_prefab_loaded(lc_prefab_filename))
# Instantiate prefab
lc_prefab_instance2 = lc_prefab.instantiate()
helper.wait_for_condition(lambda: lc_prefab_instance2.has_editor_prefab_component(), 5.0)
Report.result(Tests.prefab_instantiated, lc_prefab_instance2.has_editor_prefab_component())
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(Prefab_CreateInstantiate)

@ -58,7 +58,6 @@ def ShapeNodes_EntityCreatedOnNodeAdd():
import editor_python_test_tools.hydra_editor_utils as hydra 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 Report
from editor_python_test_tools.utils import TestHelper as helper
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
@ -67,9 +66,7 @@ def ShapeNodes_EntityCreatedOnNodeAdd():
newEntityId = parameters[0] newEntityId = parameters[0]
# Open an existing simple level # Open an existing simple level
hydra.open_base_level()
helper.init_idle()
helper.open_level("Physics", "Base")
# Open Landscape Canvas tool and verify # Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas') general.open_pane('Landscape Canvas')

@ -58,8 +58,8 @@ def ShapeNodes_EntityRemovedOnNodeDelete():
import azlmbr.legacy.general as general import azlmbr.legacy.general as general
import azlmbr.math as math import azlmbr.math as math
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.utils import Report from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
@ -72,8 +72,7 @@ def ShapeNodes_EntityRemovedOnNodeDelete():
deletedEntityId = parameters[0] deletedEntityId = parameters[0]
# Open an existing simple level # Open an existing simple level
helper.init_idle() hydra.open_base_level()
helper.open_level("Physics", "Base")
# Open Landscape Canvas tool and verify # Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas') general.open_pane('Landscape Canvas')

@ -1,84 +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
"""
class Tests:
slice_created = (
"Slice created successfully",
"Failed to create slice"
)
slice_instantiated = (
"Slice instantiated successfully",
"Failed to instantiate slice"
)
def Slice_CreateInstantiate():
"""
Summary:
A slice containing the LandscapeCanvas component can be created/instantiated.
Expected Result:
Slice is created/processed/instantiated successfully and free of errors/warnings.
Test Steps:
1) Open a simple level
2) Create a new entity with a Landscape Canvas component
3) Create a slice of the new entity
4) Instantiate a new copy of the slice
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 azlmbr.math as math
import azlmbr.bus as bus
import azlmbr.asset as asset
import azlmbr.slice as slice
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 path_is_valid_asset(asset_path):
asset_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", asset_path, math.Uuid(), False)
return asset_id.invoke("IsValid")
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
# Create entity with Landscape Canvas component
position = math.Vector3(512.0, 512.0, 32.0)
landscape_canvas = hydra.Entity("landscape_canvas_entity")
landscape_canvas.create_entity(position, ["Landscape Canvas"])
# Create slice from the created entity
slice_path = os.path.join("slices", "TestSlice.slice")
slice.SliceRequestBus(bus.Broadcast, "CreateNewSlice", landscape_canvas.id, slice_path)
# Verify if slice is created
helper.wait_for_condition(lambda: path_is_valid_asset(slice_path), 5.0)
Report.result(Tests.slice_created, path_is_valid_asset(slice_path))
# Instantiate slice
transform = math.Transform_CreateIdentity()
asset_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", slice_path, math.Uuid(), False)
test_slice = slice.SliceRequestBus(bus.Broadcast, "InstantiateSliceFromAssetId", asset_id, transform)
helper.wait_for_condition(lambda: test_slice.IsValid(), 5.0)
Report.result(Tests.slice_instantiated, test_slice.IsValid())
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(Slice_CreateInstantiate)

@ -67,7 +67,6 @@ def SlotConnections_UpdateComponentReferences():
import editor_python_test_tools.hydra_editor_utils as hydra 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 Report
from editor_python_test_tools.utils import TestHelper as helper
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
@ -101,8 +100,7 @@ def SlotConnections_UpdateComponentReferences():
newEntityId = parameters[0] newEntityId = parameters[0]
# Open an existing simple level # Open an existing simple level
helper.init_idle() hydra.open_base_level()
helper.open_level("Physics", "Base")
# Open Landscape Canvas tool and verify # Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas') general.open_pane('Landscape Canvas')

@ -1,29 +1,88 @@
""" """
Copyright (c) Contributors to the Open 3D Engine Project. 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. For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT SPDX-License-Identifier: Apache-2.0 OR MIT
""" """
import os
import pytest 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 ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite
from base import TestAutomationBase
@pytest.mark.SUITE_main
@pytest.mark.parametrize("launcher_platform", ['windows_editor']) @pytest.mark.parametrize("launcher_platform", ['windows_editor'])
@pytest.mark.parametrize("project", ["AutomatedTesting"]) @pytest.mark.parametrize("project", ["AutomatedTesting"])
class TestAutomation(TestAutomationBase): class TestAutomation(EditorTestSuite):
def test_LandscapeCanvas_SlotConnections_UpdateComponentReferences(self, request, workspace, editor, launcher_platform): class test_LandscapeCanvas_AreaNodes_DependentComponentsAdded(EditorSharedTest):
from .EditorScripts import SlotConnections_UpdateComponentReferences as test_module from .EditorScripts import AreaNodes_DependentComponentsAdded as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
class test_LandscapeCanvas_AreaNodes_EntityCreatedOnNodeAdd(EditorSharedTest):
from .EditorScripts import AreaNodes_EntityCreatedOnNodeAdd as test_module
class test_LandscapeCanvas_AreaNodes_EntityRemovedOnNodeDelete(EditorSharedTest):
from .EditorScripts import AreaNodes_EntityRemovedOnNodeDelete as test_module
class test_LandscapeCanvas_Component_AddedRemoved(EditorSharedTest):
from .EditorScripts import Component_AddedRemoved as test_module
class test_LandscapeCanvas_ComponentUpdates_UpdateGraph(EditorSharedTest):
from .EditorScripts import ComponentUpdates_UpdateGraph as test_module
def test_LandscapeCanvas_GradientMixer_NodeConstruction(self, request, workspace, editor, launcher_platform): class test_LandscapeCanvas_Edit_DisabledNodeDuplication(EditorSharedTest):
from .EditorScripts import Edit_DisabledNodeDuplication as test_module
class test_LandscapeCanvas_Edit_UndoNodeDelete_PrefabEntity(EditorSharedTest):
from .EditorScripts import Edit_UndoNodeDelete_PrefabEntity as test_module
class test_LandscapeCanvas_GradientMixer_NodeConstruction(EditorSharedTest):
from .EditorScripts import GradientMixer_NodeConstruction as test_module from .EditorScripts import GradientMixer_NodeConstruction as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
class test_LandscapeCanvas_GradientModifierNodes_EntityCreatedOnNodeAdd(EditorSharedTest):
from .EditorScripts import GradientModifierNodes_EntityCreatedOnNodeAdd as test_module
class test_LandscapeCanvas_GradientModifierNodes_EntityRemovedOnNodeDelete(EditorSharedTest):
from .EditorScripts import GradientModifierNodes_EntityRemovedOnNodeDelete as test_module
class test_LandscapeCanvas_GradientNodes_DependentComponentsAdded(EditorSharedTest):
from .EditorScripts import GradientNodes_DependentComponentsAdded as test_module
class test_LandscapeCanvas_GradientNodes_EntityCreatedOnNodeAdd(EditorSharedTest):
from .EditorScripts import GradientNodes_EntityCreatedOnNodeAdd as test_module
class test_LandscapeCanvas_GradientNodes_EntityRemovedOnNodeDelete(EditorSharedTest):
from .EditorScripts import GradientNodes_EntityRemovedOnNodeDelete as test_module
@pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/2201")
class test_LandscapeCanvas_GraphClosed_OnEntityDelete(EditorSharedTest):
from .EditorScripts import GraphClosed_OnEntityDelete as test_module
class test_LandscapeCanvas_GraphClosed_OnLevelChange(EditorSharedTest):
from .EditorScripts import GraphClosed_OnLevelChange as test_module
class test_LandscapeCanvas_GraphClosed_TabbedGraphClosesIndependently(EditorSharedTest):
from .EditorScripts import GraphClosed_TabbedGraph as test_module
@pytest.mark.skip(reason="https://github.com/o3de/o3de/issues/7141" "https://github.com/o3de/o3de/issues/4872")
class test_LandscapeCanvas_GraphUpdates_UpdateComponents(EditorSharedTest):
from .EditorScripts import GraphUpdates_UpdateComponents as test_module
class test_LandscapeCanvas_LayerBlender_NodeConstruction(EditorSharedTest):
from .EditorScripts import LayerBlender_NodeConstruction as test_module
class test_LandscapeCanvas_LayerExtenderNodes_ComponentEntitySync(EditorSharedTest):
from .EditorScripts import LayerExtenderNodes_ComponentEntitySync as test_module
class test_LandscapeCanvas_NewGraph_CreatedSuccessfully(EditorSharedTest):
from .EditorScripts import NewGraph_CreatedSuccessfully as test_module
class test_LandscapeCanvas_Prefab_CreateInstantiate(EditorSharedTest):
from .EditorScripts import Prefab_CreateInstantiate as test_module
class test_LandscapeCanvas_ShapeNodes_EntityCreatedOnNodeAdd(EditorSharedTest):
from .EditorScripts import ShapeNodes_EntityCreatedOnNodeAdd as test_module
class test_LandscapeCanvas_ShapeNodes_EntityRemovedOnNodeDelete(EditorSharedTest):
from .EditorScripts import ShapeNodes_EntityRemovedOnNodeDelete as test_module
class test_LandscapeCanvas_SlotConnections_UpdateComponentReferences(EditorSharedTest):
from .EditorScripts import SlotConnections_UpdateComponentReferences as test_module

@ -1,104 +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
import ly_test_tools._internal.pytest_plugin as internal_plugin
from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite
@pytest.mark.SUITE_periodic
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
@pytest.mark.parametrize("project", ["AutomatedTesting"])
class TestAutomationWithPrefabSystemEnabled(EditorTestSuite):
class test_LandscapeCanvas_AreaNodes_DependentComponentsAdded(EditorSharedTest):
from .EditorScripts import AreaNodes_DependentComponentsAdded as test_module
@pytest.mark.SUITE_periodic
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
@pytest.mark.parametrize("project", ["AutomatedTesting"])
class TestAutomation(EditorTestSuite):
enable_prefab_system = False
class test_LandscapeCanvas_SlotConnections_UpdateComponentReferences(EditorSharedTest):
from .EditorScripts import SlotConnections_UpdateComponentReferences as test_module
class test_LandscapeCanvas_GradientMixer_NodeConstruction(EditorSharedTest):
from .EditorScripts import GradientMixer_NodeConstruction as test_module
class test_LandscapeCanvas_AreaNodes_EntityCreatedOnNodeAdd(EditorSharedTest):
from .EditorScripts import AreaNodes_EntityCreatedOnNodeAdd as test_module
class test_LandscapeCanvas_AreaNodes_EntityRemovedOnNodeDelete(EditorSharedTest):
from .EditorScripts import AreaNodes_EntityRemovedOnNodeDelete as test_module
class test_LandscapeCanvas_LayerExtenderNodes_ComponentEntitySync(EditorSharedTest):
from .EditorScripts import LayerExtenderNodes_ComponentEntitySync as test_module
class test_LandscapeCanvas_Edit_DisabledNodeDuplication(EditorSharedTest):
from .EditorScripts import Edit_DisabledNodeDuplication as test_module
class test_LandscapeCanvas_Edit_UndoNodeDelete_SliceEntity(EditorSharedTest):
from .EditorScripts import Edit_UndoNodeDelete_SliceEntity as test_module
class test_LandscapeCanvas_NewGraph_CreatedSuccessfully(EditorSharedTest):
from .EditorScripts import NewGraph_CreatedSuccessfully as test_module
class test_LandscapeCanvas_Component_AddedRemoved(EditorSharedTest):
from .EditorScripts import Component_AddedRemoved as test_module
class test_LandscapeCanvas_GraphClosed_OnLevelChange(EditorSharedTest):
from .EditorScripts import GraphClosed_OnLevelChange as test_module
@pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/2201")
class test_LandscapeCanvas_GraphClosed_OnEntityDelete(EditorSharedTest):
from .EditorScripts import GraphClosed_OnEntityDelete as test_module
class test_LandscapeCanvas_GraphClosed_TabbedGraphClosesIndependently(EditorSharedTest):
from .EditorScripts import GraphClosed_TabbedGraph as test_module
class test_LandscapeCanvas_Slice_CreateInstantiate(EditorSingleTest):
from .EditorScripts import Slice_CreateInstantiate as test_module
# 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", "slices",
"TestSlice.slice")], True, True)
class test_LandscapeCanvas_GradientModifierNodes_EntityCreatedOnNodeAdd(EditorSharedTest):
from .EditorScripts import GradientModifierNodes_EntityCreatedOnNodeAdd as test_module
class test_LandscapeCanvas_GradientModifierNodes_EntityRemovedOnNodeDelete(EditorSharedTest):
from .EditorScripts import GradientModifierNodes_EntityRemovedOnNodeDelete as test_module
class test_LandscapeCanvas_GradientNodes_DependentComponentsAdded(EditorSharedTest):
from .EditorScripts import GradientNodes_DependentComponentsAdded as test_module
class test_LandscapeCanvas_GradientNodes_EntityCreatedOnNodeAdd(EditorSharedTest):
from .EditorScripts import GradientNodes_EntityCreatedOnNodeAdd as test_module
class test_LandscapeCanvas_GradientNodes_EntityRemovedOnNodeDelete(EditorSharedTest):
from .EditorScripts import GradientNodes_EntityRemovedOnNodeDelete as test_module
@pytest.mark.skipif("debug" == os.path.basename(internal_plugin.build_directory),
reason="https://github.com/o3de/o3de/issues/4872")
class test_LandscapeCanvas_GraphUpdates_UpdateComponents(EditorSharedTest):
from .EditorScripts import GraphUpdates_UpdateComponents as test_module
class test_LandscapeCanvas_ComponentUpdates_UpdateGraph(EditorSharedTest):
from .EditorScripts import ComponentUpdates_UpdateGraph as test_module
class test_LandscapeCanvas_LayerBlender_NodeConstruction(EditorSharedTest):
from .EditorScripts import LayerBlender_NodeConstruction as test_module
class test_LandscapeCanvas_ShapeNodes_EntityCreatedOnNodeAdd(EditorSharedTest):
from .EditorScripts import ShapeNodes_EntityCreatedOnNodeAdd as test_module
class test_LandscapeCanvas_ShapeNodes_EntityRemovedOnNodeDelete(EditorSharedTest):
from .EditorScripts import ShapeNodes_EntityRemovedOnNodeDelete as test_module

@ -1,121 +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_slice(request, workspace, project):
file_system.delete([os.path.join(workspace.paths.engine_root(), project, "slices", "TestSlice.slice")], True, True)
def teardown():
file_system.delete([os.path.join(workspace.paths.engine_root(), project, "slices", "TestSlice.slice")], 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_LandscapeCanvas_AreaNodes_DependentComponentsAdded(self, request, workspace, editor, launcher_platform):
from .EditorScripts import AreaNodes_DependentComponentsAdded as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_AreaNodes_EntityCreatedOnNodeAdd(self, request, workspace, editor, launcher_platform):
from .EditorScripts import AreaNodes_EntityCreatedOnNodeAdd as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_AreaNodes_EntityRemovedOnNodeDelete(self, request, workspace, editor, launcher_platform):
from .EditorScripts import AreaNodes_EntityRemovedOnNodeDelete as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_LayerExtenderNodes_ComponentEntitySync(self, request, workspace, editor, launcher_platform):
from .EditorScripts import LayerExtenderNodes_ComponentEntitySync as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_Edit_DisabledNodeDuplication(self, request, workspace, editor, launcher_platform):
from .EditorScripts import Edit_DisabledNodeDuplication as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_Edit_UndoNodeDelete_SliceEntity(self, request, workspace, editor, launcher_platform):
from .EditorScripts import Edit_UndoNodeDelete_SliceEntity as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_NewGraph_CreatedSuccessfully(self, request, workspace, editor, launcher_platform):
from .EditorScripts import NewGraph_CreatedSuccessfully as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_Component_AddedRemoved(self, request, workspace, editor, launcher_platform):
from .EditorScripts import Component_AddedRemoved as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_GraphClosed_OnLevelChange(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GraphClosed_OnLevelChange as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/2201")
def test_LandscapeCanvas_GraphClosed_OnEntityDelete(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GraphClosed_OnEntityDelete as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_GraphClosed_TabbedGraphClosesIndependently(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GraphClosed_TabbedGraph as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_Slice_CreateInstantiate(self, request, workspace, editor, remove_test_slice, launcher_platform):
from .EditorScripts import Slice_CreateInstantiate as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_GradientModifierNodes_EntityCreatedOnNodeAdd(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientModifierNodes_EntityCreatedOnNodeAdd as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_GradientModifierNodes_EntityRemovedOnNodeDelete(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientModifierNodes_EntityRemovedOnNodeDelete as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_GradientNodes_DependentComponentsAdded(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientNodes_DependentComponentsAdded as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_GradientNodes_EntityCreatedOnNodeAdd(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientNodes_EntityCreatedOnNodeAdd as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_GradientNodes_EntityRemovedOnNodeDelete(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientNodes_EntityRemovedOnNodeDelete as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_GraphUpdates_UpdateComponents(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GraphUpdates_UpdateComponents as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_ComponentUpdates_UpdateGraph(self, request, workspace, editor, launcher_platform):
from .EditorScripts import ComponentUpdates_UpdateGraph as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_LayerBlender_NodeConstruction(self, request, workspace, editor, launcher_platform):
from .EditorScripts import LayerBlender_NodeConstruction as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_ShapeNodes_EntityCreatedOnNodeAdd(self, request, workspace, editor, launcher_platform):
from .EditorScripts import ShapeNodes_EntityCreatedOnNodeAdd as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_ShapeNodes_EntityRemovedOnNodeDelete(self, request, workspace, editor, launcher_platform):
from .EditorScripts import ShapeNodes_EntityRemovedOnNodeDelete as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)

@ -0,0 +1,53 @@
{
"ContainerEntity": {
"Id": "Entity_[1146574390643]",
"Name": "Level",
"Components": {
"Component_[10641544592923449938]": {
"$type": "EditorInspectorComponent",
"Id": 10641544592923449938
},
"Component_[12039882709170782873]": {
"$type": "EditorOnlyEntityComponent",
"Id": 12039882709170782873
},
"Component_[12265484671603697631]": {
"$type": "EditorPendingCompositionComponent",
"Id": 12265484671603697631
},
"Component_[14126657869720434043]": {
"$type": "EditorEntitySortComponent",
"Id": 14126657869720434043
},
"Component_[15230859088967841193]": {
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
"Id": 15230859088967841193,
"Parent Entity": ""
},
"Component_[16239496886950819870]": {
"$type": "EditorDisabledCompositionComponent",
"Id": 16239496886950819870
},
"Component_[5688118765544765547]": {
"$type": "EditorEntityIconComponent",
"Id": 5688118765544765547
},
"Component_[6545738857812235305]": {
"$type": "SelectionComponent",
"Id": 6545738857812235305
},
"Component_[7247035804068349658]": {
"$type": "EditorPrefabComponent",
"Id": 7247035804068349658
},
"Component_[9307224322037797205]": {
"$type": "EditorLockComponent",
"Id": 9307224322037797205
},
"Component_[9562516168917670048]": {
"$type": "EditorVisibilityComponent",
"Id": 9562516168917670048
}
}
}
}

@ -0,0 +1,12 @@
0,0,0,0,0,0
0,0,0,0,0,0
0,0,0,0,0,0
0,0,0,0,0,0
0,0,0,0,0,0
0,0,0,0,0,0
0,0,0,0,0,0
0,0,0,0,0,0
0,0,0,0,0,0
0,0,0,0,0,0
0,0,0,0,0,0
0,0,0,0,0,0

@ -0,0 +1,151 @@
{
"ContainerEntity": {
"Id": "ContainerEntity",
"Name": "Player",
"Components": {
"Component_[10626669441604518614]": {
"$type": "EditorPrefabComponent",
"Id": 10626669441604518614
},
"Component_[15284109105474306026]": {
"$type": "EditorVisibilityComponent",
"Id": 15284109105474306026
},
"Component_[1884250773831675865]": {
"$type": "SelectionComponent",
"Id": 1884250773831675865
},
"Component_[3027124663594865592]": {
"$type": "EditorInspectorComponent",
"Id": 3027124663594865592
},
"Component_[3314300526416851038]": {
"$type": "EditorEntitySortComponent",
"Id": 3314300526416851038,
"Child Entity Order": [
"Entity_[1340484004600]"
]
},
"Component_[5583377204116393478]": {
"$type": "EditorEntityIconComponent",
"Id": 5583377204116393478
},
"Component_[5897955848881060165]": {
"$type": "EditorLockComponent",
"Id": 5897955848881060165
},
"Component_[6405389103180201977]": {
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
"Id": 6405389103180201977,
"Parent Entity": ""
},
"Component_[7695912346724202125]": {
"$type": "EditorDisabledCompositionComponent",
"Id": 7695912346724202125
},
"Component_[775363990560391238]": {
"$type": "EditorOnlyEntityComponent",
"Id": 775363990560391238
},
"Component_[904355854135646057]": {
"$type": "EditorPendingCompositionComponent",
"Id": 904355854135646057
}
}
},
"Entities": {
"Entity_[1340484004600]": {
"Id": "Entity_[1340484004600]",
"Name": "Player",
"Components": {
"Component_[12294726333564087591]": {
"$type": "SelectionComponent",
"Id": 12294726333564087591
},
"Component_[13587084088242540786]": {
"$type": "EditorInspectorComponent",
"Id": 13587084088242540786,
"ComponentOrderEntryArray": [
{
"ComponentId": 6819443882832501114
},
{
"ComponentId": 4337571454344109612,
"SortIndex": 1
},
{
"ComponentId": 16457408099527309065,
"SortIndex": 2
},
{
"ComponentId": 5577505593558922067,
"SortIndex": 3
}
]
},
"Component_[14335168881008289852]": {
"$type": "EditorEntitySortComponent",
"Id": 14335168881008289852
},
"Component_[16308902899170829847]": {
"$type": "EditorVisibilityComponent",
"Id": 16308902899170829847
},
"Component_[16457408099527309065]": {
"$type": "GenericComponentWrapper",
"Id": 16457408099527309065,
"m_template": {
"$type": "Multiplayer::NetworkTransformComponent"
}
},
"Component_[16541569566865026527]": {
"$type": "EditorOnlyEntityComponent",
"Id": 16541569566865026527
},
"Component_[2002761223483048905]": {
"$type": "EditorPendingCompositionComponent",
"Id": 2002761223483048905
},
"Component_[4337571454344109612]": {
"$type": "GenericComponentWrapper",
"Id": 4337571454344109612,
"m_template": {
"$type": "NetBindComponent"
}
},
"Component_[477591477979440744]": {
"$type": "EditorLockComponent",
"Id": 477591477979440744
},
"Component_[5577505593558922067]": {
"$type": "AZ::Render::EditorMeshComponent",
"Id": 5577505593558922067,
"Controller": {
"Configuration": {
"ModelAsset": {
"assetId": {
"guid": "{6DE0E9A8-A1C7-5D0F-9407-4E627C1F223C}",
"subId": 284780167
},
"assetHint": "models/sphere.azmodel"
}
}
}
},
"Component_[5828214869455694702]": {
"$type": "EditorDisabledCompositionComponent",
"Id": 5828214869455694702
},
"Component_[6819443882832501114]": {
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
"Id": 6819443882832501114,
"Parent Entity": "ContainerEntity"
},
"Component_[8838623765985560328]": {
"$type": "EditorEntityIconComponent",
"Id": 8838623765985560328
}
}
}
}
}

@ -0,0 +1,580 @@
{
"ContainerEntity": {
"Id": "Entity_[1146574390643]",
"Name": "Level",
"Components": {
"Component_[10641544592923449938]": {
"$type": "EditorInspectorComponent",
"Id": 10641544592923449938
},
"Component_[12039882709170782873]": {
"$type": "EditorOnlyEntityComponent",
"Id": 12039882709170782873
},
"Component_[12265484671603697631]": {
"$type": "EditorPendingCompositionComponent",
"Id": 12265484671603697631
},
"Component_[14126657869720434043]": {
"$type": "EditorEntitySortComponent",
"Id": 14126657869720434043,
"Child Entity Order": [
"Entity_[1176639161715]",
"Entity_[806656324666]"
]
},
"Component_[15230859088967841193]": {
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
"Id": 15230859088967841193,
"Parent Entity": ""
},
"Component_[16239496886950819870]": {
"$type": "EditorDisabledCompositionComponent",
"Id": 16239496886950819870
},
"Component_[5688118765544765547]": {
"$type": "EditorEntityIconComponent",
"Id": 5688118765544765547
},
"Component_[6545738857812235305]": {
"$type": "SelectionComponent",
"Id": 6545738857812235305
},
"Component_[7247035804068349658]": {
"$type": "EditorPrefabComponent",
"Id": 7247035804068349658
},
"Component_[9307224322037797205]": {
"$type": "EditorLockComponent",
"Id": 9307224322037797205
},
"Component_[9562516168917670048]": {
"$type": "EditorVisibilityComponent",
"Id": 9562516168917670048
}
}
},
"Entities": {
"Entity_[1155164325235]": {
"Id": "Entity_[1155164325235]",
"Name": "Sun",
"Components": {
"Component_[10440557478882592717]": {
"$type": "SelectionComponent",
"Id": 10440557478882592717
},
"Component_[13620450453324765907]": {
"$type": "EditorLockComponent",
"Id": 13620450453324765907
},
"Component_[2134313378593666258]": {
"$type": "EditorInspectorComponent",
"Id": 2134313378593666258
},
"Component_[234010807770404186]": {
"$type": "EditorVisibilityComponent",
"Id": 234010807770404186
},
"Component_[2970359110423865725]": {
"$type": "EditorEntityIconComponent",
"Id": 2970359110423865725
},
"Component_[3722854130373041803]": {
"$type": "EditorOnlyEntityComponent",
"Id": 3722854130373041803
},
"Component_[5992533738676323195]": {
"$type": "EditorDisabledCompositionComponent",
"Id": 5992533738676323195
},
"Component_[7378860763541895402]": {
"$type": "AZ::Render::EditorDirectionalLightComponent",
"Id": 7378860763541895402,
"Controller": {
"Configuration": {
"Intensity": 1.0,
"CameraEntityId": "",
"ShadowFilterMethod": 1
}
}
},
"Component_[7892834440890947578]": {
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
"Id": 7892834440890947578,
"Parent Entity": "Entity_[1176639161715]",
"Transform Data": {
"Translate": [
0.0,
0.0,
13.487043380737305
],
"Rotate": [
-76.13099670410156,
-0.847000002861023,
-15.8100004196167
]
}
},
"Component_[8599729549570828259]": {
"$type": "EditorEntitySortComponent",
"Id": 8599729549570828259
},
"Component_[952797371922080273]": {
"$type": "EditorPendingCompositionComponent",
"Id": 952797371922080273
}
}
},
"Entity_[1159459292531]": {
"Id": "Entity_[1159459292531]",
"Name": "Ground",
"Components": {
"Component_[11701138785793981042]": {
"$type": "SelectionComponent",
"Id": 11701138785793981042
},
"Component_[12260880513256986252]": {
"$type": "EditorEntityIconComponent",
"Id": 12260880513256986252
},
"Component_[13711420870643673468]": {
"$type": "EditorDisabledCompositionComponent",
"Id": 13711420870643673468
},
"Component_[138002849734991713]": {
"$type": "EditorOnlyEntityComponent",
"Id": 138002849734991713
},
"Component_[16578565737331764849]": {
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
"Id": 16578565737331764849,
"Parent Entity": "Entity_[1176639161715]"
},
"Component_[16919232076966545697]": {
"$type": "EditorInspectorComponent",
"Id": 16919232076966545697
},
"Component_[5182430712893438093]": {
"$type": "EditorMaterialComponent",
"Id": 5182430712893438093
},
"Component_[5675108321710651991]": {
"$type": "AZ::Render::EditorMeshComponent",
"Id": 5675108321710651991,
"Controller": {
"Configuration": {
"ModelAsset": {
"assetId": {
"guid": "{0CD745C0-6AA8-569A-A68A-73A3270986C4}",
"subId": 277889906
},
"assetHint": "objects/groudplane/groundplane_512x512m.azmodel"
}
}
}
},
"Component_[5681893399601237518]": {
"$type": "EditorEntitySortComponent",
"Id": 5681893399601237518
},
"Component_[592692962543397545]": {
"$type": "EditorPendingCompositionComponent",
"Id": 592692962543397545
},
"Component_[7090012899106946164]": {
"$type": "EditorLockComponent",
"Id": 7090012899106946164
},
"Component_[9410832619875640998]": {
"$type": "EditorVisibilityComponent",
"Id": 9410832619875640998
}
}
},
"Entity_[1163754259827]": {
"Id": "Entity_[1163754259827]",
"Name": "Camera",
"Components": {
"Component_[11895140916889160460]": {
"$type": "EditorEntityIconComponent",
"Id": 11895140916889160460
},
"Component_[16880285896855930892]": {
"$type": "{CA11DA46-29FF-4083-B5F6-E02C3A8C3A3D} EditorCameraComponent",
"Id": 16880285896855930892,
"Controller": {
"Configuration": {
"Field of View": 55.0,
"EditorEntityId": 9021008456353177945
}
}
},
"Component_[17187464423780271193]": {
"$type": "EditorLockComponent",
"Id": 17187464423780271193
},
"Component_[17495696818315413311]": {
"$type": "EditorEntitySortComponent",
"Id": 17495696818315413311
},
"Component_[18086214374043522055]": {
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
"Id": 18086214374043522055,
"Parent Entity": "Entity_[1176639161715]",
"Transform Data": {
"Translate": [
-2.3000001907348633,
-3.9368600845336914,
1.0
],
"Rotate": [
-2.050307512283325,
1.9552897214889526,
-43.623355865478516
]
}
},
"Component_[18387556550380114975]": {
"$type": "SelectionComponent",
"Id": 18387556550380114975
},
"Component_[2654521436129313160]": {
"$type": "EditorVisibilityComponent",
"Id": 2654521436129313160
},
"Component_[5265045084611556958]": {
"$type": "EditorDisabledCompositionComponent",
"Id": 5265045084611556958
},
"Component_[7169798125182238623]": {
"$type": "EditorPendingCompositionComponent",
"Id": 7169798125182238623
},
"Component_[7255796294953281766]": {
"$type": "GenericComponentWrapper",
"Id": 7255796294953281766,
"m_template": {
"$type": "FlyCameraInputComponent"
}
},
"Component_[8866210352157164042]": {
"$type": "EditorInspectorComponent",
"Id": 8866210352157164042
},
"Component_[9129253381063760879]": {
"$type": "EditorOnlyEntityComponent",
"Id": 9129253381063760879
}
}
},
"Entity_[1168049227123]": {
"Id": "Entity_[1168049227123]",
"Name": "Grid",
"Components": {
"Component_[11443347433215807130]": {
"$type": "EditorEntityIconComponent",
"Id": 11443347433215807130
},
"Component_[11779275529534764488]": {
"$type": "SelectionComponent",
"Id": 11779275529534764488
},
"Component_[14249419413039427459]": {
"$type": "EditorInspectorComponent",
"Id": 14249419413039427459
},
"Component_[15448581635946161318]": {
"$type": "AZ::Render::EditorGridComponent",
"Id": 15448581635946161318,
"Controller": {
"Configuration": {
"primarySpacing": 4.0,
"primaryColor": [
0.501960813999176,
0.501960813999176,
0.501960813999176
],
"secondarySpacing": 0.5,
"secondaryColor": [
0.250980406999588,
0.250980406999588,
0.250980406999588
]
}
}
},
"Component_[1843303322527297409]": {
"$type": "EditorDisabledCompositionComponent",
"Id": 1843303322527297409
},
"Component_[380249072065273654]": {
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
"Id": 380249072065273654,
"Parent Entity": "Entity_[1176639161715]"
},
"Component_[7476660583684339787]": {
"$type": "EditorPendingCompositionComponent",
"Id": 7476660583684339787
},
"Component_[7557626501215118375]": {
"$type": "EditorEntitySortComponent",
"Id": 7557626501215118375
},
"Component_[7984048488947365511]": {
"$type": "EditorVisibilityComponent",
"Id": 7984048488947365511
},
"Component_[8118181039276487398]": {
"$type": "EditorOnlyEntityComponent",
"Id": 8118181039276487398
},
"Component_[9189909764215270515]": {
"$type": "EditorLockComponent",
"Id": 9189909764215270515
}
}
},
"Entity_[1176639161715]": {
"Id": "Entity_[1176639161715]",
"Name": "Atom Default Environment",
"Components": {
"Component_[10757302973393310045]": {
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
"Id": 10757302973393310045,
"Parent Entity": "Entity_[1146574390643]"
},
"Component_[14505817420424255464]": {
"$type": "EditorInspectorComponent",
"Id": 14505817420424255464,
"ComponentOrderEntryArray": [
{
"ComponentId": 10757302973393310045
}
]
},
"Component_[14988041764659020032]": {
"$type": "EditorLockComponent",
"Id": 14988041764659020032
},
"Component_[15808690248755038124]": {
"$type": "SelectionComponent",
"Id": 15808690248755038124
},
"Component_[15900837685796817138]": {
"$type": "EditorVisibilityComponent",
"Id": 15900837685796817138
},
"Component_[3298767348226484884]": {
"$type": "EditorOnlyEntityComponent",
"Id": 3298767348226484884
},
"Component_[4076975109609220594]": {
"$type": "EditorPendingCompositionComponent",
"Id": 4076975109609220594
},
"Component_[5679760548946028854]": {
"$type": "EditorDisabledCompositionComponent",
"Id": 5679760548946028854
},
"Component_[5855590796136709437]": {
"$type": "EditorEntitySortComponent",
"Id": 5855590796136709437,
"Child Entity Order": [
"Entity_[1155164325235]",
"Entity_[1180934129011]",
"Entity_[1168049227123]",
"Entity_[1163754259827]",
"Entity_[1159459292531]"
]
},
"Component_[9277695270015777859]": {
"$type": "EditorEntityIconComponent",
"Id": 9277695270015777859
}
}
},
"Entity_[1180934129011]": {
"Id": "Entity_[1180934129011]",
"Name": "Global Sky",
"Components": {
"Component_[11231930600558681245]": {
"$type": "AZ::Render::EditorHDRiSkyboxComponent",
"Id": 11231930600558681245,
"Controller": {
"Configuration": {
"CubemapAsset": {
"assetId": {
"guid": "{215E47FD-D181-5832-B1AB-91673ABF6399}",
"subId": 1000
},
"assetHint": "lightingpresets/highcontrast/goegap_4k_skyboxcm.exr.streamingimage"
}
}
}
},
"Component_[11980494120202836095]": {
"$type": "SelectionComponent",
"Id": 11980494120202836095
},
"Component_[1428633914413949476]": {
"$type": "EditorLockComponent",
"Id": 1428633914413949476
},
"Component_[14936200426671614999]": {
"$type": "AZ::Render::EditorImageBasedLightComponent",
"Id": 14936200426671614999,
"Controller": {
"Configuration": {
"diffuseImageAsset": {
"assetId": {
"guid": "{3FD09945-D0F2-55C8-B9AF-B2FD421FE3BE}",
"subId": 3000
},
"assetHint": "lightingpresets/highcontrast/goegap_4k_iblglobalcm_ibldiffuse.exr.streamingimage"
},
"specularImageAsset": {
"assetId": {
"guid": "{3FD09945-D0F2-55C8-B9AF-B2FD421FE3BE}",
"subId": 2000
},
"assetHint": "lightingpresets/highcontrast/goegap_4k_iblglobalcm_iblspecular.exr.streamingimage"
}
}
}
},
"Component_[14994774102579326069]": {
"$type": "EditorDisabledCompositionComponent",
"Id": 14994774102579326069
},
"Component_[15417479889044493340]": {
"$type": "EditorPendingCompositionComponent",
"Id": 15417479889044493340
},
"Component_[15826613364991382688]": {
"$type": "EditorEntitySortComponent",
"Id": 15826613364991382688
},
"Component_[1665003113283562343]": {
"$type": "EditorOnlyEntityComponent",
"Id": 1665003113283562343
},
"Component_[3704934735944502280]": {
"$type": "EditorEntityIconComponent",
"Id": 3704934735944502280
},
"Component_[5698542331457326479]": {
"$type": "EditorVisibilityComponent",
"Id": 5698542331457326479
},
"Component_[6644513399057217122]": {
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
"Id": 6644513399057217122,
"Parent Entity": "Entity_[1176639161715]"
},
"Component_[931091830724002070]": {
"$type": "EditorInspectorComponent",
"Id": 931091830724002070
}
}
},
"Entity_[806656324666]": {
"Id": "Entity_[806656324666]",
"Name": "NetEntity",
"Components": {
"Component_[10272449525230713408]": {
"$type": "EditorScriptCanvasComponent",
"Id": 10272449525230713408,
"m_name": "SimpleNetworkLevelEntity.scriptcanvas",
"runtimeDataIsValid": true,
"runtimeDataOverrides": {
"source": {
"id": "{C8F17F94-1225-5FFB-A89F-7C5546FF9DD2}",
"path": "C:/prj/o3de/AutomatedTesting/Levels/Multiplayer/SimpleNetworkLevelEntity/SimpleNetworkLevelEntity.scriptcanvas"
}
},
"sourceHandle": {
"id": "{C8F17F94-1225-5FFB-A89F-7C5546FF9DD2}",
"path": "C:/prj/o3de/AutomatedTesting/Levels/Multiplayer/SimpleNetworkLevelEntity/SimpleNetworkLevelEntity.scriptcanvas"
}
},
"Component_[12604265186664827718]": {
"$type": "EditorDisabledCompositionComponent",
"Id": 12604265186664827718
},
"Component_[12971088454284742740]": {
"$type": "EditorInspectorComponent",
"Id": 12971088454284742740
},
"Component_[13637345797899267673]": {
"$type": "EditorPendingCompositionComponent",
"Id": 13637345797899267673
},
"Component_[14691827217729577086]": {
"$type": "EditorVisibilityComponent",
"Id": 14691827217729577086
},
"Component_[17587769654029626028]": {
"$type": "AZ::Render::EditorMeshComponent",
"Id": 17587769654029626028,
"Controller": {
"Configuration": {
"ModelAsset": {
"assetId": {
"guid": "{6DE0E9A8-A1C7-5D0F-9407-4E627C1F223C}",
"subId": 284780167
},
"assetHint": "models/sphere.azmodel"
}
}
}
},
"Component_[3583806849894952953]": {
"$type": "EditorOnlyEntityComponent",
"Id": 3583806849894952953
},
"Component_[3992057042487734240]": {
"$type": "EditorLockComponent",
"Id": 3992057042487734240
},
"Component_[4205899043279271481]": {
"$type": "GenericComponentWrapper",
"Id": 4205899043279271481,
"m_template": {
"$type": "Multiplayer::NetworkTransformComponent"
}
},
"Component_[4416976521140638764]": {
"$type": "EditorEntityIconComponent",
"Id": 4416976521140638764
},
"Component_[4951162661196722987]": {
"$type": "EditorEntitySortComponent",
"Id": 4951162661196722987
},
"Component_[57491843687005111]": {
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
"Id": 57491843687005111,
"Parent Entity": "Entity_[1146574390643]",
"Transform Data": {
"Translate": [
-0.010266244411468506,
0.09999752044677734,
0.4922151565551758
]
}
},
"Component_[7427201282284088219]": {
"$type": "SelectionComponent",
"Id": 7427201282284088219
},
"Component_[9767802049284917261]": {
"$type": "GenericComponentWrapper",
"Id": 9767802049284917261,
"m_template": {
"$type": "NetBindComponent"
}
}
}
}
}
}

@ -0,0 +1,228 @@
{
"Type": "JsonSerialization",
"Version": 1,
"ClassName": "ScriptCanvasData",
"ClassData": {
"m_scriptCanvas": {
"Id": {
"id": 5227099818161821361
},
"Name": "Script Canvas Graph",
"Components": {
"Component_[14745706451564425001]": {
"$type": "EditorGraphVariableManagerComponent",
"Id": 14745706451564425001
},
"Component_[6188351434280490877]": {
"$type": "EditorGraph",
"Id": 6188351434280490877,
"m_graphData": {
"m_nodes": [
{
"Id": {
"id": 1181151842701
},
"Name": "SC-Node(Print)",
"Components": {
"Component_[11204048151736284490]": {
"$type": "Print",
"Id": 11204048151736284490,
"Slots": [
{
"id": {
"m_id": "{A417FF98-493E-4DE6-AD3A-E7A1848661E4}"
},
"contracts": [
{
"$type": "SlotTypeContract"
}
],
"slotName": "In",
"toolTip": "Input signal",
"Descriptor": {
"ConnectionType": 1,
"SlotType": 1
}
},
{
"id": {
"m_id": "{38BC2AB1-7654-407E-9903-4B5D77EDB6F3}"
},
"contracts": [
{
"$type": "SlotTypeContract"
}
],
"slotName": "Out",
"Descriptor": {
"ConnectionType": 2,
"SlotType": 1
}
}
],
"m_format": "SimpleNetworkLevelEntity: On Graph Start\n",
"m_unresolvedString": [
"SimpleNetworkLevelEntity: On Graph Start\n"
]
}
}
},
{
"Id": {
"id": 811784655245
},
"Name": "SC-Node(Start)",
"Components": {
"Component_[2986280341871382503]": {
"$type": "Start",
"Id": 2986280341871382503,
"Slots": [
{
"id": {
"m_id": "{61FBEFC6-23BA-4A53-89BF-D0D0E834608C}"
},
"contracts": [
{
"$type": "SlotTypeContract"
}
],
"slotName": "Out",
"toolTip": "Signaled when the entity that owns this graph is fully activated.",
"Descriptor": {
"ConnectionType": 2,
"SlotType": 1
}
}
]
}
}
}
],
"m_connections": [
{
"Id": {
"id": 2521181639053
},
"Name": "srcEndpoint=(On Graph Start: Out), destEndpoint=(Print: In)",
"Components": {
"Component_[16295428600276205051]": {
"$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection",
"Id": 16295428600276205051,
"sourceEndpoint": {
"nodeId": {
"id": 811784655245
},
"slotId": {
"m_id": "{61FBEFC6-23BA-4A53-89BF-D0D0E834608C}"
}
},
"targetEndpoint": {
"nodeId": {
"id": 1181151842701
},
"slotId": {
"m_id": "{A417FF98-493E-4DE6-AD3A-E7A1848661E4}"
}
}
}
}
}
]
},
"m_assetType": "{00000000-0000-0000-D033-B2489A010000}",
"versionData": {
"_grammarVersion": 1,
"_runtimeVersion": 1,
"_fileVersion": 1
},
"GraphCanvasData": [
{
"Key": {
"id": 811784655245
},
"Value": {
"ComponentData": {
"{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": {
"$type": "NodeSaveData"
},
"{328FF15C-C302-458F-A43D-E1794DE0904E}": {
"$type": "GeneralNodeTitleComponentSaveData",
"PaletteOverride": "TimeNodeTitlePalette"
},
"{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": {
"$type": "GeometrySaveData",
"Position": [
340.0,
180.0
]
},
"{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": {
"$type": "StylingComponentSaveData"
},
"{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": {
"$type": "PersistentIdComponentSaveData",
"PersistentId": "{6045F7F7-02B0-442A-96C7-A0CBCEFF7275}"
}
}
}
},
{
"Key": {
"id": 1181151842701
},
"Value": {
"ComponentData": {
"{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": {
"$type": "NodeSaveData"
},
"{328FF15C-C302-458F-A43D-E1794DE0904E}": {
"$type": "GeneralNodeTitleComponentSaveData",
"PaletteOverride": "StringNodeTitlePalette"
},
"{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": {
"$type": "GeometrySaveData",
"Position": [
580.0,
180.0
]
},
"{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": {
"$type": "StylingComponentSaveData"
},
"{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": {
"$type": "PersistentIdComponentSaveData",
"PersistentId": "{589F773E-D82A-4EDD-AEBD-3ADC07FC67CE}"
}
}
}
},
{
"Key": {
"id": 5227099818161821361
},
"Value": {
"ComponentData": {
"{5F84B500-8C45-40D1-8EFC-A5306B241444}": {
"$type": "SceneComponentSaveData"
}
}
}
}
],
"StatisticsHelper": {
"InstanceCounter": [
{
"Key": 4199610336680704683,
"Value": 1
},
{
"Key": 10684225535275896474,
"Value": 1
}
]
}
}
}
}
}
}

@ -0,0 +1,12 @@
0,0,0,0,0,0
0,0,0,0,0,0
0,0,0,0,0,0
0,0,0,0,0,0
0,0,0,0,0,0
0,0,0,0,0,0
0,0,0,0,0,0
0,0,0,0,0,0
0,0,0,0,0,0
0,0,0,0,0,0
0,0,0,0,0,0
0,0,0,0,0,0

@ -44,51 +44,11 @@ include(cmake/SettingsRegistry.cmake)
include(cmake/TestImpactFramework/LYTestImpactFramework.cmake) include(cmake/TestImpactFramework/LYTestImpactFramework.cmake)
include(cmake/CMakeFiles.cmake) include(cmake/CMakeFiles.cmake)
include(cmake/O3DEJson.cmake) include(cmake/O3DEJson.cmake)
include(cmake/Subdirectories.cmake)
################################################################################ # Gather the list of o3de_manifest external Subdirectories
# Subdirectory processing # into the LY_EXTERNAL_SUBDIRS_O3DE_MANIFEST_PROPERTY
################################################################################ add_o3de_manifest_json_external_subdirectories()
# this function is building up the LY_EXTERNAL_SUBDIRS global property
function(add_engine_gem_json_external_subdirectories gem_path)
set(gem_json_path ${gem_path}/gem.json)
if(EXISTS ${gem_json_path})
read_json_external_subdirs(gem_external_subdirs ${gem_path}/gem.json)
foreach(gem_external_subdir ${gem_external_subdirs})
file(REAL_PATH ${gem_external_subdir} real_external_subdir BASE_DIRECTORY ${gem_path})
set_property(GLOBAL APPEND PROPERTY LY_EXTERNAL_SUBDIRS ${real_external_subdir})
add_engine_gem_json_external_subdirectories(${real_external_subdir})
endforeach()
endif()
endfunction()
function(add_engine_json_external_subdirectories)
read_json_external_subdirs(engine_external_subdirs ${LY_ROOT_FOLDER}/engine.json)
foreach(engine_external_subdir ${engine_external_subdirs})
file(REAL_PATH ${engine_external_subdir} real_external_subdir BASE_DIRECTORY ${LY_ROOT_FOLDER})
set_property(GLOBAL APPEND PROPERTY LY_EXTERNAL_SUBDIRS ${real_external_subdir})
add_engine_gem_json_external_subdirectories(${real_external_subdir})
endforeach()
endfunction()
function(add_subdirectory_on_externalsubdirs)
get_property(external_subdirs GLOBAL PROPERTY LY_EXTERNAL_SUBDIRS)
list(APPEND LY_EXTERNAL_SUBDIRS ${external_subdirs})
# Loop over the additional external subdirectories and invoke add_subdirectory on them
foreach(external_directory ${LY_EXTERNAL_SUBDIRS})
# Hash the external_directory name and append it to the Binary Directory section of add_subdirectory
# This is to deal with potential situations where multiple external directories has the same last directory name
# For example if D:/Company1/RayTracingGem and F:/Company2/Path/RayTracingGem were both added as a subdirectory
file(REAL_PATH ${external_directory} full_directory_path)
string(SHA256 full_directory_hash ${full_directory_path})
# Truncate the full_directory_hash down to 8 characters to avoid hitting the Windows 260 character path limit
# when the external subdirectory contains relative paths of significant length
string(SUBSTRING ${full_directory_hash} 0 8 full_directory_hash)
# Use the last directory as the suffix path to use for the Binary Directory
get_filename_component(directory_name ${external_directory} NAME)
add_subdirectory(${external_directory} ${CMAKE_BINARY_DIR}/External/${directory_name}-${full_directory_hash})
endforeach()
endfunction()
# Add the projects first so the Launcher can find them # Add the projects first so the Launcher can find them
include(cmake/Projects.cmake) include(cmake/Projects.cmake)
@ -99,9 +59,11 @@ endif()
if(NOT INSTALLED_ENGINE) if(NOT INSTALLED_ENGINE)
# Add external subdirectories listed in the engine.json. LY_EXTERNAL_SUBDIRS is a cache variable so the user can add extra # Add external subdirectories listed in the engine.json. LY_EXTERNAL_SUBDIRS is a cache variable so the user can add extra
# external subdirectories. This should go before adding the rest of the targets so the targets are availbe to the launcher. # external subdirectories. This should go before adding the rest of the targets so the targets are available to the launcher.
add_engine_json_external_subdirectories() add_engine_json_external_subdirectories()
add_subdirectory_on_externalsubdirs()
# Invoke add_subdirectory on external subdirectories that should be used a this point
add_subdirectory_on_external_subdirs()
# Add the rest of the targets # Add the rest of the targets
add_subdirectory(Assets) add_subdirectory(Assets)
@ -114,7 +76,7 @@ if(NOT INSTALLED_ENGINE)
else() else()
ly_find_o3de_packages() ly_find_o3de_packages()
add_subdirectory_on_externalsubdirs() add_subdirectory_on_external_subdirs()
endif() endif()
################################################################################ ################################################################################

@ -1,73 +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
*
*/
#include "AzAssetBrowserWindow.h"
#include "AzAssetBrowser/ui_AssetBrowserWindow.h"
#include <AzToolsFramework/AssetBrowser/UI/AssetTreeView.h>
#include <AzToolsFramework/AssetBrowser/UI/SortFilterProxyModel.hxx>
#include <AzToolsFramework/AssetBrowser/UI/AssetBrowserModel.h>
#include <AzToolsFramework/AssetBrowser/AssetCache/AssetCacheBus.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserRequestBus.h>
const char* ASSET_BROWSER_PREVIEW_NAME = "Asset Browser (PREVIEW)";
AzAssetBrowserWindow::AzAssetBrowserWindow(const QString& name, QWidget* parent)
: QDialog(parent)
, m_ui(new Ui::AssetBrowserWindowClass())
, m_assetDatabaseSortFilterProxyModel(new AssetBrowser::UI::SortFilterProxyModel(parent))
, m_name(name)
, m_assetBrowser(new AssetBrowser::UI::AssetTreeView(name, this))
{
EBUS_EVENT_RESULT(m_assetBrowserModel, AssetBrowser::AssetCache::AssetCacheRequestsBus, GetAssetBrowserModel);
AZ_Assert(m_assetBrowserModel, "Failed to get filebrowser model");
m_assetDatabaseSortFilterProxyModel->setSourceModel(m_assetBrowserModel);
m_ui->setupUi(this);
connect(m_ui->searchCriteriaWidget,
&AzToolsFramework::SearchCriteriaWidget::SearchCriteriaChanged,
m_assetDatabaseSortFilterProxyModel.data(),
&AssetBrowser::UI::SortFilterProxyModel::OnSearchCriteriaChanged);
connect(m_assetBrowser, &QTreeView::customContextMenuRequested, this, &AzAssetBrowserWindow::OnContextMenu);
}
AzAssetBrowserWindow::~AzAssetBrowserWindow()
{
m_assetBrowser->SaveState();
}
//////////////////////////////////////////////////////////////////////////
const AZ::Uuid& AzAssetBrowserWindow::GetClassID()
{
return AZ::AzTypeInfo<AzAssetBrowserWindow>::Uuid();
}
void AzAssetBrowserWindow::OnContextMenu(const QPoint& point)
{
(void)point;
//get the selected entries
QModelIndexList sourceIndexes;
for (const auto& index : m_assetBrowser->selectedIndexes())
{
sourceIndexes.push_back(m_assetDatabaseSortFilterProxyModel->mapToSource(index));
}
AZStd::vector<AssetBrowser::UI::Entry*> entries;
m_assetBrowserModel->SourceIndexesToAssetDatabaseEntries(sourceIndexes, entries);
if (entries.empty() || entries.size() > 1)
{
return;
}
auto entry = entries.front();
EBUS_EVENT(AssetBrowser::AssetBrowserRequestBus::Bus, OnItemContextMenu, this, entry);
}
#include <AzAssetBrowser/moc_AzAssetBrowserWindow.cpp>

@ -1,57 +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
*
*/
#pragma once
#if !defined(Q_MOC_RUN)
#include <AzCore/Memory/SystemAllocator.h>
#include <AzCore/Math/Uuid.h>
#include <QDialog>
#endif
namespace Ui
{
class AssetBrowserWindowClass;
}
namespace AssetBrowser
{
namespace UI
{
class AssetTreeView;
class SortFilterProxyModel;
class AssetBrowserModel;
}
}
class AzAssetBrowserWindow
: public QDialog
{
Q_OBJECT
public:
AZ_CLASS_ALLOCATOR(AzAssetBrowserWindow, AZ::SystemAllocator, 0);
AZ_TYPE_INFO(AzAssetBrowserWindow, "{20238D23-2670-44BC-9110-A51374C18B5A}");
explicit AzAssetBrowserWindow(const QString& name = "default", QWidget* parent = nullptr);
virtual ~AzAssetBrowserWindow();
static const AZ::Uuid& GetClassID();
protected Q_SLOTS:
void OnContextMenu(const QPoint& point);
private:
QScopedPointer<Ui::AssetBrowserWindowClass> m_ui;
QScopedPointer<AssetBrowser::UI::AssetBrowserModel> m_assetDatabaseModel;
QScopedPointer<AssetBrowser::UI::SortFilterProxyModel> m_assetDatabaseSortFilterProxyModel;
QString m_name;
AssetBrowser::UI::AssetTreeView* m_assetBrowser;
AssetBrowser::UI::AssetBrowserModel* m_assetBrowserModel;
};
extern const char* ASSET_BROWSER_PREVIEW_NAME;

@ -1,186 +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
*
*/
#include "EditorDefs.h"
#include "CVarMenu.h"
CVarMenu::CVarMenu(QWidget* parent)
: QMenu(parent)
{
}
void CVarMenu::AddCVarToggleItem(CVarToggle cVarToggle)
{
// Add CVar toggle action
QAction* action = addAction(cVarToggle.m_displayName);
connect(action, &QAction::triggered, [this, cVarToggle](bool checked)
{
// Update the CVar's value based on the action's new checked state
ICVar* cVar = gEnv->pConsole->GetCVar(cVarToggle.m_cVarName.toUtf8().data());
if (cVar)
{
SetCVar(cVar, checked ? cVarToggle.m_onValue : cVarToggle.m_offValue);
}
});
action->setCheckable(true);
// Initialize the action's checked state based on the associated CVar's value
ICVar* cVar = gEnv->pConsole->GetCVar(cVarToggle.m_cVarName.toUtf8().data());
bool checked = (cVar && cVar->GetFVal() == cVarToggle.m_onValue);
action->setChecked(checked);
}
void CVarMenu::AddCVarValuesItem(QString cVarName,
QString displayName,
CVarDisplayNameValuePairs availableCVarValues,
float offValue)
{
// Add a submenu offering multiple values for one CVar
QMenu* menu = addMenu(displayName);
QActionGroup* group = new QActionGroup(menu);
group->setExclusive(true);
ICVar* cVar = gEnv->pConsole->GetCVar(cVarName.toUtf8().data());
float cVarValue = cVar ? cVar->GetFVal() : 0.0f;
for (const auto& availableCVarValue : availableCVarValues)
{
QAction* action = menu->addAction(availableCVarValue.first);
action->setCheckable(true);
group->addAction(action);
float availableOnValue = availableCVarValue.second;
connect(action, &QAction::triggered, [this, action, cVarName, availableOnValue, offValue](bool checked)
{
ICVar* cVar = gEnv->pConsole->GetCVar(cVarName.toUtf8().data());
if (cVar)
{
if (!checked)
{
SetCVar(cVar, offValue);
}
else
{
// Toggle the CVar and update the action's checked state to
// allow none of the items to be checked in the exclusive group.
// Otherwise we could have just used the action's currently checked
// state and updated the CVar's value only
bool cVarOn = (cVar->GetFVal() == availableOnValue);
checked = !cVarOn;
SetCVar(cVar, checked ? availableOnValue : offValue);
action->setChecked(checked);
}
}
});
// Initialize the action's checked state based on the CVar's current value
bool checked = (cVarValue == availableOnValue);
action->setChecked(checked);
}
}
void CVarMenu::AddUniqueCVarsItem(QString displayName,
AZStd::vector<CVarToggle> availableCVars)
{
// Add a submenu of actions offering values for unique CVars
QMenu* menu = addMenu(displayName);
QActionGroup* group = new QActionGroup(menu);
group->setExclusive(true);
for (const CVarToggle& availableCVar : availableCVars)
{
QAction* action = menu->addAction(availableCVar.m_displayName);
action->setCheckable(true);
group->addAction(action);
connect(action, &QAction::triggered, [this, action, availableCVar, availableCVars](bool checked)
{
ICVar* cVar = gEnv->pConsole->GetCVar(availableCVar.m_cVarName.toUtf8().data());
if (cVar)
{
if (!checked)
{
SetCVar(cVar, availableCVar.m_offValue);
}
else
{
// Toggle the CVar and update the action's checked state to
// allow none of the items to be checked in the exclusive group.
// Otherwise we could have just used the action's currently checked
// state and updated the CVar's value only
bool cVarOn = (cVar->GetFVal() == availableCVar.m_onValue);
bool cVarChecked = !cVarOn;
SetCVar(cVar, cVarChecked ? availableCVar.m_onValue : availableCVar.m_offValue);
action->setChecked(cVarChecked);
if (cVarChecked)
{
// Set the rest of the CVars in the group to their off values
SetCVarsToOffValue(availableCVars, availableCVar);
}
}
}
});
// Initialize the action's checked state based on its associated CVar's current value
ICVar* cVar = gEnv->pConsole->GetCVar(availableCVar.m_cVarName.toUtf8().data());
bool cVarChecked = (cVar && cVar->GetFVal() == availableCVar.m_onValue);
action->setChecked(cVarChecked);
if (cVarChecked)
{
// Set the rest of the CVars in the group to their off values
SetCVarsToOffValue(availableCVars, availableCVar);
}
}
}
void CVarMenu::AddResetCVarsItem()
{
QAction* action = addAction(tr("Reset to Default"));
connect(action, &QAction::triggered, this, [this]()
{
for (auto it : m_originalCVarValues)
{
ICVar* cVar = gEnv->pConsole->GetCVar(it.first.c_str());
if (cVar)
{
cVar->Set(it.second);
}
}
});
}
void CVarMenu::SetCVarsToOffValue(const AZStd::vector<CVarToggle>& cVarToggles, const CVarToggle& excludeCVarToggle)
{
// Set all but the specified CVars to their off values
for (const CVarToggle& cVarToggle : cVarToggles)
{
if (cVarToggle.m_cVarName != excludeCVarToggle.m_cVarName
|| cVarToggle.m_onValue != excludeCVarToggle.m_onValue)
{
ICVar* cVar = gEnv->pConsole->GetCVar(cVarToggle.m_cVarName.toUtf8().data());
if (cVar)
{
SetCVar(cVar, cVarToggle.m_offValue);
}
}
}
}
void CVarMenu::SetCVar(ICVar* cVar, float newValue)
{
float oldValue = cVar->GetFVal();
cVar->Set(newValue);
// Store original value for CVar if not already in the list
m_originalCVarValues.emplace(AZStd::string(cVar->GetName()), oldValue);
}
void CVarMenu::AddSeparator()
{
addSeparator();
}

@ -1,65 +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
*
*/
#pragma once
#include <QMenu>
#include <QString>
#include <AzCore/std/string/string.h>
#include <AzCore/std/containers/unordered_map.h>
#include <AzCore/std/containers/vector.h>
#include <AzCore/std/utils.h>
struct ICVar;
class CVarMenu
: public QMenu
{
Q_OBJECT
public:
// CVar that can be toggled on and off
struct CVarToggle
{
QString m_cVarName;
QString m_displayName;
float m_onValue;
float m_offValue;
};
// List of a CVar's available values and their descriptions
using CVarDisplayNameValuePairs = AZStd::vector<AZStd::pair<QString, float>>;
CVarMenu(QWidget* parent = nullptr);
// Add an action that turns a CVar on/off
void AddCVarToggleItem(CVarToggle cVarToggle);
// Add a submenu of actions for a CVar that offers multiple values for exclusive selection
void AddCVarValuesItem(QString cVarName,
QString displayName,
CVarDisplayNameValuePairs availableCVarValues,
float offValue);
// Add a submenu of actions for exclusively turning unique CVars on/off
void AddUniqueCVarsItem(QString displayName,
AZStd::vector<CVarToggle> availableCVars);
// Add an action to reset all CVars to their original values before they
// were modified by this menu
void AddResetCVarsItem();
void AddSeparator();
private:
void SetCVarsToOffValue(const AZStd::vector<CVarToggle>& cVarToggles, const CVarToggle& excludeCVarToggle);
void SetCVar(ICVar* cVar, float newValue);
// Original CVar values before they were modified by this menu
AZStd::unordered_map<AZStd::string, float> m_originalCVarValues;
};

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

Loading…
Cancel
Save