Integrating latest 47acbe8

This commit is contained in:
alexpete
2021-03-25 13:57:57 -07:00
parent 448c549698
commit 75dc720198
10312 changed files with 2711566 additions and 671451 deletions
@@ -0,0 +1,49 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
#
# This is a pytest module to test the in-Editor Python API from PythonEditorFuncs
#
import pytest
pytest.importorskip('ly_test_tools')
import sys
import os
sys.path.append(os.path.dirname(__file__))
from hydra_utils import launch_test_case
@pytest.mark.SUITE_sandbox
@pytest.mark.parametrize('launcher_platform', ['windows_editor'])
@pytest.mark.parametrize('project', ['AutomatedTesting'])
@pytest.mark.parametrize('level', ['Simple'])
class TestGradientRequiresShape(object):
def test_ComponentAsset(self, request, editor, level, launcher_platform):
unexpected_lines=[]
expected_lines = [
"New entity with no parent created: SUCCESS",
"Mesh component added to entity: SUCCESS",
"Entity has a Mesh component: SUCCESS",
"GetSetCompare Test MeshComponentRenderNode|Mesh asset: SUCCESS",
"GetSetCompare Clear MeshComponentRenderNode|Mesh asset: SUCCESS",
"PTE Test MeshComponentRenderNode|Mesh asset: SUCCESS",
"PTE Clear MeshComponentRenderNode|Mesh asset: SUCCESS",
"GetSetCompare Test MeshComponentRenderNode|Material override: SUCCESS",
"GetSetCompare Clear MeshComponentRenderNode|Material override: SUCCESS",
"PTE Test MeshComponentRenderNode|Material override: SUCCESS",
"PTE Clear MeshComponentRenderNode|Material override: SUCCESS",
]
test_case_file = os.path.join(os.path.dirname(__file__), 'ComponentAssetCommands_test_case.py')
launch_test_case(editor, test_case_file, expected_lines, unexpected_lines)
@@ -0,0 +1,141 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
# Tests a portion of the Component Property Get/Set Python API while the Editor is running
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.entity as entity
import azlmbr.math as math
import azlmbr.asset as asset
# Open a level (any level should work)
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'OpenLevelNoPrompt', 'WaterSample')
def GetSetCompareTest(component, path, assetId):
# Test Get/Set (get old value, set new value, check that new value was set correctly)
oldObj = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentProperty', component, path)
if(oldObj.IsSuccess()):
oldValue = oldObj.GetValue()
oldValueCompared = editor.EditorComponentAPIBus(bus.Broadcast, 'CompareComponentProperty', component, path, oldValue)
editor.EditorComponentAPIBus(bus.Broadcast, 'SetComponentProperty', component, path, assetId)
newObj = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentProperty', component, path)
if(newObj.IsSuccess()):
newValue = newObj.GetValue()
newValueCompared = editor.EditorComponentAPIBus(bus.Broadcast, 'CompareComponentProperty', component, path, newValue)
isOldNewValueSame = editor.EditorComponentAPIBus(bus.Broadcast, 'CompareComponentProperty', component, path, oldValue)
if not(newValue == oldValue) and oldValueCompared and newValueCompared and not isOldNewValueSame:
print("GetSetCompare Test " + path + ": SUCCESS")
else:
print("GetSetCompare Test " + path + ": FAILURE")
# Test Clear (set an invalid AssetId, check that the field was cleared correctly)
editor.EditorComponentAPIBus(bus.Broadcast, 'SetComponentProperty', component, path, asset.AssetId())
clearObj = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentProperty', component, path)
if(clearObj.IsSuccess()):
clearValue = clearObj.GetValue()
clearedValueCompared = editor.EditorComponentAPIBus(bus.Broadcast, 'CompareComponentProperty', component, path, clearValue)
isNewClearedValueSame = editor.EditorComponentAPIBus(bus.Broadcast, 'CompareComponentProperty', component, path, newValue)
if (clearValue == asset.AssetId()) and clearedValueCompared and not isNewClearedValueSame:
print("GetSetCompare Clear " + path + ": SUCCESS")
else:
print("GetSetCompare Clear " + path + ": FAILURE")
def PteTest(pte, path, value):
# Test Get/Set (get old value, set new value, check that new value was set correctly)
oldObj = pte.get_value(path)
if(oldObj.IsSuccess()):
oldValue = oldObj.GetValue()
oldValueCompared = pte.compare_value(path, oldValue)
pte.set_value(path, value)
newObj = pte.get_value(path)
if(newObj.IsSuccess()):
newValue = newObj.GetValue()
newValueCompared = pte.compare_value(path, newValue)
isOldNewValueSame = pte.compare_value(path, oldValue)
if not(newValue == oldValue) and oldValueCompared and newValueCompared and not isOldNewValueSame:
print("PTE Test " + path + ": SUCCESS")
else:
print("PTE Test " + path + ": FAILURE")
# Test Clear (set an invalid AssetId, check that the field was cleared correctly)
pte.set_value(path, asset.AssetId())
clearObj = pte.get_value(path)
if(clearObj.IsSuccess()):
clearValue = clearObj.GetValue()
clearedValueCompared = pte.compare_value(path, clearValue)
isNewClearedValueSame = pte.compare_value(path, newValue)
if (clearValue == asset.AssetId()) and clearedValueCompared and not isNewClearedValueSame:
print("PTE Clear " + path + ": SUCCESS")
else:
print("PTE Clear " + path + ": FAILURE")
# Create new Entity
entityId = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', entity.EntityId())
if (entityId):
print("New entity with no parent created: SUCCESS")
# Get Component Type for Mesh
typeIdsList = editor.EditorComponentAPIBus(bus.Broadcast, 'FindComponentTypeIdsByEntityType', ["Mesh"], entity.EntityType().Game)
componentOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentsOfType', entityId, typeIdsList)
if (componentOutcome.IsSuccess()):
print("Mesh component added to entity: SUCCESS")
components = componentOutcome.GetValue()
component = components[0]
hasComponent = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', entityId, typeIdsList[0])
if(hasComponent):
print("Entity has a Mesh component: SUCCESS")
# Get the PTE from the Mesh Component
pteObj = editor.EditorComponentAPIBus(bus.Broadcast, 'BuildComponentPropertyTreeEditor', component)
if(pteObj.IsSuccess()):
pte = pteObj.GetValue()
# Tests for the Asset<> case
cubeId = asset.AssetCatalogRequestBus(bus.Broadcast, 'GetAssetIdByPath', 'objects/default/primitive_cube.cgf', math.Uuid(), False)
GetSetCompareTest(component, "MeshComponentRenderNode|Mesh asset", cubeId)
PteTest(pte, "MeshComponentRenderNode|Mesh asset", cubeId)
# Tests for the SimpleAssetReference case
materialId = asset.AssetCatalogRequestBus(bus.Broadcast, 'GetAssetIdByPath', 'engineassets/texturemsg/defaultsolids.mtl', math.Uuid(), False)
GetSetCompareTest(component, "MeshComponentRenderNode|Material override", materialId)
PteTest(pte, "MeshComponentRenderNode|Material override", materialId)
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'ExitNoPrompt')
@@ -0,0 +1,63 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
#
# This is a pytest module to test the in-Editor Python API from PythonEditorFuncs
#
import pytest
pytest.importorskip('ly_test_tools')
import sys
import os
sys.path.append(os.path.dirname(__file__))
from hydra_utils import launch_test_case
@pytest.mark.skip # SPEC-4102
@pytest.mark.SUITE_sandbox
@pytest.mark.parametrize('launcher_platform', ['windows_editor'])
@pytest.mark.parametrize('project', ['AutomatedTesting'])
@pytest.mark.parametrize('level', ['Simple'])
class TestComponentCommands(object):
def test_MeshComponentBasics(self, request, editor, level, launcher_platform):
unexpected_lines=[]
expected_lines = [
"Type Ids List returned correctly",
"Type Names List returned correctly",
"New entity with no parent created",
"Entity does not have a Mesh component",
"Mesh component added to entity",
"EntityId on the meshComponent EntityComponentIdPair matches",
"EntityComponentIdPair to_string works",
"Entity has a Mesh component",
"Mesh component is active",
"Mesh component is not active",
"Mesh component is valid",
"Comment components added to entity",
"Got both Comment components",
"GetComponent works",
"Entity has two Comment components",
"Disabled both Comment components",
"Enabled both Comment components",
"Mesh Component removed",
"Mesh component is no longer valid",
"Single comment component added to entity",
"Entity has three Comment components",
"Mesh Collider component added to entity",
"Mesh Collider component retrieved from entity",
"Mesh Collider component removed from entity"
]
test_case_file = os.path.join(os.path.dirname(__file__), 'ComponentCommands_test_case.py')
launch_test_case(editor, test_case_file, expected_lines, unexpected_lines)
@@ -0,0 +1,193 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
# Tests a portion of the Component CRUD Python API while the Editor is running
import azlmbr.bus as bus
import azlmbr.entity as entity
import azlmbr.editor as editor
import azlmbr.object
import azlmbr.math
from azlmbr.entity import EntityId
def CompareComponentEntityIdPairs(component1, component2):
return component1.Equal(component2)
# Open a level (any level should work)
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'OpenLevelNoPrompt', 'WaterSample')
# Get Component Types for Mesh and Comment
typeIdsList = editor.EditorComponentAPIBus(bus.Broadcast, 'FindComponentTypeIdsByEntityType', ["Mesh", "Comment", "Mesh Collider"], entity.EntityType().Game)
if(len(typeIdsList) > 0):
print("Type Ids List returned correctly")
meshComponentTypeId = typeIdsList[0]
commentComponentTypeId = typeIdsList[1]
meshColliderComponentTypeId = typeIdsList[2]
# Get Component Ids from Component Types
typeNamesList = editor.EditorComponentAPIBus(bus.Broadcast, 'FindComponentTypeNames', typeIdsList)
if(typeNamesList[0] == "Mesh") and (typeNamesList[1] == "Comment") and (typeNamesList[2] == "Mesh Collider"):
print("Type Names List returned correctly")
# Test Component API
newEntityId = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', EntityId())
if (newEntityId):
print("New entity with no parent created")
hadComponent = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId, meshComponentTypeId)
if not(hadComponent):
print("Entity does not have a Mesh component")
meshComponentOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentsOfType', newEntityId, [meshComponentTypeId])
if (meshComponentOutcome.IsSuccess()):
print("Mesh component added to entity")
meshComponents = meshComponentOutcome.GetValue()
meshComponent = meshComponents[0]
if(meshComponent.get_entity_id() == newEntityId):
print("EntityId on the meshComponent EntityComponentIdPair matches")
if not(meshComponent.to_string() == ""):
print("EntityComponentIdPair to_string works")
hasComponent = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId, meshComponentTypeId)
if(hasComponent):
print("Entity has a Mesh component")
isActive = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', meshComponent)
if(isActive):
print("Mesh component is active")
editor.EditorComponentAPIBus(bus.Broadcast, 'DisableComponents', [meshComponent])
isNotActive = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', meshComponent)
if not(isNotActive):
print("Mesh component is not active")
if(editor.EditorComponentAPIBus(bus.Broadcast, 'IsValid', meshComponent)):
print("Mesh component is valid")
CommentComponentsOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentsOfType', newEntityId, [commentComponentTypeId, commentComponentTypeId])
if (CommentComponentsOutcome.IsSuccess()):
print("Comment components added to entity")
CommentComponents = CommentComponentsOutcome.GetValue()
GetCommentComponentsOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentsOfType', newEntityId, commentComponentTypeId)
if(GetCommentComponentsOutcome.IsSuccess()):
GetCommentComponents = GetCommentComponentsOutcome.GetValue()
if(CompareComponentEntityIdPairs(CommentComponents[0], GetCommentComponents[0]) and CompareComponentEntityIdPairs(CommentComponents[1], GetCommentComponents[1])):
print("Got both Comment components")
if(CompareComponentEntityIdPairs(CommentComponents[0], GetCommentComponents[1]) and CompareComponentEntityIdPairs(CommentComponents[1], GetCommentComponents[0])):
print("Got both Comment components")
GetComponentOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', newEntityId, meshComponentTypeId)
if(GetComponentOutcome.IsSuccess() and CompareComponentEntityIdPairs(GetComponentOutcome.GetValue(), meshComponent)):
print("GetComponent works")
commentsCount = editor.EditorComponentAPIBus(bus.Broadcast, 'CountComponentsOfType', newEntityId, commentComponentTypeId)
if(commentsCount == 2):
print("Entity has two Comment components")
editor.EditorComponentAPIBus(bus.Broadcast, 'DisableComponents', CommentComponents)
isCActive = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', CommentComponents[0])
isC2Active = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', CommentComponents[1])
if not(isCActive) and not(isC2Active):
print("Disabled both Comment components")
editor.EditorComponentAPIBus(bus.Broadcast, 'EnableComponents', CommentComponents)
isCActive = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', CommentComponents[0])
isC2Active = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', CommentComponents[1])
if (isCActive) and (isC2Active):
print("Enabled both Comment components")
editor.EditorComponentAPIBus(bus.Broadcast, 'RemoveComponents', [meshComponent])
hasMesh = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId, meshComponentTypeId)
componentSingleOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentOfType', newEntityId, commentComponentTypeId)
if (componentSingleOutcome.IsSuccess()):
print("Single comment component added to entity")
commentsCount = editor.EditorComponentAPIBus(bus.Broadcast, 'CountComponentsOfType', newEntityId, commentComponentTypeId)
if (commentsCount == 3):
print("Entity has three Comment components")
if not(hasMesh):
print("Mesh Component removed")
if not(editor.EditorComponentAPIBus(bus.Broadcast, 'IsValid', meshComponent)):
print("Mesh component is no longer valid")
# Test that it is possible to access Components with no Editor Component (for example, the legacy mesh collider)
meshColliderComponentOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentsOfType', newEntityId, [meshColliderComponentTypeId])
if (meshColliderComponentOutcome.IsSuccess()):
print("Mesh Collider component added to entity")
meshColliderComponent = meshColliderComponentOutcome.GetValue()
getMeshColliderComponentOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', newEntityId, meshComponentTypeId)
if(getMeshColliderComponentOutcome.IsSuccess() and CompareComponentEntityIdPairs(meshColliderComponent, getMeshColliderComponentOutcome.GetValue())):
print("Mesh Collider component retrieved from entity")
editor.EditorComponentAPIBus(bus.Broadcast, 'RemoveComponents', [meshColliderComponent])
hasMeshCollider = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId, meshColliderComponentTypeId)
if not(hasMeshCollider):
print("Mesh Collider Component removed")
# Test that it is possible to access Components with no Editor Component(for example, the legacy mesh collider) via GetComponentOfType
meshColliderComponentOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentsOfType', newEntityId, [meshColliderComponentTypeId])
if (meshColliderComponentOutcome.IsSuccess()):
print("Mesh Collider component added to entity")
meshColliderComponent = meshColliderComponentOutcome.GetValue()[0]
getMeshColliderComponentOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', newEntityId, meshColliderComponentTypeId)
if(getMeshColliderComponentOutcome.IsSuccess() and CompareComponentEntityIdPairs(meshColliderComponent, getMeshColliderComponentOutcome.GetValue())):
print("Mesh Collider component retrieved from entity")
meshColliderRemoved = False;
meshColliderRemoved = editor.EditorComponentAPIBus(bus.Broadcast, 'RemoveComponents', [meshColliderComponent])
if meshColliderRemoved:
print("Mesh Collider component removed from entity")
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'ExitNoPrompt')
@@ -0,0 +1,28 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
# LY-107818 reported a crash with this code snippet
# This new test will be used to regress test the issue
import azlmbr.bus as bus
import azlmbr.editor as editor
try:
componentList = editor.EditorComponentAPIBus(bus.Broadcast, 'BuildComponentTypeNameList')
if(componentList is not None and len(componentList) > 0):
print("BuildComponentTypeNameList returned a valid list: SUCCESS")
print("BuildComponentTypeNameList ran: SUCCESS")
except:
print("BuildComponentTypeNameList usage threw an exception: FAILURE")
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'ExitNoPrompt')
@@ -0,0 +1,120 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
#
# This is a pytest module to test the in-Editor Python API from PythonEditorFuncs
#
import pytest
pytest.importorskip('ly_test_tools')
import sys
import os
sys.path.append(os.path.dirname(__file__))
from hydra_utils import launch_test_case
@pytest.mark.SUITE_sandbox
@pytest.mark.parametrize('launcher_platform', ['windows_editor'])
@pytest.mark.parametrize('project', ['AutomatedTesting'])
@pytest.mark.parametrize('level', ['Simple'])
class TestGradientRequiresShape(object):
@pytest.mark.skip # SPEC-4102
def test_ComponentProperty(self, request, editor, level, launcher_platform):
unexpected_lines=[]
expected_lines = [
"New entity with no parent created",
"Environment Probe component added to entity",
"Entity has an Environment Probe component",
"get_paths_list works",
"GetSetCompareTest Settings|General Settings|Visible: SUCCESS",
"GetSetCompareTest Settings|Animation|Style: SUCCESS",
"GetSetCompareTest Settings|Environment Probe Settings|Box height: SUCCESS",
"GetSetCompareTest Settings|General Settings|Color: SUCCESS",
"GetSetCompareTest Settings|Environment Probe Settings|Area dimensions: SUCCESS",
"PteTest Settings|General Settings|Visible: SUCCESS",
"PteTest Settings|Animation|Style: SUCCESS",
"PteTest Settings|Environment Probe Settings|Box height: SUCCESS",
"PteTest Settings|General Settings|Color: SUCCESS",
"PteTest Settings|Environment Probe Settings|Area dimensions: SUCCESS",
]
test_case_file = os.path.join(os.path.dirname(__file__), 'ComponentPropertyCommands_test_case.py')
launch_test_case(editor, test_case_file, expected_lines, unexpected_lines)
@pytest.mark.skip # SPEC-4102
def test_SetDistance_Between_FilterBound_Mode(self, request, editor, level, launcher_platform):
unexpected_lines = ['FAILURE', 'script failure']
expected_lines = [
"New entity with no parent created: SUCCESS",
"Components added to entity: SUCCESS",
"Found Vegetation Distance Between Filter: SUCCESS",
"CompareComponentProperty - Configuration|Bound Mode: SUCCESS",
"GetSetCompareTest - Configuration|Bound Mode: SUCCESS"
]
test_case_file = os.path.join(os.path.dirname(__file__), 'ComponentPropertyCommands_test_enum.py')
launch_test_case(editor, test_case_file, expected_lines, unexpected_lines)
@pytest.mark.skip # LYN-1951
def test_PropertyTreeVisibility(self, request, editor, level, launcher_platform):
unexpected_lines = ['FAILURE', 'script failure']
expected_lines = [
"oceanEntityId was found: SUCCESS",
"Found Infinite Ocean component ID: SUCCESS",
"Created a PropertyTreeEditor for the infiniteOceanId: SUCCESS",
"Found proprety hidden node in path: SUCCESS",
"Proprety node is now a hidden path: SUCCESS",
"Property path enforcement of visibility: SUCCESS"
]
test_case_file = os.path.join(os.path.dirname(__file__), 'ComponentPropertyCommands_test_case_visibility.py')
launch_test_case(editor, test_case_file, expected_lines, unexpected_lines)
@pytest.mark.skip # SPEC-4102
def test_PropertyContainerOpeartions(self, request, editor, level, launcher_platform):
unexpected_lines = ['FAILURE', 'script failure']
expected_lines = [
"New entity with no parent created: SUCCESS",
"GradientSurfaceDataComponent added to entity :SUCCESS",
"Has zero items: SUCCESS",
"Add an item 0: SUCCESS",
"Has one item 0: SUCCESS",
"Add an item 1: SUCCESS",
"Add an item 2: SUCCESS",
"Add an item 3: SUCCESS",
"Has four items: SUCCESS",
"Updated an item: SUCCESS",
"itemTag equals tagFour: SUCCESS",
"Removed one item 0: SUCCESS",
"Removed one item 1: SUCCESS",
"Has two items: SUCCESS",
"Reset items: SUCCESS",
"Has cleared the items: SUCCESS"
]
test_case_file = os.path.join(os.path.dirname(__file__), 'ComponentPropertyCommands_test_containers.py')
launch_test_case(editor, test_case_file, expected_lines, unexpected_lines)
@pytest.mark.skip # LYN-1951
def test_PropertyContainerOpeartionWithNone(self, request, editor, level, launcher_platform):
unexpected_lines = ['FAILURE', 'script failure']
expected_lines = [
"material current is valid - True: SUCCESS",
"material set to None: SUCCESS",
"material has been set to None: SUCCESS"
]
test_case_file = os.path.join(os.path.dirname(__file__), 'ComponentPropertyCommands_test_case_set_none.py')
launch_test_case(editor, test_case_file, expected_lines, unexpected_lines)
@@ -0,0 +1,142 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
# Tests a portion of the Component Property Get/Set Python API while the Editor is running
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.entity as entity
import azlmbr.math as math
# Open a level (any level should work)
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'OpenLevelNoPrompt', 'WaterSample')
def GetSetCompareTest(component, path, value):
oldObj = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentProperty', component, path)
if(oldObj.IsSuccess()):
oldValue = oldObj.GetValue()
oldValueCompared = editor.EditorComponentAPIBus(bus.Broadcast, 'CompareComponentProperty', component, path, oldValue)
editor.EditorComponentAPIBus(bus.Broadcast, 'SetComponentProperty', component, path, value)
newObj = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentProperty', component, path)
if(newObj.IsSuccess()):
newValue = newObj.GetValue()
newValueCompared = editor.EditorComponentAPIBus(bus.Broadcast, 'CompareComponentProperty', component, path, newValue)
isOldNewValueSame = editor.EditorComponentAPIBus(bus.Broadcast, 'CompareComponentProperty', component, path, oldValue)
if not(newValue == oldValue and oldValueCompared and newValueCompared and not isOldNewValueSame):
print("GetSetCompareTest " + path + ": SUCCESS")
else:
print("GetSetCompareTest " + path + ": FAILURE")
def PteTest(pte, path, value):
oldObj = pte.get_value(path)
if(oldObj.IsSuccess()):
oldValue = oldObj.GetValue()
oldValueCompared = pte.compare_value(path, oldValue)
pte.set_value(path, value)
newObj = pte.get_value(path)
if(newObj.IsSuccess()):
newValue = newObj.GetValue()
newValueCompared = pte.compare_value(path, newValue)
isOldNewValueSame = pte.compare_value(path, oldValue)
if not(newValue == oldValue and oldValueCompared and newValueCompared and not isOldNewValueSame):
print("PteTest " + path + ": SUCCESS")
else:
print("PteTest " + path + ": FAILURE")
# Create new Entity
entityId = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', entity.EntityId())
if (entityId):
print("New entity with no parent created")
# Get Component Type for Environment Probe
typeIdsList = editor.EditorComponentAPIBus(bus.Broadcast, 'FindComponentTypeIdsByEntityType', ["Environment Probe"], entity.EntityType().Game)
componentOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentsOfType', entityId, typeIdsList)
if (componentOutcome.IsSuccess()):
print("Environment Probe component added to entity")
components = componentOutcome.GetValue()
component = components[0]
hasComponent = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', entityId, typeIdsList[0])
if(hasComponent):
print("Entity has an Environment Probe component")
# Test BuildComponentPropertyList
paths = editor.EditorComponentAPIBus(bus.Broadcast, 'BuildComponentPropertyList', component)
if(len(paths) > 0):
print("get_paths_list works")
# Tests for GetComponentProperty/SetComponentProperty
GetSetCompareTest(component, "Settings|General Settings|Visible", False)
GetSetCompareTest(component, "Settings|Animation|Style", 2.0)
GetSetCompareTest(component, "Settings|Environment Probe Settings|Box height", 42)
color = math.Color()
color.r = 0.4
color.g = 0.5
color.b = 0.6
GetSetCompareTest(component, "Settings|General Settings|Color", color)
vec3 = math.Vector3()
vec3.x = 1.0
vec3.y = 2.0
vec3.z = 3.0
GetSetCompareTest(component, "Settings|Environment Probe Settings|Area dimensions", vec3)
# Tests for BuildComponentPropertyTreeEditor
pteObj = editor.EditorComponentAPIBus(bus.Broadcast, 'BuildComponentPropertyTreeEditor', component)
if(pteObj.IsSuccess()):
print("")
pte = pteObj.GetValue()
PteTest(pte, "Settings|General Settings|Visible", True)
PteTest(pte, "Settings|Animation|Style", 4)
PteTest(pte, "Settings|Environment Probe Settings|Box height", 48.0)
color = math.Color()
color.r = 0.9
color.g = 0.1
color.b = 0.3
PteTest(pte, "Settings|General Settings|Color", color)
vec3 = math.Vector3()
vec3.x = 7.0
vec3.y = 4.0
vec3.z = 1.0
PteTest(pte, "Settings|Environment Probe Settings|Area dimensions", vec3)
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'ExitNoPrompt')
@@ -0,0 +1,86 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
# Tests setting property values that are not 32 or 64 bit such as a u8
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.entity as entity
import azlmbr.math as math
# Open a level
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'OpenLevelNoPrompt', 'ocean_component')
# toggle the entity system to use visibility enforcement rules
editor.EditorComponentAPIBus(bus.Broadcast, 'SetVisibleEnforcement', True)
def print_result(message, result):
if result:
print(message + ": SUCCESS")
else:
print(message + ": FAILURE")
def get_entity_by_name(name):
searchFilter = entity.SearchFilter()
searchFilter.names = [name]
searchResult = entity.SearchBus(bus.Broadcast, 'SearchEntities', searchFilter)
if(len(searchResult) > 0):
return searchResult
print_result("get_entity_by_name - {}".format(name), False)
return None
def get_component_type_by_name(name):
gameType = entity.EntityType().Game
listOfTypeIds = editor.EditorComponentAPIBus(bus.Broadcast, 'FindComponentTypeIdsByEntityType', [name], gameType)
if(len(listOfTypeIds) > 0):
return listOfTypeIds[0]
print_result("get_component_type_by_name - {}".format(name), False)
return None
def get_component_of_type(entity, componentTypeId):
outcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', entity, componentTypeId)
if(outcome.IsSuccess()):
return outcome.GetValue()
print_result("get_component_of_type - {} for type {}".format(entity, componentTypeId), False)
return None
def get_component_property(component, path):
outcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentProperty', component, path)
if(outcome.IsSuccess()):
return outcome.GetValue()
print_result("get_component_property - {}".format(path), False)
return None
def set_component_property(component, path, value):
outcome = editor.EditorComponentAPIBus(bus.Broadcast, 'SetComponentProperty', component, path, value)
if(outcome.IsSuccess()):
return True
print_result("set_component_property - {} with value {}".format(path, value), False)
return False
# fetch the ocean entity and its 'ocean' component
entityId = get_entity_by_name('the_ocean')[0]
riverComponentTypeId = get_component_type_by_name('Infinite Ocean')
riverComponent = get_component_of_type(entityId, riverComponentTypeId)
# this series tests that a material can be fetched, mutated with a None, and reverts to an 'empty asset'
materialPropertPath = 'General|Water Material'
material = get_component_property(riverComponent, materialPropertPath)
print_result("material current is valid - {}".format(material.is_valid()), material.is_valid())
materialUpdateResult = set_component_property(riverComponent, materialPropertPath, None)
print_result("material set to None", materialUpdateResult)
material = get_component_property(riverComponent, materialPropertPath)
print_result("material has been set to None", material.is_valid() is False)
# All Done!
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'ExitNoPrompt')
@@ -0,0 +1,61 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
# ComponentPropertyCommands test case visibility
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.entity as entity
# Open a level
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'OpenLevelNoPrompt', 'ocean_component')
def print_result(result, message):
if result:
print(message + ": SUCCESS")
else:
print(message + ": FAILURE")
def add_componet(typename, entityId):
typeIdsList = editor.EditorComponentAPIBus(bus.Broadcast, 'FindComponentTypeIdsByEntityType', [typename], entity.EntityType().Game)
componentOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentsOfType', entityId, typeIdsList)
print_result(componentOutcome.IsSuccess(), "{} component added to entity".format(typename))
return componentOutcome.GetValue()
# Find ocean entity
searchFilter = entity.SearchFilter()
searchFilter.names = ["the_ocean"]
oceanEntityId = entity.SearchBus(bus.Broadcast, 'SearchEntities', searchFilter)[0]
print_result(oceanEntityId, "oceanEntityId was found")
# Find Infinite Ocean component
typeIdsList = editor.EditorComponentAPIBus(bus.Broadcast, 'FindComponentTypeIdsByEntityType', ['Infinite Ocean'], entity.EntityType().Game)
getComponentOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', oceanEntityId, typeIdsList[0])
print_result(getComponentOutcome.IsSuccess(), "Found Infinite Ocean component ID")
infiniteOceanId = getComponentOutcome.GetValue()
# Get the PTE from the Mesh Component
pteObj = editor.EditorComponentAPIBus(bus.Broadcast, 'BuildComponentPropertyTreeEditor', infiniteOceanId)
print_result(pteObj.IsSuccess(), "Created a PropertyTreeEditor for the infiniteOceanId")
pte = pteObj.GetValue()
# test for visibility (default all nodes are exposed)
print_result(pte.get_value('m_data|General|General|Enable Ocean Bottom').IsSuccess(), "Found proprety hidden node in path")
# enable visibility enforcement
pte.set_visible_enforcement(True)
print_result(pte.get_value('m_data|General|General|Enable Ocean Bottom').IsSuccess() is not True, "Proprety node is now a hidden path")
# test for visibility (missing some properties now)
print_result(pte.get_value('General|Enable Ocean Bottom').IsSuccess(), "Property path enforcement of visibility")
# All Done!
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'ExitNoPrompt')
@@ -0,0 +1,130 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
# Tests component properties that are containers
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.entity as entity
import azlmbr.surface_data
import azlmbr.globals
# Open a level
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'OpenLevelNoPrompt', 'auto_test')
def print_result(message, result):
if result:
print(message + ": SUCCESS")
else:
print(message + ": FAILURE")
def is_container(pte, path):
return pte.is_container(path)
def get_container_count(pte, path):
outcome = pte.get_container_count(path)
if(outcome.IsSuccess()):
return outcome.GetValue()
return False
def reset_container(pte, path):
outcome = pte.reset_container(path)
if(outcome.IsSuccess()):
return outcome.GetValue()
return False
def add_container_item(pte, path, key, item):
outcome = pte.add_container_item(path, key, item)
if(outcome.IsSuccess()):
return outcome.GetValue()
return False
def remove_container_item(pte, path, key):
outcome = pte.remove_container_item(path, key)
if(outcome.IsSuccess()):
return outcome.GetValue()
return False
def update_container_item(pte, path, key, value):
outcome = pte.update_container_item(path, key, value)
if(outcome.IsSuccess()):
return outcome.GetValue()
return False
def get_container_item(pte, path, key):
outcome = pte.get_container_item(path, key)
if(outcome.IsSuccess()):
return outcome.GetValue()
return False
# Create new Entity
entityId = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', entity.EntityId())
print_result("New entity with no parent created", entityId)
tagOne = azlmbr.surface_data.SurfaceTag()
tagOne.SetTag('one')
tagTwo = azlmbr.surface_data.SurfaceTag()
tagTwo.SetTag('two')
tagThree = azlmbr.surface_data.SurfaceTag()
tagThree.SetTag('three')
tagFour = azlmbr.surface_data.SurfaceTag()
tagFour.SetTag('four')
# create a component with a TagSurface container
typeIdsList = [azlmbr.globals.property.GradientSurfaceDataComponentTypeId]
componentOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentsOfType', entityId, typeIdsList)
if (componentOutcome.IsSuccess()):
print("GradientSurfaceDataComponent added to entity :SUCCESS")
else:
raise Exception('FAILURE FATAL: AddComponentsOfType')
components = componentOutcome.GetValue()
tagList = components[0]
pteOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'BuildComponentPropertyTreeEditor', tagList)
if(pteOutcome.IsSuccess()):
pte = pteOutcome.GetValue()
print("Created a PropertyTreeEditor :SUCCESS")
else:
raise Exception('FAILURE FATAL: BuildComponentPropertyTreeEditor')
# Test BuildComponentPropertyList
paths = pte.build_paths_list()
for p in paths:
print('>> {}'.format(p))
tagListPropertyPath = 'm_template|Extended Tags'
print_result('Has a container', is_container(pte, tagListPropertyPath))
print_result('Has zero items', get_container_count(pte, tagListPropertyPath) == 0)
print_result('Add an item 0', add_container_item(pte, tagListPropertyPath, 0, tagOne))
print_result('Has one item 0', get_container_count(pte, tagListPropertyPath) == 1)
print_result('Add an item 1', add_container_item(pte, tagListPropertyPath, 1, tagOne))
print_result('Add an item 2', add_container_item(pte, tagListPropertyPath, 2, tagTwo))
print_result('Add an item 3', add_container_item(pte, tagListPropertyPath, 3, tagThree))
print_result('Has four items', get_container_count(pte, tagListPropertyPath) == 4)
print_result('Updated an item', update_container_item(pte, tagListPropertyPath, 2, tagFour))
itemTag = get_container_item(pte, tagListPropertyPath, 2)
print_result ('itemTag equals tagFour', itemTag.Equal(tagFour))
print_result('Removed one item 0', remove_container_item(pte, tagListPropertyPath, 0))
print_result('Removed one item 1', remove_container_item(pte, tagListPropertyPath, 0))
print_result('Has two items', get_container_count(pte, tagListPropertyPath) == 2)
print_result('Reset items', reset_container(pte, tagListPropertyPath))
print_result('Has cleared the items', get_container_count(pte, tagListPropertyPath) == 0)
# All Done!
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'ExitNoPrompt')
@@ -0,0 +1,68 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
# Tests setting property values that are not 32 or 64 bit such as a u8
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.entity as entity
import azlmbr.math as math
# Open a level
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'OpenLevelNoPrompt', 'auto_test')
def print_result(message, result):
if result:
print(message + ": SUCCESS")
else:
print(message + ": FAILURE")
def GetSetCompareTest(component, path, value):
oldObj = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentProperty', component, path)
if(oldObj.IsSuccess()):
oldValue = oldObj.GetValue()
oldValueCompared = editor.EditorComponentAPIBus(bus.Broadcast, 'CompareComponentProperty', component, path, oldValue)
print_result("CompareComponentProperty - {}".format(path), oldValueCompared)
editor.EditorComponentAPIBus(bus.Broadcast, 'SetComponentProperty', component, path, value)
newObj = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentProperty', component, path)
if(newObj.IsSuccess()):
newValue = newObj.GetValue()
newValueCompared = editor.EditorComponentAPIBus(bus.Broadcast, 'CompareComponentProperty', component, path, newValue)
isOldNewValueSame = editor.EditorComponentAPIBus(bus.Broadcast, 'CompareComponentProperty', component, path, oldValue)
result = not(newValue == oldValue and newValueCompared and not isOldNewValueSame)
print_result("GetSetCompareTest - {}".format(path), result)
# Create new Entity
entity_position = math.Vector3(125.0,136.0,32.0)
entityId = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntityAtPosition', entity_position, entity.EntityId())
print_result("New entity with no parent created", entityId is not None)
# create a vegetation layer with a box shape and distance filter
typenameList = ["Vegetation Layer Spawner", "Vegetation Asset List", "Box Shape", "Vegetation Distance Between Filter"]
typeIdsList = editor.EditorComponentAPIBus(bus.Broadcast, 'FindComponentTypeIdsByEntityType', typenameList, entity.EntityType().Game)
addComponentsOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentsOfType', entityId, typeIdsList)
print_result("Components added to entity", addComponentsOutcome.IsSuccess())
# fetch the Vegetation Distance Between Filter
vegDistTypeIdList = editor.EditorComponentAPIBus(bus.Broadcast, 'FindComponentTypeIdsByEntityType', ["Vegetation Distance Between Filter"], entity.EntityType().Game)
componentOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentsOfType', entityId, vegDistTypeIdList[0])
print_result('Found Vegetation Distance Between Filter', componentOutcome.IsSuccess())
paths = editor.EditorComponentAPIBus(bus.Broadcast, 'BuildComponentPropertyList', componentOutcome.GetValue()[0])
# update the bound box type
pathToBoundMode = "Configuration|Bound Mode"
GetSetCompareTest(componentOutcome.GetValue()[0], pathToBoundMode, 1)
# All Done!
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'ExitNoPrompt')
@@ -0,0 +1,43 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
#
# This is a pytest module to test the in-Editor Python API from PythonEditorFuncs
#
import pytest
pytest.importorskip('ly_test_tools')
import sys
import os
sys.path.append(os.path.dirname(__file__))
from hydra_utils import launch_test_case
@pytest.mark.SUITE_sandbox
@pytest.mark.parametrize('launcher_platform', ['windows_editor'])
@pytest.mark.parametrize('project', ['AutomatedTesting'])
@pytest.mark.parametrize('level', ['Simple'])
class TestComponentAssetAutomation(object):
def test_ComponentAsset(self, request, editor, level, launcher_platform):
unexpected_lines=[]
expected_lines = [
'Set EditorDescriptorListComponent Embedded Assets as List',
'Set EditorDescriptorListComponent Embedded Assets 0 Descriptor Mesh Asset ID',
'Set EditorDescriptorListComponent Embedded Assets 1 Descriptor Mesh Asset ID',
'Set EditorDescriptorListComponent Embedded Assets 2 Descriptor Mesh Asset ID',
'Set EditorDescriptorListComponent Embedded Assets 3 Descriptor Mesh Asset ID'
]
test_case_file = os.path.join(os.path.dirname(__file__), 'ComponentUpdateListProperty_test_case.py')
launch_test_case(editor, test_case_file, expected_lines, unexpected_lines)
@@ -0,0 +1,78 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
import azlmbr.object as object
import azlmbr.legacy.general as general
import azlmbr.editor as editor
import azlmbr.bus as bus
import azlmbr.entity as entity
import azlmbr.math as math
import azlmbr.asset as asset
def add_component_with_uuid(entityId, typeId):
componentOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentsOfType', entityId, [typeId])
if (componentOutcome.IsSuccess()):
return componentOutcome.GetValue()[0]
def set_component_property(component, path, value):
outcome = editor.EditorComponentAPIBus(bus.Broadcast, 'SetComponentProperty', component, path, value)
return outcome.IsSuccess()
def get_component_property(component, path):
outcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentProperty', component, path)
if (outcome.IsSuccess()):
return outcome.GetValue()
return None
try:
# Open a level
print ('Test started')
general.open_level_no_prompt('auto_test')
newEntityId = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', entity.EntityId())
editorDescriptorListComponentId = math.Uuid_CreateString('{3AF9BE58-6D2D-44FB-AB4D-CA1182F6C78F}', 0)
descListComponent = add_component_with_uuid(newEntityId, editorDescriptorListComponentId)
print ('descListComponent added')
primitiveCubeId = asset.AssetCatalogRequestBus(bus.Broadcast, 'GetAssetIdByPath', 'objects/default/primitive_cube.cgf', math.Uuid(), False)
primitiveSphereId = asset.AssetCatalogRequestBus(bus.Broadcast, 'GetAssetIdByPath', 'objects/default/primitive_sphere.cgf', math.Uuid(), False)
primitiveCapsuleId = asset.AssetCatalogRequestBus(bus.Broadcast, 'GetAssetIdByPath', 'objects/default/primitive_capsule.cgf', math.Uuid(), False)
primitivePlaneId = asset.AssetCatalogRequestBus(bus.Broadcast, 'GetAssetIdByPath', 'objects/default/primitive_plane.cgf', math.Uuid(), False)
print ('fetched asset ids')
# expand the list of veg descriptors to 4 elements
descList = get_component_property(descListComponent, 'Configuration|Embedded Assets')
print('Got the veg descriptor list')
descElem = descList[0]
descList.append(descElem)
descList.append(descElem)
descList.append(descElem)
set_component_property(descListComponent, 'Configuration|Embedded Assets', descList)
print('Set EditorDescriptorListComponent Embedded Assets as List')
set_component_property(descListComponent, 'Configuration|Embedded Assets|[0]|Instance|Mesh Asset', primitiveCubeId)
print('Set EditorDescriptorListComponent Embedded Assets 0 Descriptor Mesh Asset ID')
set_component_property(descListComponent, 'Configuration|Embedded Assets|[1]|Instance|Mesh Asset', primitiveSphereId)
print('Set EditorDescriptorListComponent Embedded Assets 1 Descriptor Mesh Asset ID')
set_component_property(descListComponent, 'Configuration|Embedded Assets|[2]|Instance|Mesh Asset', primitiveCapsuleId)
print('Set EditorDescriptorListComponent Embedded Assets 2 Descriptor Mesh Asset ID')
set_component_property(descListComponent, 'Configuration|Embedded Assets|[3]|Instance|Mesh Asset', primitivePlaneId)
print('Set EditorDescriptorListComponent Embedded Assets 3 Descriptor Mesh Asset ID')
except:
print ('Test failed.')
finally:
print ('Test done.')
general.exit_no_prompt()
@@ -0,0 +1,75 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
#
# This is a pytest module to test the in-Editor Python API from ViewPane.h
#
import pytest
pytest.importorskip('ly_test_tools')
import sys
import os
sys.path.append(os.path.dirname(__file__))
from hydra_utils import launch_test_case
@pytest.mark.SUITE_sandbox
@pytest.mark.parametrize('launcher_platform', ['windows_editor'])
@pytest.mark.parametrize('project', ['AutomatedTesting'])
@pytest.mark.parametrize('level', ['auto_test'])
class TestLegacyCryMaterialsCommandsAutomation(object):
def test_Legacy_CryMaterials(self, request, editor, level, launcher_platform):
unexpected_lines=[]
expected_lines = [
# "Material Settings/Shader updated correctly", # Disabled, SPEC-3590
# "Material Settings/Surface Type updated correctly", # Disabled, SPEC-3590
"Texture Maps/Diffuse/Tiling/IsTileU updated correctly",
"Texture Maps/Diffuse/Tiling/TileU updated correctly",
"Texture Maps/Diffuse/Rotator/Type updated correctly",
"Texture Maps/Diffuse/Rotator/Amplitude updated correctly",
"Texture Maps/Diffuse/Oscillator/AmplitudeU updated correctly",
"Opacity Settings/Opacity updated correctly",
"Opacity Settings/AlphaTest updated correctly",
"Opacity Settings/Additive updated correctly",
"Lighting Settings/Diffuse Color updated correctly",
"Lighting Settings/Specular Color updated correctly",
"Lighting Settings/Emissive Intensity updated correctly",
"Lighting Settings/Emissive Color updated correctly",
"Advanced/Allow layer activation updated correctly",
"Advanced/2 Sided updated correctly",
"Advanced/No Shadow updated correctly",
"Advanced/Use Scattering updated correctly",
"Advanced/Hide After Breaking updated correctly",
"Advanced/Fog Volume Shading Quality High updated correctly",
"Advanced/Blend Terrain Color updated correctly",
"Advanced/Voxel Coverage updated correctly",
"Advanced/Propagate Opacity Settings updated correctly",
"Advanced/Propagate Lighting Settings updated correctly",
"Advanced/Propagate Advanced Settings updated correctly",
"Advanced/Propagate Texture Maps updated correctly",
"Advanced/Propagate Shader Params updated correctly",
"Advanced/Propagate Shader Generation updated correctly",
"Advanced/Propagate Vertex Deformation updated correctly",
# "Shader Params/Blend Factor updated correctly", # Disabled, SPEC-3590
# "Shader Params/Indirect bounce color updated correctly", # Disabled, SPEC-3590
"Vertex Deformation/Type updated correctly",
"Vertex Deformation/Wave Length X updated correctly",
"Vertex Deformation/Wave X/Level updated correctly",
"Vertex Deformation/Wave X/Amplitude updated correctly",
"Vertex Deformation/Wave X/Phase updated correctly",
"Vertex Deformation/Wave X/Frequency updated correctly"
]
test_case_file = os.path.join(os.path.dirname(__file__), 'CryMaterialsCommands_test_case.py')
launch_test_case(editor, test_case_file, expected_lines, unexpected_lines)
@@ -0,0 +1,116 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
# Tests the legacy Python API for CryMaterials while the Editor is running
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.legacy.material as material
import azlmbr.math as math
materialName = 'materials/ter_layer_green'
print(f'Starting CryMaterial test case using material {materialName}')
def MaterialPropertyTest(property, value, doReset=True):
try:
# get old value and attempt to set new value
oldValue = material.get_property(materialName, property)
if oldValue == value:
print(f'>>> `{property}` already set to {oldValue}')
return
material.set_property(materialName, property, value)
# test that the set new value worked
newValue = material.get_property(materialName, property)
if oldValue != newValue:
print(f"{property} updated correctly")
# reset back to old value
if doReset:
material.set_property(materialName, property, oldValue)
except:
print(f'!!! hit an exception when setting `{property}` to {value}')
color = math.Color()
color.r = 255.0
color.g = 128.0
color.b = 64.0
color.a = 0.0
# Material Settings
# MaterialPropertyTest("Material Settings/Shader", "Geometrybeam") # Disabled, SPEC-3590
# MaterialPropertyTest("Material Settings/Surface Type", "grass") # Disabled, SPEC-3590
# Texture Maps
MaterialPropertyTest("Texture Maps/Diffuse/Tiling/IsTileU", False)
MaterialPropertyTest("Texture Maps/Diffuse/Tiling/IsTileV", False)
MaterialPropertyTest("Texture Maps/Diffuse/Tiling/TileU", 0.42)
MaterialPropertyTest("Texture Maps/Diffuse/Rotator/Type", 'Oscillated Rotation')
MaterialPropertyTest("Texture Maps/Diffuse/Rotator/Amplitude", 42.0)
MaterialPropertyTest("Texture Maps/Diffuse/Oscillator/TypeU", 'Fixed Moving')
MaterialPropertyTest("Texture Maps/Diffuse/Oscillator/AmplitudeU", 42.0)
# Vertex Deformation
MaterialPropertyTest("Vertex Deformation/Type", 'Sin Wave')
MaterialPropertyTest("Vertex Deformation/Wave Length X", 42.0)
MaterialPropertyTest("Vertex Deformation/Type", 'Perlin 3D')
MaterialPropertyTest("Vertex Deformation/Noise Scale", math.Vector3(1.1, 2.2, 3.3))
# Opacity Settings
MaterialPropertyTest("Opacity Settings/Opacity", 42)
MaterialPropertyTest("Opacity Settings/AlphaTest", 2)
MaterialPropertyTest("Opacity Settings/Additive", True)
# Lighting Settings
MaterialPropertyTest("Lighting Settings/Diffuse Color", color)
MaterialPropertyTest("Lighting Settings/Specular Color", color)
MaterialPropertyTest("Lighting Settings/Emissive Intensity", 42.0)
MaterialPropertyTest("Lighting Settings/Emissive Color", color)
MaterialPropertyTest("Lighting Settings/Specular Level", 2.0)
# Advanced
MaterialPropertyTest("Advanced/Allow layer activation", False)
MaterialPropertyTest("Advanced/2 Sided", True)
MaterialPropertyTest("Advanced/No Shadow", True)
MaterialPropertyTest("Advanced/Use Scattering", True)
MaterialPropertyTest("Advanced/Hide After Breaking", True)
MaterialPropertyTest("Advanced/Fog Volume Shading Quality High", True)
MaterialPropertyTest("Advanced/Blend Terrain Color", True)
MaterialPropertyTest("Advanced/Voxel Coverage", 0.42)
# --- MaterialPropertyTest("Advanced/Link to Material", "materials/ter_layer_blue") # Works, but clears on UI refresh
MaterialPropertyTest("Advanced/Propagate Opacity Settings", True)
MaterialPropertyTest("Advanced/Propagate Lighting Settings", True)
MaterialPropertyTest("Advanced/Propagate Advanced Settings", True)
MaterialPropertyTest("Advanced/Propagate Texture Maps", True)
MaterialPropertyTest("Advanced/Propagate Shader Params", True)
MaterialPropertyTest("Advanced/Propagate Shader Generation", True)
MaterialPropertyTest("Advanced/Propagate Vertex Deformation", True)
# Shader parameters vary with each Shader, just testing a couple of them...
# MaterialPropertyTest("Shader Params/Blend Factor", 7.0, False) # Disabled, SPEC-3590
# MaterialPropertyTest("Shader Params/Indirect bounce color", color, False) # Disabled, SPEC-3590
### These values are reset to False when set. Left them here commented for reference.
# MaterialPropertyTest("Shader Generation Params/Dust & Turbulence", True)
# MaterialPropertyTest("Shader Generation Params/Receive Shadows", True)
# MaterialPropertyTest("Shader Generation Params/UV Vignetting", True)
# Vertex Deformation
MaterialPropertyTest("Vertex Deformation/Type", "Sin Wave")
MaterialPropertyTest("Vertex Deformation/Wave Length X", 42.0)
MaterialPropertyTest("Vertex Deformation/Wave X/Level", 42.0)
MaterialPropertyTest("Vertex Deformation/Wave X/Amplitude", 42.0)
MaterialPropertyTest("Vertex Deformation/Wave X/Phase", 42.0)
MaterialPropertyTest("Vertex Deformation/Wave X/Frequency", 42.0)
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'ExitNoPrompt')
@@ -0,0 +1,38 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
#
# This is a pytest module to test the in-Editor Python API from ViewPane.h
#
import pytest
pytest.importorskip('ly_test_tools')
import sys
import os
sys.path.append(os.path.dirname(__file__))
from .hydra_utils import launch_test_case
@pytest.mark.SUITE_sandbox
@pytest.mark.parametrize('launcher_platform', ['windows_editor'])
@pytest.mark.parametrize('project', ['AutomatedTesting'])
@pytest.mark.parametrize('level', ['Simple'])
class TestDisplaySettingsAutomation(object):
def test_DisplaySettings(self, request, editor, level, launcher_platform):
unexpected_lines=[]
expected_lines = [
"display settings were changed correctly"
]
test_case_file = os.path.join(os.path.dirname(__file__), 'DisplaySettingsBus_test_case.py')
launch_test_case(editor, test_case_file, expected_lines, unexpected_lines)
@@ -0,0 +1,50 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
# Tests the Python API from DisplaySettingsPythonFuncs.cpp while the Editor is running
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.display_settings as display_settings
# Retrieve current settings
existingState = display_settings.DisplaySettingsBus(bus.Broadcast, 'GetSettingsState')
# Alter settings
alteredState = azlmbr.object.create('DisplaySettingsState')
alteredState.no_collision = False
alteredState.no_labels = False
alteredState.simulate = True
alteredState.hide_tracks = False
alteredState.hide_links = False
alteredState.hide_helpers = False
alteredState.show_dimension_figures = True
# Set altered settings
display_settings.DisplaySettingsBus(bus.Broadcast, 'SetSettingsState', alteredState)
# Get settings again
newState = display_settings.DisplaySettingsBus(bus.Broadcast, 'GetSettingsState')
# Check if the setter worked
if alteredState.no_collision == newState.no_collision and \
alteredState.no_labels == newState.no_labels and \
alteredState.simulate == newState.simulate and \
alteredState.hide_tracks == newState.hide_tracks and \
alteredState.hide_links == newState.hide_links and \
alteredState.hide_helpers == newState.hide_helpers and \
alteredState.show_dimension_figures == newState.show_dimension_figures:
print("display settings were changed correctly")
# Restore previous settings
display_settings.DisplaySettingsBus(bus.Broadcast, 'SetSettingsState', existingState)
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'ExitNoPrompt')
@@ -0,0 +1,38 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
#
# This is a pytest module to test the in-Editor Python API from ViewPane.h
#
import pytest
pytest.importorskip('ly_test_tools')
import sys
import os
sys.path.append(os.path.dirname(__file__))
from hydra_utils import launch_test_case
@pytest.mark.SUITE_sandbox
@pytest.mark.parametrize('launcher_platform', ['windows_editor'])
@pytest.mark.parametrize('project', ['AutomatedTesting'])
@pytest.mark.parametrize('level', ['Simple'])
class TestDisplaySettingsAutomation(object):
def test_DisplaySettings(self, request, editor, level, launcher_platform):
unexpected_lines=[]
expected_lines = [
"display settings were changed correctly"
]
test_case_file = os.path.join(os.path.dirname(__file__), 'DisplaySettingsCommands_test_case.py')
launch_test_case(editor, test_case_file, expected_lines, unexpected_lines)
@@ -0,0 +1,37 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
# Tests the Python API from DisplaySettingsPythonFuncs.cpp while the Editor is running
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.legacy.settings as settings
# Retrieve current settings
existingSettings = settings.get_misc_editor_settings()
# Alter settings
alteredSettings = existingSettings + 12
# Set altered settings
settings.set_misc_editor_settings(alteredSettings)
# Get settings again
newSettings = settings.get_misc_editor_settings()
# Check if the setter worked
if(alteredSettings == newSettings):
print("display settings were changed correctly")
# Restore previous settings
settings.set_misc_editor_settings(existingSettings)
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'ExitNoPrompt')
@@ -0,0 +1,55 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
#
# This is a pytest module to test the in-Editor Python API from PythonEditorFuncs
#
import pytest
pytest.importorskip('ly_test_tools')
import sys
import os
sys.path.append(os.path.dirname(__file__))
from hydra_utils import launch_test_case, launch_test_case_with_args
@pytest.mark.SUITE_sandbox
@pytest.mark.parametrize('launcher_platform', ['windows_editor'])
@pytest.mark.parametrize('project', ['AutomatedTesting'])
@pytest.mark.parametrize('level', ['Simple'])
class TestEditorAutomation(object):
def test_EditorNoArgs(self, request, editor, level, launcher_platform):
unexpected_lines=[]
expected_lines = [
"editor command line works",
]
test_case_file = os.path.join(os.path.dirname(__file__), 'EditorCommandLine_test_case.py')
launch_test_case(editor, test_case_file, expected_lines, unexpected_lines)
def test_EditorWithArgs(self, request, editor, level, launcher_platform):
unexpected_lines=[]
expected_lines = [
"editor command line works",
"editor command line arg foo",
"editor command line arg bar",
"editor command line arg baz",
"editor engroot set",
"editor devroot set",
"path resolved worked"
]
extra_args = ['foo bar baz']
test_case_file = os.path.join(os.path.dirname(__file__), 'EditorCommandLine_test_case.py')
launch_test_case_with_args(editor, test_case_file, expected_lines, unexpected_lines, extra_args)
@@ -0,0 +1,39 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
import sys
import azlmbr.bus as bus
import azlmbr.editor as editor
print ('editor command line works')
for x in range(len(sys.argv)):
print ('editor command line arg {}'.format(sys.argv[x]))
# make sure the @engroot@ exists as a azlmbr.paths property
engroot = azlmbr.paths.engroot
if (engroot is not None and len(engroot) is not 0):
print ('engroot is {}'.format(engroot))
print ('editor engroot set')
# make sure the @devroot@ exists as a azlmbr.paths property
devroot = azlmbr.paths.devroot
if (devroot is not None and len(devroot) != 0):
print ('devroot is {}'.format(devroot))
print ('editor devroot set')
# resolving a basic path
path = azlmbr.paths.resolve_path('@engroot@/engineassets/texturemsg/defaultsolids.mtl')
if (len(path) != 0 and path.find('@engroot@') == -1):
print ('path resolved to {}'.format(path))
print ('path resolved worked')
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'ExitNoPrompt')
@@ -0,0 +1,82 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
# Tests the Python API from PythonEditorFuncs.cpp while the Editor is running
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.legacy.general as general
import azlmbr.globals
import math
def testing_cvar(setMethod, methodName, label, value, compare):
try:
setMethod(label, value)
test_value = general.get_cvar(label)
if(compare(test_value, value)):
print('{} worked'.format(methodName))
except:
print('{} failed'.format(methodName))
def testing_edit_mode(mode):
general.set_edit_mode(mode)
if (general.get_edit_mode(mode)):
return True
return False
def testing_axis_constraints(constraint):
general.set_axis_constraint(constraint)
if (general.get_axis_constraint(constraint)):
return True
return False
# ----- Test cvar
compare = lambda lhs, rhs: rhs == float(lhs)
testing_cvar(general.set_cvar_float, 'set_cvar_float', 'sys_LocalMemoryOuterViewDistance', 501.0, compare)
compare = lambda lhs, rhs: rhs == lhs
testing_cvar(general.set_cvar_string, 'set_cvar_string', 'e_ScreenShotFileFormat', 'jpg', compare)
compare = lambda lhs, rhs: rhs == int(lhs)
testing_cvar(general.set_cvar_integer, 'set_cvar_integer', 'sys_LocalMemoryGeometryLimit', 33, compare)
# ----- Test Edit Mode
if (testing_edit_mode("SELECT") and testing_edit_mode('SELECTAREA') and
testing_edit_mode("MOVE") and testing_edit_mode("ROTATE") and
testing_edit_mode("SCALE") and testing_edit_mode("TOOL")):
print("edit mode works")
# ----- Test Axis Constraints
if (testing_axis_constraints("X") and testing_axis_constraints("Y") and
testing_axis_constraints("Z") and testing_axis_constraints("XY") and
testing_axis_constraints("XZ") and testing_axis_constraints("YZ") and
testing_axis_constraints("XYZ") and testing_axis_constraints("TERRAIN") and
testing_axis_constraints("TERRAINSNAP")):
print("axis constraint works")
print("end of editor utility tests")
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'ExitNoPrompt')
@@ -0,0 +1,57 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
#
# This is a pytest module to test the in-Editor Python API from PythonEditorFuncs
#
import pytest
pytest.importorskip('ly_test_tools')
import sys
import os
sys.path.append(os.path.dirname(__file__))
from hydra_utils import launch_test_case
@pytest.mark.SUITE_sandbox
@pytest.mark.parametrize('launcher_platform', ['windows_editor'])
@pytest.mark.parametrize('project', ['AutomatedTesting'])
@pytest.mark.parametrize('level', ['Simple'])
class TestEditorAutomation(object):
def test_Editor(self, request, editor, level, launcher_platform):
unexpected_lines = []
expected_lines = [
"SetCVarFromFloat worked",
"SetCVarFromString worked",
"SetCVarFromInteger worked",
"edit mode works",
"axis constraint works",
"end of editor utility tests"
]
test_case_file = os.path.join(os.path.dirname(__file__), 'EditorUtilityCommands_test_case.py')
launch_test_case(editor, test_case_file, expected_lines, unexpected_lines)
def test_Legacy_Editor(self, request, editor, level, launcher_platform):
unexpected_lines=[]
expected_lines = [
"set_cvar_float worked",
"set_cvar_string worked",
"set_cvar_integer worked",
"edit mode works",
"axis constraint works",
"end of editor utility tests"
]
test_case_file = os.path.join(os.path.dirname(__file__), 'EditorUtilityCommands_legacy_test_case.py')
launch_test_case(editor, test_case_file, expected_lines, unexpected_lines)
@@ -0,0 +1,81 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
# Tests the Python API from PythonEditorFuncs.cpp while the Editor is running
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.python_editor_funcs as python_editor_funcs
import azlmbr.globals
import math
def testing_cvar(setMethod, methodName, label, value, compare):
try:
python_editor_funcs.PythonEditorBus(bus.Broadcast, setMethod, label, value)
test_value = python_editor_funcs.PythonEditorBus(bus.Broadcast, 'GetCVar', label)
if compare(test_value, value):
print('{} worked'.format(methodName))
except:
print('{} failed'.format(methodName))
def testing_edit_mode(mode):
python_editor_funcs.PythonEditorBus(bus.Broadcast, 'SetEditMode', mode)
if mode == python_editor_funcs.PythonEditorBus(bus.Broadcast, 'GetEditMode'):
return True
return False
def testing_axis_constraints(constraint):
python_editor_funcs.PythonEditorBus(bus.Broadcast, 'SetAxisConstraint', constraint)
if constraint == python_editor_funcs.PythonEditorBus(bus.Broadcast, 'GetAxisConstraint'):
return True
return False
# ----- Test cvar
compare = lambda lhs, rhs: rhs == float(lhs)
testing_cvar('SetCVarFromFloat', 'SetCVarFromFloat', 'sys_LocalMemoryOuterViewDistance', 501.0, compare)
compare = lambda lhs, rhs: rhs == lhs
testing_cvar('SetCVarFromString', 'SetCVarFromString', 'e_ScreenShotFileFormat', 'jpg', compare)
compare = lambda lhs, rhs: rhs == int(lhs)
testing_cvar('SetCVarFromInteger', 'SetCVarFromInteger', 'sys_LocalMemoryGeometryLimit', 33, compare)
# ----- Test Edit Mode
if (testing_edit_mode("SELECT") and testing_edit_mode('SELECTAREA') and
testing_edit_mode("MOVE") and testing_edit_mode("ROTATE") and
testing_edit_mode("SCALE") and testing_edit_mode("TOOL")):
print("edit mode works")
# ----- Test Axis Constraints
if (testing_axis_constraints("X") and testing_axis_constraints("Y") and
testing_axis_constraints("Z") and testing_axis_constraints("XY") and
testing_axis_constraints("XZ") and testing_axis_constraints("YZ") and
testing_axis_constraints("XYZ") and testing_axis_constraints("TERRAIN") and
testing_axis_constraints("TERRAINSNAP")):
print("axis constraint works")
# ----- End
print("end of editor utility tests")
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'ExitNoPrompt')
@@ -0,0 +1,40 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
#
# This is a pytest module to test the in-Editor Python API from PythonEditorFuncs
#
import pytest
pytest.importorskip('ly_test_tools')
import sys
import os
sys.path.append(os.path.dirname(__file__))
from hydra_utils import launch_test_case
@pytest.mark.SUITE_sandbox
@pytest.mark.parametrize('launcher_platform', ['windows_editor'])
@pytest.mark.parametrize('project', ['AutomatedTesting'])
@pytest.mark.parametrize('level', ['Simple'])
class TestEditorViewAutomation(object):
def test_EditorView(self, request, editor, level, launcher_platform):
unexpected_lines=[]
expected_lines = [
"set_current_view_position works",
"set_current_view_rotation works"
]
test_case_file = os.path.join(os.path.dirname(__file__), 'EditorViewCommands_test_case.py')
launch_test_case(editor, test_case_file, expected_lines, unexpected_lines)
@@ -0,0 +1,54 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
# Tests a portion of the Editor View Python API from CryEdit.cpp while the Editor is running
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.math
import azlmbr.legacy.general as general
def fetch_vector3_parts(vec3):
x = vec3.get_property('x')
y = vec3.get_property('y')
z = vec3.get_property('z')
return (x, y, z)
pos = general.get_current_view_position()
rot = general.get_current_view_rotation()
px, py, pz = fetch_vector3_parts(pos)
rx, ry, rz = fetch_vector3_parts(rot)
px = px + 5.0
py = py - 2.0
pz = pz + 1.0
rx = rx + 2.0
ry = ry + 3.0
rz = rz - 5.0
general.set_current_view_position(px, py, pz)
general.set_current_view_rotation(rx, ry, rz)
pos2 = general.get_current_view_position()
rot2 = general.get_current_view_rotation()
p2x, p2y, p2z = fetch_vector3_parts(pos2)
r2x, r2y, r2z = fetch_vector3_parts(rot2)
if not (px == p2x) and not (py == p2y) and not (pz == p2z):
print("set_current_view_position works")
if not (rx == r2x) and not (ry == r2y) and not (rz == r2z):
print("set_current_view_rotation works")
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'ExitNoPrompt')
@@ -0,0 +1,55 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
#
# This is a pytest module to test the in-Editor Python API for Entity CRUD
#
import pytest
pytest.importorskip('ly_test_tools')
import sys
import os
sys.path.append(os.path.dirname(__file__))
from hydra_utils import launch_test_case
@pytest.mark.SUITE_sandbox
@pytest.mark.parametrize('launcher_platform', ['windows_editor'])
@pytest.mark.parametrize('project', ['AutomatedTesting'])
@pytest.mark.parametrize('level', ['Simple'])
class TestEntityCRUDCommandsAutomation(object):
def test_EntityCRUDCommands(self, request, editor, level, launcher_platform):
unexpected_lines=[]
expected_lines = [
"childEntity is parented to the Root",
"childEntity is now parented to the parentEntity",
"parentEntityId isn't locked",
"parentEntityId is now locked",
"childEntityId is now locked too",
"parentEntityId is visible",
"parentEntityId isn't hidden",
"parentEntityId is now hidden",
"childEntityId is now hidden too",
"parentEntityId isn't set to Editor Only",
"parentEntityId is now set to Editor Only",
"childEntityId does not inherit Editor Only",
"parentEntityId isn't set to Start Inactive",
"parentEntityId is now set to Start Inactive",
"childEntityId does not inherit Start Inactive",
"parentEntityId isn't set to Start Active",
"parentEntityId is now set to Start Active",
"childEntityId should still be set to Start Active by default"
]
test_case_file = os.path.join(os.path.dirname(__file__), 'EntityCRUDCommands_test_case.py')
launch_test_case(editor, test_case_file, expected_lines, unexpected_lines)
@@ -0,0 +1,134 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
# Tests a portion of the Entity CRUD Python API while the Editor is running
import azlmbr.bus as bus
import azlmbr.editor as editor
from azlmbr.entity import EntityId
# Open a level (any level should work)
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'OpenLevelNoPrompt', 'WaterSample')
parentEntityId = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', EntityId())
childEntityId = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', EntityId())
# Test SetParent/GetParent
queryParent = editor.EditorEntityInfoRequestBus(bus.Event, 'GetParent', childEntityId)
if(queryParent.ToString() == EntityId().ToString()):
print("childEntity is parented to the Root")
editor.EditorEntityAPIBus(bus.Event, 'SetParent', childEntityId, parentEntityId)
queryParent = editor.EditorEntityInfoRequestBus(bus.Event, 'GetParent', childEntityId)
if(queryParent.ToString() == parentEntityId.ToString()):
print("childEntity is now parented to the parentEntity")
# Test SetLockState and IsLocked
queryLock = editor.EditorEntityInfoRequestBus(bus.Event, 'IsLocked', parentEntityId)
if(queryLock == False):
print("parentEntityId isn't locked")
editor.EditorEntityAPIBus(bus.Event, 'SetLockState', parentEntityId, True)
queryLock = editor.EditorEntityInfoRequestBus(bus.Event, 'IsLocked', parentEntityId)
if(queryLock == True):
print("parentEntityId is now locked")
queryLock = editor.EditorEntityInfoRequestBus(bus.Event, 'IsLocked', childEntityId)
if(queryLock == True):
print("childEntityId is now locked too")
# Test SetVisibilityState, IsVisible and IsHidden
queryVisibility = editor.EditorEntityInfoRequestBus(bus.Event, 'IsVisible', parentEntityId)
if(queryVisibility == True):
print("parentEntityId is visible")
queryHidden = editor.EditorEntityInfoRequestBus(bus.Event, 'IsHidden', parentEntityId)
if(queryHidden == False):
print("parentEntityId isn't hidden")
editor.EditorEntityAPIBus(bus.Event, 'SetVisibilityState', parentEntityId, False)
queryVisibility = editor.EditorEntityInfoRequestBus(bus.Event, 'IsVisible', parentEntityId)
if(queryVisibility == False):
print("parentEntityId is now hidden")
queryVisibility = editor.EditorEntityInfoRequestBus(bus.Event, 'IsVisible', childEntityId)
if(queryVisibility == False):
print("childEntityId is now hidden too")
# Test EditorOnly
queryStatus = editor.EditorEntityInfoRequestBus(bus.Event, 'GetStartStatus', parentEntityId)
print("EditorOnly before queryStatus: " + str(queryStatus))
if not(queryStatus == azlmbr.globals.property.EditorEntityStartStatus_EditorOnly):
print("parentEntityId isn't set to Editor Only")
editor.EditorEntityAPIBus(bus.Event, 'SetStartStatus', parentEntityId, azlmbr.globals.property.EditorEntityStartStatus_EditorOnly)
queryStatus = editor.EditorEntityInfoRequestBus(bus.Event, 'GetStartStatus', parentEntityId)
print("EditorOnly after queryStatus: " + str(queryStatus))
if (queryStatus == azlmbr.globals.property.EditorEntityStartStatus_EditorOnly):
print("parentEntityId is now set to Editor Only")
queryStatus = editor.EditorEntityInfoRequestBus(bus.Event, 'GetStartStatus', childEntityId)
if not(queryStatus == azlmbr.globals.property.EditorEntityStartStatus_EditorOnly):
print("childEntityId does not inherit Editor Only")
# Test StartInactive
queryStatus = editor.EditorEntityInfoRequestBus(bus.Event, 'GetStartStatus', parentEntityId)
print("queryStatus: " + str(queryStatus))
if not(queryStatus == azlmbr.globals.property.EditorEntityStartStatus_StartInactive):
print("parentEntityId isn't set to Start Inactive")
editor.EditorEntityAPIBus(bus.Event, 'SetStartStatus', parentEntityId, azlmbr.globals.property.EditorEntityStartStatus_StartInactive)
queryStatus = editor.EditorEntityInfoRequestBus(bus.Event, 'GetStartStatus', parentEntityId)
if (queryStatus == azlmbr.globals.property.EditorEntityStartStatus_StartInactive):
print("parentEntityId is now set to Start Inactive")
queryStatus = editor.EditorEntityInfoRequestBus(bus.Event, 'GetStartStatus', childEntityId)
if not(queryStatus == azlmbr.globals.property.EditorEntityStartStatus_StartInactive):
print("childEntityId does not inherit Start Inactive")
# Test StartActive
queryStatus = editor.EditorEntityInfoRequestBus(bus.Event, 'GetStartStatus', parentEntityId)
print("queryStatus: " + str(queryStatus))
if not(queryStatus == azlmbr.globals.property.EditorEntityStartStatus_StartActive):
print("parentEntityId isn't set to Start Active")
editor.EditorEntityAPIBus(bus.Event, 'SetStartStatus', parentEntityId, azlmbr.globals.property.EditorEntityStartStatus_StartActive)
queryStatus = editor.EditorEntityInfoRequestBus(bus.Event, 'GetStartStatus', parentEntityId)
if (queryStatus == azlmbr.globals.property.EditorEntityStartStatus_StartActive):
print("parentEntityId is now set to Start Active")
queryStatus = editor.EditorEntityInfoRequestBus(bus.Event, 'GetStartStatus', childEntityId)
if (queryStatus == azlmbr.globals.property.EditorEntityStartStatus_StartActive):
print("childEntityId should still be set to Start Active by default")
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'ExitNoPrompt')
@@ -0,0 +1,49 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
#
# This is a pytest module to test the in-Editor Python API for Entity CRUD
#
import pytest
pytest.importorskip('ly_test_tools')
import sys
import os
sys.path.append(os.path.dirname(__file__))
from hydra_utils import launch_test_case
@pytest.mark.SUITE_sandbox
@pytest.mark.parametrize('launcher_platform', ['windows_editor'])
@pytest.mark.parametrize('project', ['AutomatedTesting'])
@pytest.mark.parametrize('level', ['Simple'])
class TestEntityCommandsAutomation(object):
def test_EntityCommands(self, request, editor, level, launcher_platform):
unexpected_lines=[]
expected_lines = [
"New entity with no parent created",
"New root entity matches entity received from notification",
"New entity with valid parent created",
"First child entity matches entity received from notification",
"Another new entity with valid parent created",
"Second child entity matches entity received from notification",
"Deleted all entities we created",
"GetName and SetName work",
"GetParent works",
"TestName entity found",
"TestChild entity found",
"Test* 3 entities found"
]
test_case_file = os.path.join(os.path.dirname(__file__), 'EntityCommands_test_case.py')
launch_test_case(editor, test_case_file, expected_lines, unexpected_lines)
@@ -0,0 +1,152 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
# Tests the Python API for Entity CRUD while the Editor is running
import azlmbr.bus as bus
import azlmbr.editor as editor
from azlmbr.entity import EntityId
createdEntityIds = []
def onEditorEntityCreated(parameters):
global createdEntityIds
entityId = parameters[0]
createdEntityIds.append(entityId)
def onEditorEntityDeleted(parameters):
global createdEntityIds
deletedEntityId = parameters[0]
for entityId in createdEntityIds:
if (entityId.invoke("Equal", deletedEntityId)):
createdEntityIds.remove(entityId)
break
# Open a level (any level should work)
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'OpenLevelNoPrompt', 'WaterSample')
# Listen for notifications when entities are created/deleted
handler = bus.NotificationHandler('EditorEntityContextNotificationBus')
handler.connect()
handler.add_callback('OnEditorEntityCreated', onEditorEntityCreated)
handler.add_callback('OnEditorEntityDeleted', onEditorEntityDeleted)
# Create a new Entity at the root level
rootEntityId = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', EntityId())
if (rootEntityId):
print("New entity with no parent created")
if (rootEntityId.invoke("Equal", createdEntityIds[0])):
print("New root entity matches entity received from notification")
# Create a new Entity parented to the first Entity we created
firstChildEntityId = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', rootEntityId)
if (firstChildEntityId):
print("New entity with valid parent created")
if (firstChildEntityId.invoke("Equal", createdEntityIds[1])):
print("First child entity matches entity received from notification")
# Create another Entity parented to the first Entity we created
secondChildEntityId = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', rootEntityId)
if (secondChildEntityId):
print("Another new entity with valid parent created")
if (secondChildEntityId.invoke("Equal", createdEntityIds[2])):
print("Second child entity matches entity received from notification")
# Create two more entities and then delete them using the API that takes a list instead of a single entity
thirdChildEntityId = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', secondChildEntityId)
fourthChildEntityId = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', secondChildEntityId)
editor.ToolsApplicationRequestBus(bus.Broadcast, 'DeleteEntities', [thirdChildEntityId, fourthChildEntityId])
# Delete the second child Entity we created
editor.ToolsApplicationRequestBus(bus.Broadcast, 'DeleteEntityById', secondChildEntityId)
# Delete the root Entity we created and all its children (so this should also delete the firstChildEntityId)
editor.ToolsApplicationRequestBus(bus.Broadcast, 'DeleteEntityAndAllDescendants', rootEntityId)
# There should be no more entities left that we created
if (len(createdEntityIds) == 0):
print("Deleted all entities we created")
# Stop listening for entity creation/deletion notifications
handler.disconnect()
# Create new Entity
entityId = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', EntityId())
# Get current name
oldName = editor.EditorEntityInfoRequestBus(bus.Event, 'GetName', entityId);
# Set a new name
editor.EditorEntityAPIBus(bus.Event, 'SetName', entityId, "TestName")
# Get new name
newName = editor.EditorEntityInfoRequestBus(bus.Event, 'GetName', entityId);
if not(oldName == newName):
print("GetName and SetName work")
# Create new Entity
parentId = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', EntityId())
# Create new Entity with parentId as parent
childId = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', parentId)
getId = editor.EditorEntityInfoRequestBus(bus.Event, 'GetParent', childId);
if(getId.Equal(parentId)):
print("GetParent works")
# Find the entity in the scene
import azlmbr.bus as bus
import azlmbr.entity
searchFilter = azlmbr.entity.SearchFilter()
searchFilter.names = ['TestName']
# Search by name
searchEntityIdList = azlmbr.entity.SearchBus(bus.Broadcast, 'SearchEntities', searchFilter)
for entityId in searchEntityIdList:
entityName = editor.EditorEntityInfoRequestBus(bus.Event, 'GetName', entityId)
if(entityName == 'TestName'):
print("TestName entity found")
# Search by name path (DAG)
editor.EditorEntityAPIBus(bus.Event, 'SetName', parentId, "TestParent")
editor.EditorEntityAPIBus(bus.Event, 'SetName', childId, "TestChild")
searchFilter = azlmbr.entity.SearchFilter()
searchFilter.names = ['TestParent|TestChild']
searchEntityIdList = azlmbr.entity.SearchBus(bus.Broadcast, 'SearchEntities', searchFilter)
for entityId in searchEntityIdList:
entityName = editor.EditorEntityInfoRequestBus(bus.Event, 'GetName', entityId)
if(entityName == 'TestChild'):
print("TestChild entity found")
# Search using wildcard
searchFilter = azlmbr.entity.SearchFilter()
searchFilter.names = ['Test*']
searchEntityIdList = azlmbr.entity.SearchBus(bus.Broadcast, 'SearchEntities', searchFilter)
if(len(searchEntityIdList) == 3):
print("Test* 3 entities found")
# Close Editor
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'ExitNoPrompt')
@@ -0,0 +1,81 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
#
# This is a pytest module to test the in-Editor Python API for Entity Search
#
import pytest
pytest.importorskip('ly_test_tools')
import sys
import os
sys.path.append(os.path.dirname(__file__))
from hydra_utils import launch_test_case
@pytest.mark.SUITE_sandbox
@pytest.mark.parametrize('launcher_platform', ['windows_editor'])
@pytest.mark.parametrize('project', ['AutomatedTesting'])
@pytest.mark.parametrize('level', ['Simple'])
class TestEntitySearchAutomation(object):
def test_EntitySearch(self, request, editor, level, launcher_platform):
unexpected_lines=[]
expected_lines = [
"SUCCESS: Root Entities",
"SUCCESS: No filters - return all entities",
"SUCCESS: Filter by name - single entity",
"SUCCESS: Filter by name - multiple entities",
"SUCCESS: Filter by name - multiple names",
"SUCCESS: Filter by name - wildcard 01",
"SUCCESS: Filter by name - wildcard 02",
"SUCCESS: Filter by name - wildcard 03",
"SUCCESS: Filter by name - wildcard 04",
"SUCCESS: Filter by name - wildcard 05",
"SUCCESS: Filter by name - case sensitive 01",
"SUCCESS: Filter by name - case sensitive 02",
"SUCCESS: Filter by name - case sensitive 03",
"SUCCESS: Filter by name - case sensitive 04",
"SUCCESS: Filter by path - base 01",
"SUCCESS: Filter by path - base 02",
"SUCCESS: Filter by path - wildcard 01",
"SUCCESS: Filter by path - wildcard 02",
"SUCCESS: Filter by path - wildcard 03",
"SUCCESS: Filter by path - wildcard 04",
"SUCCESS: Filter by path - case sensitive 01",
"SUCCESS: Filter by path - case sensitive 02",
"SUCCESS: Filter by path - case sensitive 03",
"SUCCESS: Filter by path - case sensitive 04",
"SUCCESS: Filter by component - base 01",
"SUCCESS: Filter by component - base 02",
"SUCCESS: Filter by component - multiple 01",
"SUCCESS: Filter by component - multiple 02",
"SUCCESS: Filter with roots - base 01",
"SUCCESS: Filter with roots - base 02",
"SUCCESS: Filter with roots - base 03",
"SUCCESS: Filter with roots - base 04",
"SUCCESS: Filter with roots - base 05",
"SUCCESS: Filter with roots - NameIsRootBased 01",
"SUCCESS: Filter with roots - NameIsRootBased 02",
"SUCCESS: Filter with roots - NameIsRootBased 03",
"SUCCESS: Filter with roots - NameIsRootBased 04",
"SUCCESS: Filter with roots - NameIsRootBased 05",
"SUCCESS: Search with Multiple Filters",
"SUCCESS: Filter by AABB - base 01",
"SUCCESS: Filter by AABB - base 02",
"SUCCESS: Filter by Component Properties - base 01",
"SUCCESS: Filter by Component Properties - base 02",
"SUCCESS: Filter by Component Properties - base 03"
]
test_case_file = os.path.join(os.path.dirname(__file__), 'EntitySearchCommands_test_case.py')
launch_test_case(editor, test_case_file, expected_lines, unexpected_lines)
@@ -0,0 +1,408 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
# Tests the Entity Search Python API while the Editor is running
import azlmbr.editor as editor
import azlmbr.entity as entity
import azlmbr.bus as bus
import azlmbr.math as math
import azlmbr.components as components
# Open a level (any level should work)
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'OpenLevelNoPrompt', 'WaterSample')
# Save Root Entities and Total Entity number
root = entity.SearchBus(bus.Broadcast, 'GetRootEditorEntities')
rootNum = len(root)
all = entity.SearchBus(bus.Broadcast, 'SearchEntities', entity.SearchFilter())
allNum = len(all)
# Create Hierarchy
#
# City
# |_ Street (2)
# |_ Car
# | |_ Passenger (1, 2)
# | |_ Passenger
# |_ Car (1)
# | |_ Passenger
# |_ SportsCar
# |_ Passenger (2)
# |_ Passenger
#
def CreateEntity(name, parentId):
newEntityId = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', parentId)
editor.EditorEntityAPIBus(bus.Event, 'SetName', newEntityId, name)
testName = editor.EditorEntityInfoRequestBus(bus.Event, 'GetName', newEntityId)
if (testName != name):
print("FAILURE: testName {} does not equal set name {}".format(testName, name))
return newEntityId
# Entities
cityId = CreateEntity('City', entity.EntityId())
streetId = CreateEntity('Street', cityId)
carId1 = CreateEntity('Car', streetId)
passengerId1 = CreateEntity('Passenger', carId1)
passengerId2 = CreateEntity('Passenger', carId1)
carId2 = CreateEntity('Car', streetId)
passengerId3 = CreateEntity('Passenger', carId2)
sportsCarId = CreateEntity('SportsCar', streetId)
passengerId4 = CreateEntity('Passenger', sportsCarId)
passengerId5 = CreateEntity('Passenger', sportsCarId)
# Components
typeIdsList = editor.EditorComponentAPIBus(bus.Broadcast, 'FindComponentTypeIdsByEntityType', ["Comment", "Actor"], entity.EntityType().Game)
editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentsOfType', passengerId1, [typeIdsList[0]])
editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentsOfType', carId2, [typeIdsList[0]])
editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentsOfType', streetId, [typeIdsList[1]])
editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentsOfType', passengerId1, [typeIdsList[1]])
editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentsOfType', passengerId4, [typeIdsList[1]])
# Test the Entity Search API
def CompareEntityIds(id1, id2):
return (id1.ToString() == id2.ToString())
def SearchResultCheck(searchFilter, testName, resultId):
entities = entity.SearchBus(bus.Broadcast, 'SearchEntities', searchFilter)
if(len(entities) == 1) and (CompareEntityIds(entities[0], resultId)):
print("SUCCESS: " + testName)
else:
print("FAILURE: " + testName)
def SearchResultsCheck(searchFilter, testName, resultSize):
entities = entity.SearchBus(bus.Broadcast, 'SearchEntities', searchFilter)
if(len(entities) == resultSize):
print("SUCCESS: " + testName)
else:
print("FAILURE: " + testName + " (size is " + str(len(entities)) + ", should be " + str(resultSize) + ")")
# Get Root Entities
rootEntities = entity.SearchBus(bus.Broadcast, 'GetRootEditorEntities')
if(len(rootEntities) == 1 + rootNum):
print("SUCCESS: Root Entities")
else:
print("FAILURE: Root Entities")
# Search by Name - Base
# No filters - return all entities
searchFilter1 = entity.SearchFilter()
SearchResultsCheck(searchFilter1, "No filters - return all entities", (10 + allNum))
# Filter by name - single entity
searchFilter2 = entity.SearchFilter()
searchFilter2.names = ["Street"]
SearchResultCheck(searchFilter2, "Filter by name - single entity", streetId)
# Filter by name - multiple entities
searchFilter3 = entity.SearchFilter()
searchFilter3.names = ["Passenger"]
SearchResultsCheck(searchFilter3, "Filter by name - multiple entities", 5)
# Filter by name - multiple names
searchFilter4 = entity.SearchFilter()
searchFilter4.names = ["Passenger", "Street"]
SearchResultsCheck(searchFilter4, "Filter by name - multiple names", 6)
# Search by Name - Wildcard
# Filter by name - wildcard 01
searchFilter5 = entity.SearchFilter()
searchFilter5.names = ["Str*et"]
SearchResultCheck(searchFilter5, "Filter by name - wildcard 01", streetId)
# Filter by name - wildcard 02
searchFilter6 = entity.SearchFilter()
searchFilter6.names = ["St*et"]
SearchResultCheck(searchFilter6, "Filter by name - wildcard 02", streetId)
# Filter by name - wildcard 03
searchFilter7 = entity.SearchFilter()
searchFilter7.names = ["Str?et"]
SearchResultCheck(searchFilter7, "Filter by name - wildcard 03", streetId)
# Filter by name - wildcard 04
searchFilter8 = entity.SearchFilter()
searchFilter8.names = ["Str?t"]
SearchResultsCheck(searchFilter8, "Filter by name - wildcard 04", 0)
# Filter by name - wildcard 05
searchFilter10 = entity.SearchFilter()
searchFilter10.names = ["*"]
SearchResultsCheck(searchFilter10, "Filter by name - wildcard 05", (10 + allNum))
# Search by Name - Case Sensitive
# Filter by name - case sensitive 01
searchFilter11 = entity.SearchFilter()
searchFilter11.names = ["Street"]
searchFilter11.names_case_sensitive = False # default
SearchResultCheck(searchFilter11, "Filter by name - case sensitive 01", streetId)
# Filter by name - case sensitive 02
searchFilter12 = entity.SearchFilter()
searchFilter12.names = ["street"]
searchFilter12.names_case_sensitive = False
SearchResultCheck(searchFilter12, "Filter by name - case sensitive 02", streetId)
# Filter by name - case sensitive 03
searchFilter13 = entity.SearchFilter()
searchFilter13.names = ["Street"]
searchFilter13.names_case_sensitive = True
SearchResultCheck(searchFilter13, "Filter by name - case sensitive 03", streetId)
# Filter by name - case sensitive 04
searchFilter14 = entity.SearchFilter()
searchFilter14.names = ["street"]
searchFilter14.names_case_sensitive = True # default
SearchResultsCheck(searchFilter14, "Filter by name - case sensitive 04", 0)
# Search by Path - Base
# Filter by path - base 01
searchFilter15 = entity.SearchFilter()
searchFilter15.names = ["City|Street|SportsCar"]
SearchResultCheck(searchFilter15, "Filter by path - base 01", sportsCarId)
# Filter by path - base 02
searchFilter16 = entity.SearchFilter()
searchFilter16.names = ["City|Street|Car|Passenger"]
SearchResultsCheck(searchFilter16, "Filter by path - base 02", 3)
# Search by Path - Wildcard
# Filter by path - wildcard 01
searchFilter17 = entity.SearchFilter()
searchFilter17.names = ["City|*|SportsCar"]
SearchResultCheck(searchFilter17, "Filter by path - wildcard 01", sportsCarId)
# Filter by path - wildcard 02
searchFilter18 = entity.SearchFilter()
searchFilter18.names = ["City|Street|*|Passenger"]
SearchResultsCheck(searchFilter18, "Filter by path - wildcard 02", 5)
# Filter by path - wildcard 03
searchFilter19 = entity.SearchFilter()
searchFilter19.names = ["City|Street|*Car|Passenger"]
SearchResultsCheck(searchFilter19, "Filter by path - wildcard 03", 5)
# Filter by path - wildcard 04
searchFilter20 = entity.SearchFilter()
searchFilter20.names = ["City|Street|Sport*|Passenger"]
SearchResultsCheck(searchFilter20, "Filter by path - wildcard 04", 2)
# Search by Path - Case Sensitive
# Filter by path - case sensitive 01
searchFilter21 = entity.SearchFilter()
searchFilter21.names = ["City|Street"]
searchFilter21.names_case_sensitive = False # default
SearchResultCheck(searchFilter21, "Filter by path - case sensitive 01", streetId)
# Filter by path - case sensitive 02
searchFilter22 = entity.SearchFilter()
searchFilter22.names = ["city|street"]
searchFilter22.names_case_sensitive = False # default
SearchResultCheck(searchFilter22, "Filter by path - case sensitive 02", streetId)
# Filter by path - case sensitive 03
searchFilter23 = entity.SearchFilter()
searchFilter23.names = ["City|Street"]
searchFilter23.names_case_sensitive = True
SearchResultCheck(searchFilter23, "Filter by path - case sensitive 03", streetId)
# Filter by path - case sensitive 04
searchFilter24 = entity.SearchFilter()
searchFilter24.names = ["city|street"]
searchFilter24.names_case_sensitive = True
SearchResultsCheck(searchFilter24, "Filter by path - case sensitive 04", 0)
# Search by Component - Base
# Filter by component - base 01
searchFilter25 = entity.SearchFilter()
searchFilter25.components = { typeIdsList[0]:{} }
SearchResultsCheck(searchFilter25, "Filter by component - base 01", 2)
# Filter by component - base 02
searchFilter26 = entity.SearchFilter()
searchFilter26.components = { typeIdsList[1]:{} }
SearchResultsCheck(searchFilter26, "Filter by component - base 02", 3)
# Search by Component - Multiple
# Filter by component - multiple 01
searchFilter27 = entity.SearchFilter()
searchFilter27.components = { typeIdsList[0]: {} , typeIdsList[1]: {} }
searchFilter27.components_match_all = False # default
SearchResultsCheck(searchFilter27, "Filter by component - multiple 01", 4)
# Filter by component - multiple 02
searchFilter28 = entity.SearchFilter()
searchFilter28.components = { typeIdsList[0]: {} , typeIdsList[1]: {} }
searchFilter28.components_match_all = True
SearchResultCheck(searchFilter28, "Filter by component - multiple 02", passengerId1)
# Search with Roots - Base
# Filter with roots - base 01
searchFilter29 = entity.SearchFilter()
searchFilter29.names = ["Passenger"]
searchFilter29.roots = [carId1]
SearchResultsCheck(searchFilter29, "Filter with roots - base 01", 2)
# Filter with roots - base 02
searchFilter30 = entity.SearchFilter()
searchFilter30.names = ["Passenger"]
searchFilter30.roots = [carId2]
SearchResultCheck(searchFilter30, "Filter with roots - base 02", passengerId3)
# Filter with roots - base 03
searchFilter31 = entity.SearchFilter()
searchFilter31.names = ["SportsCar"]
searchFilter31.roots = [carId1]
SearchResultsCheck(searchFilter31, "Filter with roots - base 03", 0)
# Filter with roots - base 04
searchFilter32 = entity.SearchFilter()
searchFilter32.names = ["City|Street|SportsCar|Passenger"]
searchFilter32.roots = [carId1]
SearchResultsCheck(searchFilter32, "Filter with roots - base 04", 0)
# Filter with roots - base 05
searchFilter33 = entity.SearchFilter()
searchFilter33.names = ["Car|Passenger"]
searchFilter33.roots = [carId1]
SearchResultsCheck(searchFilter33, "Filter with roots - base 05", 2)
# Search with Roots - NameIsRootBased
# Filter with roots - NameIsRootBased 01
searchFilter34 = entity.SearchFilter()
searchFilter34.names = ["Car|Passenger"]
searchFilter34.names_are_root_based = False # default
SearchResultsCheck(searchFilter34, "Filter with roots - NameIsRootBased 01", 3)
# Filter with roots - NameIsRootBased 02
searchFilter35 = entity.SearchFilter()
searchFilter35.names = ["Car|Passenger"]
searchFilter35.names_are_root_based = True
SearchResultsCheck(searchFilter35, "Filter with roots - NameIsRootBased 02", 0)
# Filter with roots - NameIsRootBased 03
searchFilter36 = entity.SearchFilter()
searchFilter36.names = ["Car|Passenger"]
searchFilter36.roots = [streetId]
searchFilter36.names_are_root_based = False # default
SearchResultsCheck(searchFilter36, "Filter with roots - NameIsRootBased 03", 3)
# Filter with roots - NameIsRootBased 04
searchFilter37 = entity.SearchFilter()
searchFilter37.names = ["Car|Passenger"]
searchFilter37.roots = [streetId]
searchFilter37.names_are_root_based = True
SearchResultsCheck(searchFilter37, "Filter with roots - NameIsRootBased 04", 3)
# Filter with roots - NameIsRootBased 05
searchFilter38 = entity.SearchFilter()
searchFilter38.names = ["Car|Passenger"]
searchFilter38.roots = [carId2]
searchFilter38.names_are_root_based = True
SearchResultsCheck(searchFilter38, "Filter with roots - NameIsRootBased 05", 0)
# Search with Multiple Filters
searchFilter39 = entity.SearchFilter()
searchFilter39.names = ["Pass*"]
searchFilter39.roots = [sportsCarId]
searchFilter39.components = { typeIdsList[1]:{} }
searchFilter39.names_are_root_based = True
searchFilter39.names_case_sensitive = True
SearchResultCheck(searchFilter39, "Search with Multiple Filters", passengerId4)
# Search with Aabb - Base
aabb = math.Aabb()
cityPosition = components.TransformBus(bus.Event, "GetWorldTranslation", cityId)
print("City Position: ( " + str(cityPosition.x) + ", " + str(cityPosition.y) + ", " + str(cityPosition.z) + " )")
# Filter by AABB - base 01
searchFilter40 = entity.SearchFilter()
aabbMin = math.Vector3(cityPosition.x - 1000.0, cityPosition.y - 1000.0, cityPosition.z - 1000.0)
aabbMax = math.Vector3(cityPosition.x + 1000.0, cityPosition.y + 1000.0, cityPosition.z + 1000.0)
aabb.Set(aabbMin, aabbMax)
searchFilter40.aabb = aabb
searchFilter40.names = ["City", "Street", "SportsCar", "Car", "Passenger"]
searchFilter40.names_case_sensitive = True
SearchResultsCheck(searchFilter40, "Filter by AABB - base 01", 10)
# Filter by AABB - base 02
searchFilter41 = entity.SearchFilter()
aabbMin = math.Vector3(cityPosition.x - 1000.0, cityPosition.y - 1000.0, cityPosition.z - 1000.0)
aabbMax = math.Vector3(cityPosition.x - 100.0, cityPosition.y - 100.0, cityPosition.z - 100.0)
aabb.Set(aabbMin, aabbMax)
searchFilter41.aabb = aabb
searchFilter41.names = ["City", "Street", "SportsCar", "Car", "Passenger"]
searchFilter41.names_case_sensitive = True
SearchResultsCheck(searchFilter41, "Filter by AABB - base 02", 0)
# Search with Component Properties - Base
# Filter by Component Properties - base 01
searchFilter42 = entity.SearchFilter()
searchFilter42.components = { typeIdsList[1]:{'Render options|Draw character': True} }
searchFilter42.names = ["City", "Street", "SportsCar", "Car", "Passenger"]
SearchResultsCheck(searchFilter42, "Filter by Component Properties - base 01", 3)
# Filter by Component Properties - base 02
searchFilter43 = entity.SearchFilter()
searchFilter43.components = { typeIdsList[0]:{}, typeIdsList[1]:{'Render options|Draw character': True} }
searchFilter43.components_match_all = False
searchFilter43.names = ["City", "Street", "SportsCar", "Car", "Passenger"]
SearchResultsCheck(searchFilter43, "Filter by Component Properties - base 02", 4)
# Filter by Component Properties - base 03
searchFilter44 = entity.SearchFilter()
searchFilter44.components = { typeIdsList[0]:{}, typeIdsList[1]:{'Render options|Draw character': True} }
searchFilter44.components_match_all = True
searchFilter44.names = ["City", "Street", "SportsCar", "Car", "Passenger"]
SearchResultsCheck(searchFilter44, "Filter by Component Properties - base 03", 1)
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'ExitNoPrompt')
@@ -0,0 +1,43 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
#
# This is a pytest module to test the in-Editor Python API for Entity Selection
#
import pytest
pytest.importorskip('ly_test_tools')
import sys
import os
sys.path.append(os.path.dirname(__file__))
from hydra_utils import launch_test_case
@pytest.mark.SUITE_sandbox
@pytest.mark.parametrize('launcher_platform', ['windows_editor'])
@pytest.mark.parametrize('project', ['AutomatedTesting'])
@pytest.mark.parametrize('level', ['Simple'])
class TestEntitySelectionAutomation(object):
def test_EntitySelection(self, request, editor, level, launcher_platform):
unexpected_lines=[]
expected_lines = [
"SUCCESS: All Test Entities Selected",
"SUCCESS: One Test Entity Marked as DeSelected",
"SUCCESS: One New Test Entity Marked as Selected",
"SUCCESS: Half of Test Entity Marked as DeSelected",
"SUCCESS: All Test Entities Marked as Selected",
"SUCCESS: Clear All Test Entities Selected",
]
test_case_file = os.path.join(os.path.dirname(__file__), 'EntitySelectionCommands_test_case.py')
launch_test_case(editor, test_case_file, expected_lines, unexpected_lines)
@@ -0,0 +1,89 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
# Tests the Entity Selection Python API while the Editor is running
import azlmbr.bus as bus
import azlmbr.editor as editor
from azlmbr.entity import EntityId
def createTestEntities(count):
testEntityIds = []
for i in range(count):
entityId = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', EntityId())
testEntityIds.append(entityId)
print("Entity " + str(i) + " created.")
editor.EditorEntityAPIBus(bus.Event, 'SetName', entityId, "TestEntity")
return testEntityIds
# Open a level (any level should work)
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'OpenLevelNoPrompt', 'WaterSample')
# Create new test entities at the root level
numTestEntities = 10
testEntityIds = createTestEntities(numTestEntities)
# Select all test entities
editor.ToolsApplicationRequestBus(bus.Broadcast, 'SetSelectedEntities', testEntityIds)
# Get all test entities selected and check if any entity selected
selectedTestEntityIds = editor.ToolsApplicationRequestBus(bus.Broadcast, 'GetSelectedEntities')
areAnyEntitiesSelected = editor.ToolsApplicationRequestBus(bus.Broadcast, 'AreAnyEntitiesSelected')
if(len(testEntityIds) == len(selectedTestEntityIds) and areAnyEntitiesSelected):
print("SUCCESS: All Test Entities Selected")
# Mark first test entity deselected
editor.ToolsApplicationRequestBus(bus.Broadcast, 'MarkEntityDeselected', testEntityIds[0])
selectedTestEntityIds = editor.ToolsApplicationRequestBus(bus.Broadcast, 'GetSelectedEntities')
isSelected = editor.ToolsApplicationRequestBus(bus.Broadcast, 'IsSelected', testEntityIds[0])
if(len(testEntityIds) - 1 == len(selectedTestEntityIds) and not isSelected):
print("SUCCESS: One Test Entity Marked as DeSelected")
# Mark first test entity selected
editor.ToolsApplicationRequestBus(bus.Broadcast, 'MarkEntitySelected', testEntityIds[0])
selectedTestEntityIds = editor.ToolsApplicationRequestBus(bus.Broadcast, 'GetSelectedEntities')
isSelected = editor.ToolsApplicationRequestBus(bus.Broadcast, 'IsSelected', testEntityIds[0])
if(len(testEntityIds) == len(selectedTestEntityIds) and isSelected):
print("SUCCESS: One New Test Entity Marked as Selected")
# Mark first half of test entities as deselected
halfNumTestEntities = len(testEntityIds)//2
editor.ToolsApplicationRequestBus(bus.Broadcast, 'MarkEntitiesDeselected', testEntityIds[:halfNumTestEntities])
selectedTestEntityIds = editor.ToolsApplicationRequestBus(bus.Broadcast, 'GetSelectedEntities')
if(len(testEntityIds) - halfNumTestEntities == len(selectedTestEntityIds)):
print("SUCCESS: Half of Test Entity Marked as DeSelected")
# Mark first half test entity as selected
editor.ToolsApplicationRequestBus(bus.Broadcast, 'MarkEntitiesSelected', testEntityIds[:halfNumTestEntities])
selectedTestEntityIds = editor.ToolsApplicationRequestBus(bus.Broadcast, 'GetSelectedEntities')
if(len(testEntityIds) == len(selectedTestEntityIds)):
print("SUCCESS: All Test Entities Marked as Selected")
# Clear all test entities selected
editor.ToolsApplicationRequestBus(bus.Broadcast, 'SetSelectedEntities', [])
selectedTestEntityIds = editor.ToolsApplicationRequestBus(bus.Broadcast, 'GetSelectedEntities')
areAnyEntitiesSelected = editor.ToolsApplicationRequestBus(bus.Broadcast, 'AreAnyEntitiesSelected')
if(len(selectedTestEntityIds) == 0 and not areAnyEntitiesSelected):
print("SUCCESS: Clear All Test Entities Selected")
# Close Editor
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'ExitNoPrompt')
@@ -0,0 +1,39 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
#
# This is a pytest module to test the in-Editor Python API from ViewPane.h
#
import pytest
pytest.importorskip('ly_test_tools')
import sys
import os
sys.path.append(os.path.dirname(__file__))
from hydra_utils import launch_test_case
@pytest.mark.SUITE_sandbox
@pytest.mark.parametrize('launcher_platform', ['windows_editor'])
@pytest.mark.parametrize('project', ['AutomatedTesting'])
@pytest.mark.parametrize('level', ['Simple'])
class TestLegacyGameModeAutomation(object):
def test_Legacy_GameMode(self, request, editor, level, launcher_platform):
unexpected_lines=[]
expected_lines = [
"Game Mode is On",
"Game Mode is Off"
]
test_case_file = os.path.join(os.path.dirname(__file__), 'GameModeCommands_test_case.py')
launch_test_case(editor, test_case_file, expected_lines, unexpected_lines)
@@ -0,0 +1,38 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
# Tests the Python Game Mode API from PythonEditorFuncs.cpp while the Editor is running
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.legacy.general as general
general.idle_enable(True)
general.idle_wait(0.125)
general.enter_game_mode()
general.idle_wait(1.0)
if(general.is_in_game_mode()):
print("Game Mode is On")
general.idle_wait(0.125)
general.exit_game_mode()
general.idle_wait(1.0)
if not (general.is_in_game_mode()):
print("Game Mode is Off")
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'ExitNoPrompt')
@@ -0,0 +1,44 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
#
# This is a pytest module to test the in-Editor Python API from PythonEditorFuncs
#
import pytest
pytest.importorskip('ly_test_tools')
import sys
import os
sys.path.append(os.path.dirname(__file__))
from hydra_utils import launch_test_case
@pytest.mark.SUITE_sandbox
@pytest.mark.parametrize('launcher_platform', ['windows_editor'])
@pytest.mark.parametrize('project', ['AutomatedTesting'])
@pytest.mark.parametrize('level', ['Simple'])
class TestLevelAutomation(object):
def test_LevelCommands(self, request, editor, level, launcher_platform):
unexpected_lines=[]
expected_lines = [
"WaterSample level has already been created",
"Editor with WaterSample level opened closed",
"WaterSample level opened",
"Level name is correct",
"The level is in the Levels folder",
"Game folder is correct"
]
test_case_file = os.path.join(os.path.dirname(__file__), 'LevelCommands_test_case.py')
launch_test_case(editor, test_case_file, expected_lines, unexpected_lines)
@@ -0,0 +1,59 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
# Tests a portion of the Python API from CryEdit.cpp while the Editor is running
import os
import azlmbr.editor as editor
import azlmbr.bus as bus
# Try to create WaterSample level (return 1 means level with given name existed)
levelAlreadyExisted = 1
if (editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'CreateLevelNoPrompt', 'WaterSample', 1024, False) is levelAlreadyExisted):
print("WaterSample level has already been created")
# Open WaterSample level
if (editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'OpenLevelNoPrompt', 'WaterSample') is True):
print("WaterSample level opened")
# Get level path
levelpath = editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'GetCurrentLevelPath')
# Split level path and get level name
path, filename = os.path.split(levelpath)
# Get level name
levelname = editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'GetCurrentLevelName')
# Compare level name gotten from path to levelname
if (filename == levelname):
print("Level name is correct")
# Remove Levels folder from path
parent, levels = os.path.split(path)
if (levels == "Levels"):
print("The level is in the Levels folder")
# Get game folder
gamefolder = editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'GetGameFolder')
# Compare game folder - normalize first because of the different formats
norm_gamefolder = os.path.normcase(gamefolder)
norm_parent = os.path.normcase(parent)
if (norm_parent == norm_gamefolder):
print("Game folder is correct")
# Close editor
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'ExitNoPrompt')
print("Editor with WaterSample level opened closed")
@@ -0,0 +1,2 @@
# this file is copied to $/dev/editor_autoexec.cfg so the the Editor automation runs for this Hydra test
pyRunFile @devroot@/Tests/hydra/LevelComponentCommands_test_case.py exit_when_done
@@ -0,0 +1,69 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
#
# This is a pytest module to test the in-Editor Python API from EditorLevelComponentAPIBus
#
import pytest
pytest.importorskip('test_tools')
import time
import logging
import os
import shutil
from test_tools import WINDOWS_LAUNCHER
import test_tools.shared.log_monitor
import test_tools.launchers.phase
import test_tools.builtin.fixtures as fixtures
import shared.file_utils as file_utils
# Use the built-in workspace and editor fixtures.
# These will configure the requested project and run the editor.
workspace = fixtures.use_fixture(fixtures.builtin_workspace_fixture, scope='function')
editor = fixtures.use_fixture(fixtures.editor, scope='function')
logger = logging.getLogger(__name__)
@pytest.mark.parametrize("platform,configuration,project,spec", [
pytest.param("win_x64_vs2017", "profile", "AutomatedTesting", "all", marks=pytest.mark.skipif(not WINDOWS_LAUNCHER, reason="Only supported on Windows hosts")),
])
class TestLevelComponentAutomation(object):
@pytest.fixture(autouse=True)
def setup_teardown(self, request, workspace, editor):
def teardown():
editor.ensure_stopped()
file_utils.delete_level(editor, "LevelComponentTest")
request.addfinalizer(teardown)
def test_Component(self, request, editor, project):
logger.debug("Running automated test")
request.addfinalizer(editor.ensure_stopped)
editor.deploy()
editor.launch(["--exec", "@engroot@/Tests/hydra/LevelComponentCommands.cfg"])
editorlog_file = os.path.join(editor.workspace.release.paths.project_log(), 'Editor.log')
expected_lines = [
"Component List returned correctly",
"Type Ids List returned correctly",
"Type Names List returned correctly",
"Level Component API validated"
]
test_tools.shared.log_monitor.monitor_for_expected_lines(editor, editorlog_file, expected_lines)
# Rely on the test script to quit after running
editor.run(test_tools.launchers.phase.WaitForLauncherToQuit(editor, 10))
@@ -0,0 +1,177 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
# Tests a portion of the Component CRUD Python API while the Editor is running
import sys
import azlmbr.legacy.general as general
import azlmbr.bus as bus
import azlmbr.editor as editor
from azlmbr.entity import EntityType
def validate_component_property_apis(levelEntityComponentIdPair, componentName, componentUuid):
propertyTreeOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'BuildComponentPropertyTreeEditor', levelEntityComponentIdPair)
if not propertyTreeOutcome.IsSuccess():
print("ERROR: BuildComponentPropertyTreeEditor failed for component with name={}, uuid={}".format(componentName, componentUuid))
return False
pte = propertyTreeOutcome.GetValue()
propList = pte.build_paths_list()
propList2 = editor.EditorComponentAPIBus(bus.Broadcast, 'BuildComponentPropertyList', levelEntityComponentIdPair)
if len(propList) != len(propList2):
print("ERROR: len(propList)={} != len(propList2)={} for component with name={}, uuid={}".format(len(propList), len(propList2), componentName, componentUuid))
return False
for propName in propList2:
#Some components like the Comment component have empty string property.
if propName == "":
continue
propOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentProperty', levelEntityComponentIdPair, propName)
if not propOutcome.IsSuccess():
print("ERROR: Failed to get component property={} for component with name={}, uuid={}".format(propName, componentName, componentUuid))
return False
if not propName in propList2:
print("ERROR: Failed to find component property={} in propList2 for component with name={}, uuid={}".format(propName, componentName, componentUuid))
return False
return True
def validate_level_component_api(componentName, componentUuid):
if componentName == "PhysX Terrain":
#Skip physX. It has issues now that the Legacy Terrain is a component.
return True
if editor.EditorLevelComponentAPIBus(bus.Broadcast, 'HasComponentOfType', componentUuid):
print("ERROR: Component with name={}, uuid={} was already present".format(componentName, componentUuid))
return False
if editor.EditorLevelComponentAPIBus(bus.Broadcast, 'CountComponentsOfType', componentUuid) > 0:
print("ERROR: Component with name={}, uuid={} was already present".format(componentName, componentUuid))
return False
addComponentsOutcome = editor.EditorLevelComponentAPIBus(bus.Broadcast, 'AddComponentsOfType', [componentUuid])
if not addComponentsOutcome.IsSuccess():
print("ERROR: Failed to add Component with name={}, uuid={}".format(componentName, componentUuid))
return False
componentIds = addComponentsOutcome.GetValue()
if len(componentIds) != 1:
print("ERROR: Expecting 1 added Component with name={}, uuid={}".format(componentName, componentUuid))
return False
print("SUCCESS: Added 1 Component with name={}, uuid={}".format(componentName, componentUuid))
general.idle_wait(3.0)
if not editor.EditorLevelComponentAPIBus(bus.Broadcast, 'HasComponentOfType', componentUuid):
print("ERROR: Component with name={}, uuid={} was not present".format(componentName, componentUuid))
return False
if editor.EditorLevelComponentAPIBus(bus.Broadcast, 'CountComponentsOfType', componentUuid) != 1:
print("ERROR: Was expecting 1 Component with name={}, uuid={}".format(componentName, componentUuid))
return False
getComponentOutcome = editor.EditorLevelComponentAPIBus(bus.Broadcast, 'GetComponentOfType', componentUuid)
if not getComponentOutcome.IsSuccess():
print("ERROR: Failed to get added component with name={}, uuid={}".format(componentName, componentUuid))
return False
componentId = getComponentOutcome.GetValue()
if not componentId.Equal(componentIds[0]):
print("ERROR. GetComponentOfType no matching for component with name={}, uuid={}".format(componentName, componentUuid))
return False
getComponentsOutcome = editor.EditorLevelComponentAPIBus(bus.Broadcast, 'GetComponentsOfType', componentUuid)
newComponentIds = getComponentsOutcome.GetValue()
if len(newComponentIds) != 1:
print("ERROR: Expecting to get 1 Component with name={}, uuid={}".format(componentName, componentUuid))
return False
if not componentIds[0].Equal(newComponentIds[0]):
print("ERROR. GetComponentsOfType no matching for component with name={}, uuid={}".format(componentName, componentUuid))
return False
if not editor.EditorComponentAPIBus(bus.Broadcast, 'IsValid', componentId):
print("ERROR. expecting valid component with name={}, uuid={}".format(componentName, componentUuid))
return False
if not editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', componentId):
if not editor.EditorComponentAPIBus(bus.Broadcast, 'EnableComponents', [componentId]):
print("ERROR. Failed to pre-enable component with name={}, uuid={}".format(componentName, componentUuid))
return False
print("SUCCESS: pre-enabled component with name={}, uuid={} ".format(componentName, componentUuid))
general.idle_wait(3.0)
if not editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', componentId):
print("ERROR. Expecting enabled component with name={}, uuid={}".format(componentName, componentUuid))
return False
if not editor.EditorComponentAPIBus(bus.Broadcast, 'DisableComponents', [componentId]):
print("ERROR. Failed to disable component with name={}, uuid={}".format(componentName, componentUuid))
return False
print("SUCCESS: Disabled component with name={}, uuid={} ".format(componentName, componentUuid))
general.idle_wait(1.0)
if editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', componentId):
print("ERROR. Expecting disabled component with name={}, uuid={}".format(componentName, componentUuid))
return False
if not editor.EditorComponentAPIBus(bus.Broadcast, 'EnableComponents', [componentId]):
print("ERROR. Failed to re-enable component with name={}, uuid={}".format(componentName, componentUuid))
return False
print("SUCCESS: Re-enabled component with name={}, uuid={} ".format(componentName, componentUuid))
general.idle_wait(3.0)
if not validate_component_property_apis(componentId, componentName, componentUuid):
print("ERROR. Failed to validate_component_property_apis for component with name={}, uuid={}".format(componentName, componentUuid))
return False
if not editor.EditorComponentAPIBus(bus.Broadcast, 'RemoveComponents', [componentId]):
print("ERROR. Failed to remove component with name={}, uuid={}".format(componentName, componentUuid))
return False
print("SUCCESS: Removed component with name={}, uuid={} ".format(componentName, componentUuid))
general.idle_wait(1.0)
if editor.EditorLevelComponentAPIBus(bus.Broadcast, 'HasComponentOfType', componentUuid):
print("ERROR: Was not expecting to have Component with name={}, uuid={}".format(componentName, componentUuid))
return False
print("SUCCESS: validated API with component with name={}, uuid={} ".format(componentName, componentUuid))
return True
exitWhenDone = False
if len(sys.argv) > 1:
if sys.argv[1] == "exit_when_done":
exitWhenDone = True
# Open a level (any level should work)
general.create_level_no_prompt('LevelComponentTest', 128, 1, 512, True)
# Make sure the default slices get a chance to initialize.
general.idle_wait(1.0)
# Generate List of Component Types
componentList = editor.EditorComponentAPIBus(bus.Broadcast, 'BuildComponentTypeNameListByEntityType', EntityType().Level)
if(len(componentList) > 0):
print("Component List returned correctly")
# Get Component Types for all level components
typeIdsList = editor.EditorComponentAPIBus(bus.Broadcast, 'FindComponentTypeIdsByEntityType', componentList, EntityType().Level)
if len(typeIdsList) != len(componentList):
print("ERROR: length of typeIdsList={} and length of componentList={}".format(len(typeIdsList), len(componentList)))
general.exit_no_prompt()
print("Type Ids List returned correctly")
# Get Component names from Component Types
typeNamesList = editor.EditorComponentAPIBus(bus.Broadcast, 'FindComponentTypeNames', typeIdsList)
if len(typeIdsList) != len(typeNamesList):
print("ERROR: length of typeIdsList={} and length of typeNamesList={}".format(len(typeIdsList), len(typeNamesList)))
general.exit_no_prompt()
for i in range(len(componentList)):
if componentList[i] != typeNamesList[i]:
print("ERROR: componentList[{}]({}) != typeNamesList=[{}]({})".format(i, componentList[i], i, typeNamesList[i]))
general.exit_no_prompt()
print("Type Names List returned correctly")
#Let's add each level component, one at a time, wait, remove component
for i in range(len(componentList)):
if validate_level_component_api(componentList[i], typeIdsList[i]):
continue
print("ERROR: Failed to validate_level_component_api for component with name={}, uuid={}".format(componentList[i], typeIdsList[i]))
general.exit_no_prompt()
print("Level Component API validated")
if exitWhenDone:
general.exit_no_prompt()
@@ -0,0 +1,40 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
#
# This is a pytest module to test the in-Editor Python API from PythonEditorFuncs
#
import pytest
pytest.importorskip('ly_test_tools')
import sys
import os
sys.path.append(os.path.dirname(__file__))
from hydra_utils import launch_test_case
@pytest.mark.SUITE_sandbox
@pytest.mark.parametrize('launcher_platform', ['windows_editor'])
@pytest.mark.parametrize('project', ['AutomatedTesting'])
@pytest.mark.parametrize('level', ['Simple'])
class TestLevelPathsAutomation(object):
def test_Legacy_LevelPaths(self, request, editor, level, launcher_platform):
unexpected_lines=[]
expected_lines = [
"Level name is correct",
"The level is in the Levels folder",
"Game folder is correct"
]
test_case_file = os.path.join(os.path.dirname(__file__), 'LevelPathsCommands_test_case.py')
launch_test_case(editor, test_case_file, expected_lines, unexpected_lines)
@@ -0,0 +1,51 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
# Tests a portion of the Python API from CryEdit.cpp while the Editor is running
import os
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.legacy.general as general
# Open a level (any level should work)
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'OpenLevelNoPrompt', 'WaterSample')
# Get level path
levelpath = general.get_current_level_path()
# Split level path and get level name
path, level = os.path.split(levelpath)
# Get level name
levelname = general.get_current_level_name()
# Compare level name gotten from path to levelname
if(level == levelname):
print("Level name is correct")
# Remove Levels folder from path
parent, levels = os.path.split(path)
if(levels == "Levels"):
print("The level is in the Levels folder")
# Get game folder
gamefolder = general.get_game_folder()
# Compare game folder - normalize first because of the different formats
norm_gamefolder = os.path.normcase(gamefolder)
norm_parent = os.path.normcase(parent)
if(norm_parent == norm_gamefolder):
print("Game folder is correct")
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'ExitNoPrompt')
@@ -0,0 +1,41 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
#
# This is a pytest module to test the in-Editor Python API from PythonEditorFuncs
#
import pytest
pytest.importorskip('ly_test_tools')
import sys
import os
sys.path.append(os.path.dirname(__file__))
from hydra_utils import launch_test_case
@pytest.mark.SUITE_sandbox
@pytest.mark.parametrize('launcher_platform', ['windows_editor'])
@pytest.mark.parametrize('project', ['AutomatedTesting'])
@pytest.mark.parametrize('level', ['Simple'])
class TestMainWindowAutomation(object):
def test_MainWindow(self, request, editor, level, launcher_platform):
unexpected_lines=[]
expected_lines = [
"get_pane_class_names worked",
"open_pane worked",
"close_pane worked"
]
test_case_file = os.path.join(os.path.dirname(__file__), 'MainWindowCommands_test_case.py')
launch_test_case(editor, test_case_file, expected_lines, unexpected_lines)
@@ -0,0 +1,37 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
# Tests the Python API from MainWindow.cpp while the Editor is running
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.legacy.general as general
# Get all pane names
panes = general.get_pane_class_names()
if(len(panes) > 0):
print('get_pane_class_names worked')
# Get any element from the panes list
test_pane = panes[4]
general.open_pane(test_pane)
if (general.is_pane_visible(test_pane)) :
print('open_pane worked')
general.close_pane(test_pane)
if not (general.is_pane_visible(test_pane)) :
print('close_pane worked')
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'ExitNoPrompt')
@@ -0,0 +1,54 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
#
# This is a pytest module to test the in-Editor Python API from PythonEditorFuncs
#
import pytest
pytest.importorskip('ly_test_tools')
import sys
import os
sys.path.append(os.path.dirname(__file__))
from hydra_utils import launch_test_case
@pytest.mark.SUITE_sandbox
@pytest.mark.parametrize('launcher_platform', ['windows_editor'])
@pytest.mark.parametrize('project', ['AutomatedTesting'])
@pytest.mark.parametrize('level', ['Simple'])
class TestObjectManagerAutomation(object):
def test_ViewPane(self, request, editor, level, launcher_platform):
unexpected_lines=[]
expected_lines = [
"get_all_objects works",
"get_names_of_selected_objects works",
"select_objects works",
"sel_position and sel_aabb both work",
"get_num_selected and unselect_objects both work",
"clear_selection works",
"hide_all_objects works",
"unhide_object works",
"hide_object works",
"freeze_object works",
"position setter/getter works",
"rotation setter/getter works",
"scale setter/getter works",
"delete_selected works",
"delete_object works",
"rename_object works"
]
test_case_file = os.path.join(os.path.dirname(__file__), 'ObjectManagerCommands_test_case.py')
launch_test_case(editor, test_case_file, expected_lines, unexpected_lines)
@@ -0,0 +1,145 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
# Tests a portion of the Python API from ObjectManager.cpp while the Editor is running
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.math
import azlmbr.legacy.general as general
def fetch_vector3_parts(vec3):
x = vec3.get_property('x')
y = vec3.get_property('y')
z = vec3.get_property('z')
return (x, y, z)
general.idle_enable(True)
# Try to open the WaterSample level. If not, fail the test.
# We need to rely on an existing level since the API does not provide
# a way to create entities, but only lets us manipulate them.
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'OpenLevelNoPrompt', 'WaterSample')
if (editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'GetCurrentLevelName') == 'WaterSample'):
objs_list = general.get_all_objects()
if(len(objs_list) > 0):
print("get_all_objects works")
general.clear_selection()
general.select_object(objs_list[0])
selected_objs_list = general.get_names_of_selected_objects()
if(len(selected_objs_list) == 1):
print("get_names_of_selected_objects works")
select = [objs_list[1], objs_list[2]]
general.select_objects(select)
selected_objs_list = general.get_names_of_selected_objects()
if(len(selected_objs_list) == 3):
print("select_objects works")
sel_position = general.get_selection_center()
sel_aabb = general.get_selection_aabb()
centerX = sel_position.get_property("x")
cornerX = sel_aabb.get_property("min").get_property("x")
if not(centerX == cornerX):
print("sel_position and sel_aabb both work")
unselect = [objs_list[0], objs_list[2]]
general.unselect_objects(unselect)
if(general.get_num_selected() == 1):
print("get_num_selected and unselect_objects both work")
general.clear_selection()
if(general.get_num_selected() == 0):
print("clear_selection works")
general.hide_all_objects()
if(general.is_object_hidden(objs_list[1])):
print("hide_all_objects works")
general.unhide_object(objs_list[1])
if not(general.is_object_hidden(objs_list[1])):
print("unhide_object works")
general.hide_object(objs_list[1])
if(general.is_object_hidden(objs_list[1])):
print("hide_object works")
general.unhide_all_objects()
general.freeze_object(objs_list[1])
if(general.is_object_frozen(objs_list[1])):
print("freeze_object works")
general.unfreeze_object(objs_list[1])
position = general.get_position(objs_list[1])
px1, py1, pz1 = fetch_vector3_parts(position)
general.set_position(objs_list[1], px1 + 10, py1 - 4, pz1 + 3)
new_position = general.get_position(objs_list[1])
px2, py2, pz2 = fetch_vector3_parts(new_position)
if(px2 > px1) and (py2 < py1) and (pz2 > pz1):
print("position setter/getter works")
rotation = general.get_rotation(objs_list[1])
rx1, ry1, rz1 = fetch_vector3_parts(rotation)
general.set_rotation(objs_list[1], rx1 + 10, ry1 - 4, rz1 + 3)
new_rotation = general.get_rotation(objs_list[1])
rx2, ry2, rz2 = fetch_vector3_parts(new_rotation)
if(rx2 > rx1) and (ry2 < ry1) and (rz2 > rz1):
print("rotation setter/getter works")
scale = general.get_scale(objs_list[1])
sx1, sy1, sz1 = fetch_vector3_parts(scale)
general.set_scale(objs_list[1], sx1 + 10, sy1 + 4, sz1 + 3)
new_scale = general.get_scale(objs_list[1])
sx2, sy2, sz2 = fetch_vector3_parts(new_scale)
if(sx2 > sx1) and (sy2 > sy1) and (sz2 > sz1):
print("scale setter/getter works")
general.select_object(objs_list[2])
general.delete_selected()
new_objs_list = general.get_all_objects()
if(len(new_objs_list) < len(objs_list)):
print("delete_selected works")
general.delete_object(objs_list[0])
new_objs_list = general.get_all_objects()
if(len(new_objs_list) < len(objs_list)):
print("delete_object works")
general.rename_object(objs_list[1], "some_test_name")
new_objs_list = general.get_all_objects()
for elem in new_objs_list:
if(elem == "some_test_name"):
print("rename_object works")
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'ExitNoPrompt')
@@ -0,0 +1,40 @@
''
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
#
# This is a pytest module to test the in-Editor Python API Object Representation
#
import pytest
pytest.importorskip('ly_test_tools')
import sys
import os
sys.path.append(os.path.dirname(__file__))
from hydra_utils import launch_test_case
@pytest.mark.SUITE_sandbox
@pytest.mark.parametrize('launcher_platform', ['windows_editor'])
@pytest.mark.parametrize('project', ['AutomatedTesting'])
@pytest.mark.parametrize('level', ['Simple'])
class TestObjectStringRepresentation(object):
def test_ObjectReprStr(self, request, editor, level, launcher_platform):
unexpected_lines=[]
expected_lines = [
"repr() returned expected value",
"str() returned expected value"
]
test_case_file = os.path.join(os.path.dirname(__file__), 'ObjectStringRepresentation_test_case.py')
launch_test_case(editor, test_case_file, expected_lines, unexpected_lines)
@@ -0,0 +1,34 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
# Tests the PythonProxyObject __str__ and __repr__
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.entity as entity
import azlmbr.object
test_id = entity.EntityId()
test_id_repr = repr(test_id)
if test_id_repr.startswith('<EntityId via PythonProxyObject at'):
print("repr() returned expected value")
test_id_str = str(test_id)
test_id_to_string = test_id.ToString()
print(test_id_str)
print(test_id_to_string)
if test_id_str == test_id_to_string:
print("str() returned expected value")
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'ExitNoPrompt')
@@ -0,0 +1,39 @@
''
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
#
# This test shows how to use PySide2 inside an Editor Python Bindings test.
#
import pytest
import sys
import os
from .hydra_utils import launch_test_case
@pytest.mark.SUITE_sandbox
@pytest.mark.parametrize('launcher_platform', ['windows_editor'])
@pytest.mark.parametrize('project', ['AutomatedTesting'])
@pytest.mark.parametrize('level', ['Simple'])
class TestPySideExample(object):
def test_PySideExample(self, request, editor, level, launcher_platform):
unexpected_lines = []
expected_lines = [
'New entity with no parent created',
'Environment Probe component added to entity',
'ComboBox Values retrieved:'
]
test_case_file = os.path.join(os.path.dirname(__file__), 'PySide_Example_test_case.py')
launch_test_case(editor, test_case_file, expected_lines, unexpected_lines)
@@ -0,0 +1,62 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
#
# This test shows how to use PySide2 inside an Editor Python Bindings test.
# For PySide details see automatedtesting_shared/pyside_utils.py and automatedtesting_shared/pyside_component_utils.py
#
import sys
import os
import PySide2
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../automatedtesting_shared')
import azlmbr.bus as bus
import azlmbr.entity as entity
import azlmbr.editor as editor
import azlmbr.legacy.general as general
import pyside_component_utils
def PySide_Example_test_case():
# Open level, any level should work
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'OpenLevelNoPrompt', os.path.join('WhiteBox', 'EmptyLevel'))
entityId = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', entity.EntityId())
if entityId:
print('New entity with no parent created')
# Get Component Type for Environment Probe and attach to entity
typeIdsList = editor.EditorComponentAPIBus(bus.Broadcast, 'FindComponentTypeIdsByEntityType', ["Environment Probe"],
entity.EntityType().Game)
componentOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentsOfType', entityId, typeIdsList)
if componentOutcome.IsSuccess():
print('Environment Probe component added to entity')
# Waiting for one frame so that the widgets in the UI are updated with the new component information
general.idle_enable(True)
general.idle_wait_frames(1)
values = pyside_component_utils.get_component_combobox_values('Environment Probe', 'Resolution', print)
if values:
print(f'ComboBox Values retrieved: {values}.')
else:
print('Could not retrieve ComboBox values')
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'ExitNoPrompt')
if __name__ == '__main__':
PySide_Example_test_case()
@@ -0,0 +1,48 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
#
# This is a pytest module to test the in-Editor Python API from VertexMode.h
#
import pytest
pytest.importorskip('ly_test_tools')
import sys
import os
sys.path.append(os.path.dirname(__file__))
from .hydra_utils import launch_test_case
@pytest.mark.SUITE_sandbox
@pytest.mark.parametrize('launcher_platform', ['windows_editor'])
@pytest.mark.parametrize('project', ['AutomatedTesting'])
@pytest.mark.parametrize('level', ['Simple'])
class TestTrackViewAutomation(object):
def test_Supported_TrackView(self, request, editor, level, launcher_platform):
unexpected_lines = []
expected_lines = [
'[PASS] GetNumSequences returned the expected number of sequences [2].',
'[PASS] GetSequenceName returned the expected name [Test Sequence 01]',
'[PASS] SetSequenceTimeRange modified time range successfully.',
'[PASS] DeleteSequence ran with no error thrown.',
'[PASS] SetCurrentSequence ran with no error thrown.',
'[PASS] PlaySequence ran with no error thrown.',
'[PASS] AddNode ran with no error thrown.',
'[PASS] Found the expected number of nodes [2].',
'[PASS] GetNodeName returned the expected name [Test Node 01].',
'[PASS] DeleteNode ran with no error thrown.',
'[PASS] Found the expected number of nodes [1].',
'[PASS] DeleteSequence ran with no error thrown.'
]
test_case_file = os.path.join(os.path.dirname(__file__), 'TrackViewCommands_test_case.py')
launch_test_case(editor, test_case_file, expected_lines, unexpected_lines)
@@ -0,0 +1,101 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
# Tests the track view
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.track_view as track_view
import azlmbr.legacy.general as general
print ('Start of track view tests.')
general.idle_wait(1.0)
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'OpenLevelNoPrompt', 'ocean_trackview')
general.idle_wait(1.0)
num_sequences = track_view.EditorLayerTrackViewRequestBus(bus.Broadcast, 'GetNumSequences')
test_sequence_name = 'Test Sequence 01'
track_view.EditorLayerTrackViewRequestBus(bus.Broadcast, 'NewSequence', test_sequence_name, 1)
new_num_sequences = track_view.EditorLayerTrackViewRequestBus(bus.Broadcast, 'GetNumSequences')
if new_num_sequences == num_sequences + 1:
print('[PASS] GetNumSequences returned the expected number of sequences [{}].'.format(new_num_sequences))
else:
print('[FAIL] GetNumSequences returned an unexpected number of sequences, was [{}] and expected [{}].'.
format(new_num_sequences, num_sequences + 1))
returned_name = track_view.EditorLayerTrackViewRequestBus(bus.Broadcast, 'GetSequenceName', 0)
if returned_name == test_sequence_name:
print('[PASS] GetSequenceName returned the expected name [{}]'.format(test_sequence_name))
else:
print('[FAIL] GetSequenceName returned an unexpected name, was [{}] and expected [{}].'.
format(returned_name, test_sequence_name))
# Test modifying the sequence time range
time_range = track_view.EditorLayerTrackViewRequestBus(bus.Broadcast, 'GetSequenceTimeRange', test_sequence_name)
start = time_range.start + 5.0
end = time_range.end + 10.0
track_view.EditorLayerTrackViewRequestBus(bus.Broadcast, 'SetSequenceTimeRange', test_sequence_name, start, end)
new_time_range = track_view.EditorLayerTrackViewRequestBus(bus.Broadcast, 'GetSequenceTimeRange', test_sequence_name)
if (int(new_time_range.start) != int(time_range.start)) and (int(new_time_range.end) != int(time_range.end)):
print('[PASS] SetSequenceTimeRange modified time range successfully.')
else:
print('[FAIL] SetSequenceTimeRange did not modify the time range as expected.')
test_sequence_name_2 = 'Test Sequence 02'
track_view.EditorLayerTrackViewRequestBus(bus.Broadcast, 'NewSequence', test_sequence_name_2, 1)
track_view.EditorLayerTrackViewRequestBus(bus.Broadcast, 'DeleteSequence', test_sequence_name_2)
print('[PASS] DeleteSequence ran with no error thrown.')
track_view.EditorLayerTrackViewRequestBus(bus.Broadcast, 'SetCurrentSequence', test_sequence_name)
print('[PASS] SetCurrentSequence ran with no error thrown.')
track_view.EditorLayerTrackViewRequestBus(bus.Broadcast, 'PlaySequence')
print('[PASS] PlaySequence ran with no error thrown.')
track_view.EditorLayerTrackViewRequestBus(bus.Broadcast, 'AddNode', 'Director', 'Test Director')
test_node_name = 'Test Node 01'
track_view.EditorLayerTrackViewRequestBus(bus.Broadcast, 'AddNode', 'Event', test_node_name)
print('[PASS] AddNode ran with no error thrown.')
new_num_nodes = track_view.EditorLayerTrackViewRequestBus(bus.Broadcast, 'GetNumNodes', '')
num_expected_nodes = 2
if new_num_nodes == num_expected_nodes:
print('[PASS] Found the expected number of nodes [{}].'.format(num_expected_nodes))
else:
print('[FAIL] Found [{}] instead of [{}] nodes.'.format(new_num_nodes, num_expected_nodes))
returned_node_name = track_view.EditorLayerTrackViewRequestBus(bus.Broadcast, 'GetNodeName', 1, '')
if returned_node_name == test_node_name:
print('[PASS] GetNodeName returned the expected name [{}].'.format(test_node_name))
else:
print('[FAIL] GetNodeName returned [{}] and expected [{}].'.format(test_node_name, returned_node_name))
track_view.EditorLayerTrackViewRequestBus(bus.Broadcast, 'DeleteNode', test_node_name, '')
print('[PASS] DeleteNode ran with no error thrown.')
new_num_nodes = track_view.EditorLayerTrackViewRequestBus(bus.Broadcast, 'GetNumNodes', '')
num_expected_nodes = 1
if new_num_nodes == num_expected_nodes:
print('[PASS] Found the expected number of nodes [{}].'.format(num_expected_nodes))
else:
print('[FAIL] Found [{}] instead of [{}] nodes.'.format(new_num_nodes, num_expected_nodes))
track_view.EditorLayerTrackViewRequestBus(bus.Broadcast, 'DeleteSequence', test_sequence_name)
print('[PASS] DeleteSequence ran with no error thrown.')
print ('End of track view tests.')
@@ -0,0 +1,46 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
#
# This is a pytest module to test the in-Editor Python API from PythonEditorFuncs
#
import pytest
pytest.importorskip('ly_test_tools')
import sys
import os
sys.path.append(os.path.dirname(__file__))
from hydra_utils import launch_test_case
@pytest.mark.SUITE_sandbox
@pytest.mark.parametrize('launcher_platform', ['windows_editor'])
@pytest.mark.parametrize('project', ['AutomatedTesting'])
@pytest.mark.parametrize('level', ['Simple'])
class TestViewPaneAutomation(object):
def test_ViewPane(self, request, editor, level, launcher_platform):
unexpected_lines=[]
expected_lines = [
"set_viewport_size works",
"resize_viewport works",
"get_viewport_expansion_policy works",
"set_viewport_expansion_policy works",
"get_view_pane_layout works",
"set_view_pane_layout works",
"get_viewport_count works",
"get_active_viewport works",
"set_active_viewport works"
]
test_case_file = os.path.join(os.path.dirname(__file__), 'ViewPaneCommands_test_case.py')
launch_test_case(editor, test_case_file, expected_lines, unexpected_lines)
@@ -0,0 +1,103 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
# Tests a portion of the View Pane Python API from ViewPane.cpp while the Editor is running
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.math
import azlmbr.legacy.general as general
# Open a level (any level should work)
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'OpenLevelNoPrompt', 'WaterSample')
general.idle_wait(0.5)
viewport_size = general.get_viewport_size()
view_width = int(viewport_size.x)
view_height = int(viewport_size.y)
general.set_viewport_size(320, 240)
new_viewport_size = general.get_viewport_size()
new_view_width = int(new_viewport_size.x)
new_view_height = int(new_viewport_size.y)
if not (view_width == new_view_width) and not (view_height == new_view_height):
print("set_viewport_size works")
general.resize_viewport(int(view_width), int(view_height))
newer_viewport_size = general.get_viewport_size()
newer_view_width = int(newer_viewport_size.x)
newer_view_height = int(newer_viewport_size.y)
if not (newer_view_width == new_view_width) and not (newer_view_height == new_view_height):
print("resize_viewport works")
def set_and_validate_viewport_size(width, height):
general.set_viewport_size(width, height)
general.update_viewport()
general.idle_wait(1.0)
new_viewport_size = general.get_viewport_size()
if (new_viewport_size.x != width) or (new_viewport_size.y != height):
return False
return True
# Perform some simple validation of get/set viewport expansion policy
general.set_viewport_expansion_policy('FixedSize')
if (general.get_viewport_expansion_policy() == 'FixedSize'):
print("get_viewport_expansion_policy works")
general.set_viewport_expansion_policy('AutoExpand')
if (general.get_viewport_expansion_policy() == 'AutoExpand'):
print("get_viewport_expansion_policy works")
# Validate that setting it to an invalid value doesn't change the setting.
general.set_viewport_expansion_policy('XXXXX')
if (general.get_viewport_expansion_policy() == 'AutoExpand'):
print("get_viewport_expansion_policy works")
# Set a series of viewport sizes (smaller to larger than display resolution sizes) and verify they all work.
general.set_viewport_expansion_policy('FixedSize')
if (set_and_validate_viewport_size(150, 300)):
print("set_viewport_expansion_policy works")
# Set different view pane layouts and verify it works
success = True
general.set_view_pane_layout(0)
general.idle_wait(0.5)
success = success and (general.get_view_pane_layout() == 0)
success = success and (general.get_viewport_count() == 1)
general.set_view_pane_layout(1)
general.idle_wait(0.5)
success = success and (general.get_view_pane_layout() == 1)
success = success and (general.get_viewport_count() == 2)
if success:
print("get_view_pane_layout works")
print("set_view_pane_layout works")
print("get_viewport_count works")
success = True
general.set_active_viewport(0)
general.idle_wait(0.5)
success = success and (general.get_active_viewport() == 0)
general.set_active_viewport(1)
general.idle_wait(0.5)
success = success and (general.get_active_viewport() == 1)
if success:
print("get_active_viewport works")
print("set_active_viewport works")
general.set_view_pane_layout(0)
general.idle_wait(0.5)
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'ExitNoPrompt')
@@ -0,0 +1,2 @@
# this file is copied to $/dev/editor_autoexec.cfg so the the Editor automation runs for this Hydra test
pyRunFile @devroot@/Tests/hydra/ViewportTitleDlgCommands_test_case.py
@@ -0,0 +1,60 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
#
# This is a pytest module to test the in-Editor Python API from ViewportTitleDlg
#
import pytest
pytest.importorskip('test_tools')
import time
import logging
import os
import shutil
from test_tools import WINDOWS_LAUNCHER
import test_tools.shared.log_monitor
import test_tools.launchers.phase
import test_tools.builtin.fixtures as fixtures
# Use the built-in workspace and editor fixtures.
# These will configure the requested project and run the editor.
workspace = fixtures.use_fixture(fixtures.builtin_workspace_fixture, scope='function')
editor = fixtures.use_fixture(fixtures.editor, scope='function')
logger = logging.getLogger(__name__)
@pytest.mark.SUITE_sandbox
@pytest.mark.parametrize("platform,configuration,project,spec", [
pytest.param("win_x64_vs2017", "profile", "AutomatedTesting", "all", marks=pytest.mark.skipif(not WINDOWS_LAUNCHER, reason="Only supported on Windows hosts")),
])
class TestViewportTitleDlgAutomation(object):
def test_ViewportTitleDlg_API(self, request, editor, project):
logger.debug("Running automated test for ViewportTitleDlg")
request.addfinalizer(editor.ensure_stopped)
editor.deploy()
editor.launch(["--exec", "@engroot@/Tests/hydra/ViewportTitleDlgCommands.cfg"])
editorlog_file = os.path.join(editor.workspace.release.paths.project_log(), 'Editor.log')
expected_lines = [
"toggle_helpers works",
"is_helpers_shown works"
]
test_tools.shared.log_monitor.monitor_for_expected_lines(editor, editorlog_file, expected_lines)
# Rely on the test script to quit after running
editor.run(test_tools.launchers.phase.WaitForLauncherToQuit(editor, 10))
@@ -0,0 +1,40 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
# Tests the ViewportTitleDlg Python API from ViewportTitleDlg.cpp while the Editor is running
import azlmbr.math
import azlmbr.legacy.general as general
# Open a level (any level should work)
general.open_level_no_prompt('WaterSample')
general.idle_wait(0.5)
test_success = True
# Get the current state of our helpers toggle.
initial_state = general.is_helpers_shown()
# Toggle it once and verify it changed
general.toggle_helpers()
test_success = test_success and (initial_state != general.is_helpers_shown())
# Toggle it a second time and verify it changed back to the original setting.
# Note: We specifically choose an even number of times so we leave the Editor
# in the same state as we found it. :)
general.toggle_helpers()
test_success = test_success and (initial_state == general.is_helpers_shown())
if test_success:
print('toggle_helpers works')
print('is_helpers_shown works')
general.exit_no_prompt()
@@ -0,0 +1,40 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
#
# This is a pytest module to test the in-Editor Python API for Entity CRUD
#
import pytest
pytest.importorskip('ly_test_tools')
import sys
import os
sys.path.append(os.path.dirname(__file__))
from hydra_utils import launch_test_case
@pytest.mark.SUITE_sandbox
@pytest.mark.parametrize('launcher_platform', ['windows_editor'])
@pytest.mark.parametrize('project', ['AutomatedTesting'])
@pytest.mark.parametrize('level', ['Simple'])
class TestEntityCommandsAutomation(object):
def test_EntityCommands(self, request, editor, level, launcher_platform):
unexpected_lines=[]
expected_lines = [
"Time is bigger after frames",
"Exact frames elapsed"
]
test_case_file = os.path.join(os.path.dirname(__file__), 'WaitCommands_test_case.py')
launch_test_case(editor, test_case_file, expected_lines, unexpected_lines)
@@ -0,0 +1,51 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.math
import azlmbr.legacy.general as general
# open any level
general.idle_enable(True)
general.idle_wait(0.5)
preTimePoint = azlmbr.components.TickRequestBus(bus.Broadcast, "GetTimeAtCurrentTick")
preTimeMs = preTimePoint.GetMilliseconds()
TICKS_TO_WAIT = 5
numTicks = 0
def onTick(args):
global numTicks
numTicks += 1
handler = bus.NotificationHandler('TickBus')
handler.connect(None)
handler.add_callback('OnTick', onTick)
general.idle_wait_frames(TICKS_TO_WAIT)
postTimePoint = azlmbr.components.TickRequestBus(bus.Broadcast, "GetTimeAtCurrentTick")
postTimeMs = postTimePoint.GetMilliseconds()
if postTimeMs > preTimeMs:
print("Time is bigger after frames")
if numTicks == TICKS_TO_WAIT:
print("Exact frames elapsed")
handler.disconnect()
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'ExitNoPrompt')
@@ -0,0 +1,10 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
@@ -0,0 +1,62 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
#
# Helpful functions to simplify running the Hydra tests
#
import pytest
pytest.importorskip('ly_test_tools')
import os
import ly_test_tools.log.log_monitor
import ly_test_tools.environment.waiter as waiter
import logging
logger = logging.getLogger(__name__)
def launch_test_case(editor, test_case, expected_lines, unexpected_lines):
timeout=180
halt_on_unexpected=False
logger.debug("Running automated test: {}".format(test_case))
editor.args.extend(['-NullRenderer', "--skipWelcomeScreenDialog", "--autotest_mode", "--runpythontest", test_case])
print ('editor.args = {}'.format(editor.args))
with editor.start():
editorlog_file = os.path.join(editor.workspace.paths.project_log(), 'Editor.log')
log_monitor = ly_test_tools.log.log_monitor.LogMonitor(editor, editorlog_file)
logger.debug("Waiting for log file '{}' to be opened by another process.".format(editorlog_file))
waiter.wait_for(
lambda: editor.is_alive(),
timeout,
exc=("Log file '{}' was never opened by another process.".format(editorlog_file)),
interval=1)
log_monitor.monitor_log_for_lines(expected_lines, unexpected_lines, halt_on_unexpected, timeout)
def launch_test_case_with_args(editor, test_case, expected_lines, unexpected_lines, extra_args):
timeout=180
halt_on_unexpected=False
logger.debug("Running automated test: {}".format(test_case))
editor.args.extend(['-NullRenderer', "--skipWelcomeScreenDialog", "--autotest_mode", "--runpythontest", test_case, '--runpythonargs'])
editor.args.extend(extra_args)
print ('editor.args = {}'.format(editor.args))
with editor.start():
editorlog_file = os.path.join(editor.workspace.paths.project_log(), 'Editor.log')
log_monitor = ly_test_tools.log.log_monitor.LogMonitor(editor, editorlog_file)
logger.debug("Waiting for log file '{}' to be opened by another process.".format(editorlog_file))
waiter.wait_for(
lambda: editor.is_alive(),
timeout,
exc=("Log file '{}' was never opened by another process.".format(editorlog_file)),
interval=1)
log_monitor.monitor_log_for_lines(expected_lines, unexpected_lines, halt_on_unexpected, timeout)
@@ -0,0 +1,51 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
#
# This is a pytest module to test the in-Editor Python API for Entity CRUD
#
import pytest
pytest.importorskip('ly_test_tools')
import sys
import os
sys.path.append(os.path.dirname(__file__))
from .hydra_utils import launch_test_case
@pytest.mark.SUITE_sandbox
@pytest.mark.parametrize('launcher_platform', ['windows_editor'])
@pytest.mark.parametrize('project', ['AutomatedTesting'])
@pytest.mark.parametrize('level', ['Simple'])
class TestLayerEntityAutomation(object):
def test_LayerEntity(self, request, editor, level, launcher_platform):
unexpected_lines=[]
expected_lines = [
"[PASS] layer has been created",
"[PASS] successfully changed status: 0",
"[PASS] successfully changed status: 1",
"[PASS] successfully changed status: 2",
"[PASS] Get name request succeeded",
"[PASS] Layer name changed",
"[PASS] Layer color changed",
"[PASS] layer child entity has been created",
"[PASS] Query parent returned layer ID",
"[PASS] EditorEntityInfoRequestBus GetChildren return list of decendants",
"[PASS] comment component has been added",
"[PASS] layer has been locked",
"[PASS] layer children are hidden",
"[PASS] Layer entity not found after delete request"
]
test_case_file = os.path.join(os.path.dirname(__file__), 'layerEntity_test_case.py')
launch_test_case(editor, test_case_file, expected_lines, unexpected_lines)
@@ -0,0 +1,143 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
# Tests AZ Layer creation, property modification and interaction with entity CRUD operations in the editor
import sys
import azlmbr.layers as layers
import azlmbr.editor as editor
import azlmbr.bus as bus
import azlmbr.entity as entity
import azlmbr.math as math
def add_component(typename, entityId):
typeIdsList = editor.EditorComponentAPIBus(bus.Broadcast, 'FindComponentTypeIdsByEntityType', [typename], entity.EntityType().Game)
componentOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentsOfType', entityId, typeIdsList)
return componentOutcome.IsSuccess()
def change_entity_status(desiredStatusProperty, entityId):
editor.EditorEntityAPIBus(bus.Event, 'SetStartStatus', entityId, desiredStatusProperty)
status = editor.EditorEntityInfoRequestBus(bus.Event, 'GetStartStatus', entityId)
if (status == desiredStatusProperty):
print('[PASS] successfully changed status: ' + str(desiredStatusProperty))
else:
print('[FAIL] unable to set status: ' + str(desiredStatusProperty))
return
# Test creating layer entity
layerId = layers.EditorLayerComponent_CreateLayerEntityFromName('testLayer')
if(layerId):
print('[PASS] layer has been created')
else:
print('[FAIL] layer was not created')
azlmbr.framework.Terminate(1)
# Test getting and setting the name property for the layer
name = editor.EditorEntityInfoRequestBus(bus.Event, 'GetName', layerId);
if(name):
print('[PASS] Get name request succeeded')
else:
print('[FAIL] Get name request failed')
editor.EditorEntityAPIBus(bus.Event, 'SetName', layerId, "test_layer")
name = editor.EditorEntityInfoRequestBus(bus.Event, 'GetName', layerId)
if(name == 'test_layer'):
print('[PASS] Layer name changed')
else:
print('[FAIL] Did not complete layer name change')
# Test Getting and Setting the color for the layer
color = math.Color_ConstructFromValues(255,255,0,1)
oldColor = layers.EditorLayerComponentRequestBus(bus.Event, 'GetColorPropertyValue', layerId)
layers.EditorLayerComponentRequestBus(bus.Event, 'SetLayerColor', layerId, color)
newColor = layers.EditorLayerComponentRequestBus(bus.Event, 'GetColorPropertyValue', layerId)
if(oldColor and newColor):
if (oldColor != newColor):
print('[PASS] Layer color changed')
else:
print('[FAIL] Was unable to change layer color property')
else:
print('[FAIL] Was unable to get color property of layer')
# Test creating child entity in layer entity
layerChild = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', layerId)
if (layerChild):
print('[PASS] layer child entity has been created')
else:
print('[FAIL] layer child entity was not created')
queryParent = editor.EditorEntityInfoRequestBus(bus.Event, 'GetParent', layerChild)
if(queryParent.ToString() == layerId.ToString()):
print('[PASS] Query parent returned layer ID')
else:
print('[FAIL] layer is not parented to entity')
# Test getting child entity IDs
childList = editor.EditorEntityInfoRequestBus(bus.Event, 'GetChildren', layerId)
if(childList):
print('[PASS] EditorEntityInfoRequestBus GetChildren return list of decendants')
else:
print('[FAILL] EditorEntityInfoRequestBus GetChildren did not return list of decendants')
# Test adding component to layer entity
result = add_component('Comment', layerId)
if(result == True):
print('[PASS] comment component has been added')
else:
print('[FAIL] comment component was not added to layer')
# Test locking layer entity. Note: layers themselves are not locked or unlocked;
# setting lock on a layer effectively sets the lock for all child entities
queryLock = editor.EditorEntityInfoRequestBus(bus.Event, 'IsLocked', layerId)
if(queryLock == False):
print('[INFO] layer is not locked')
editor.EditorEntityAPIBus(bus.Event, 'SetLockState', layerId, True)
queryLock = editor.EditorEntityInfoRequestBus(bus.Event, 'IsLocked', layerId)
if(queryLock == True):
print('[PASS] layer has been locked')
else:
print('[FAIL] layer was no locked')
# Test layer visibility. Note: layers themselves are not visible or invisible;
# setting visibility on a layer effectively sets visibility for all child entities
queryVisibility = editor.EditorEntityInfoRequestBus(bus.Event, 'IsVisible', layerChild)
if(queryVisibility == True):
print('[INFO] layer children are visible')
layers.EditorLayerComponentRequestBus(azlmbr.bus.Event, 'SetVisibility', layerId, False)
queryVisibility = editor.EditorEntityInfoRequestBus(bus.Event, 'IsVisible', layerChild)
if(queryVisibility == False):
print('[PASS] layer children are hidden')
else:
print('[FAIL] unable to set layer visibility to hidden')
# Test layer status property
# start active
change_entity_status(azlmbr.globals.property.EditorEntityStartStatus_StartActive, layerId)
# start inactive
change_entity_status(azlmbr.globals.property.EditorEntityStartStatus_StartInactive, layerId)
# editor only
change_entity_status(azlmbr.globals.property.EditorEntityStartStatus_EditorOnly, layerId)
# Test deleting layer
editor.ToolsApplicationRequestBus(bus.Broadcast, 'DeleteEntityAndAllDescendants', layerId)
entityName = editor.EditorEntityInfoRequestBus(bus.Event, 'GetName', layerId)
if (entityName):
print('[FAIL] Layer entity found after delete request')
else:
print('[PASS] Layer entity not found after delete request')
# Close editor without saving
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'ExitNoPrompt')
@@ -0,0 +1,4 @@
All the Hydra tests use the AutomatedTesting project.
The all use the hydra_utils.py file to launch the auto Editor tests.
The <Test_Type>_test.py file is run using LYTT
The <Test_Type>_test_case.py file is executed in the Editor