Landscape Canvas automation optimizations with TestAutomationBase/parallelization (#3255)

* Convert Landscape Canvas main tests to use TestAutomationBase
* Updating main Landscape Canvas test suite to batch run tests
* Converting initial batch of Landscape Canvas periodic tests to use TestAutomationBase/test parallelization
* Renaming Editor Script to fit naming convention
* Updating explicit waits to wait_for_condition checks
* Additional test conversions
* Renaming Editor Script to fit naming convention
* Additional test parallelizations
* Additional test conversions
* Renaming optimized test file
* Adding Main test file for non-optimized tests

Signed-off-by: jckand-amzn <jckand@amazon.com>
This commit is contained in:
jckand-amzn
2021-08-19 17:07:06 -05:00
committed by GitHub
parent e889bba963
commit 1a430755df
32 changed files with 2972 additions and 2645 deletions
@@ -130,8 +130,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
NAME AutomatedTesting::LandscapeCanvasTests_Main
TEST_SERIAL
TEST_SUITE main
PATH ${CMAKE_CURRENT_LIST_DIR}/landscape_canvas
PYTEST_MARKS "not SUITE_sandbox and not SUITE_periodic and not SUITE_benchmark"
PATH ${CMAKE_CURRENT_LIST_DIR}/landscape_canvas/test_LandscapeCanvas_Main.py
RUNTIME_DEPENDENCIES
AZ::AssetProcessor
Legacy::Editor
@@ -144,8 +143,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
NAME AutomatedTesting::LandscapeCanvasTests_Periodic
TEST_SERIAL
TEST_SUITE periodic
PATH ${CMAKE_CURRENT_LIST_DIR}/landscape_canvas
PYTEST_MARKS "SUITE_periodic"
PATH ${CMAKE_CURRENT_LIST_DIR}/landscape_canvas/test_LandscapeCanvas_Periodic.py
RUNTIME_DEPENDENCIES
AZ::AssetProcessor
Legacy::Editor
@@ -5,144 +5,147 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import os
import sys
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.editor.graph as graph
import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.legacy.general as general
import azlmbr.math as math
import azlmbr.paths
class Tests:
lc_tool_opened = (
"Landscape Canvas tool opened",
"Failed to open Landscape Canvas tool"
)
new_graph_created = (
"Successfully created new graph",
"Failed to create new graph"
)
graph_registered = (
"Graph registered with Landscape Canvas",
"Failed to register graph"
)
dependencies_added = (
"Node created new Entity with all required components",
"Failed to create node with all required components"
)
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.editor_test_helper import EditorTestHelper
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
newEntityId = None
class TestAreaNodeComponentDependency(EditorTestHelper):
def __init__(self):
EditorTestHelper.__init__(self, log_prefix="AreaNodeComponentDependency", args=["level"])
def AreaNodes_DependentComponentsAdded():
"""
Summary:
This test verifies that the Landscape Canvas nodes can be added to a graph, and correctly create entities with
proper dependent components.
def run_test(self):
"""
Summary:
This test verifies that the Landscape Canvas nodes can be added to a graph, and correctly create entities with
proper dependent components.
Expected Behavior:
All expected component dependencies are met when adding an area node to a graph.
Expected Behavior:
All expected component dependencies are met when adding an area node to a graph.
Test Steps:
1) Open a simple level
2) Open Landscape Canvas and create a new graph
3) Drag each of the area nodes to the graph area, and ensure the proper dependent components are added
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create a new graph
3) Drag each of the area nodes to the graph area, and ensure the proper dependent components are added
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
:return: None
"""
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.editor.graph as graph
import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.legacy.general as general
import azlmbr.math as math
def onEntityCreated(parameters):
global newEntityId
newEntityId = parameters[0]
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
# Create a new empty level
self.test_success = self.create_level(
self.args["level"],
heightmap_resolution=128,
heightmap_meters_per_pixel=1,
terrain_texture_resolution=128,
use_terrain=False,
)
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
# Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas')
self.test_success = self.test_success and general.is_pane_visible('Landscape Canvas')
if general.is_pane_visible('Landscape Canvas'):
self.log('Landscape Canvas pane is open')
def onEntityCreated(parameters):
global newEntityId
newEntityId = parameters[0]
# Create a new graph in Landscape Canvas
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
self.test_success = self.test_success and newGraphId
if newGraphId:
self.log("New graph created")
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
# Make sure the graph we created is in Landscape Canvas
success = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
self.test_success = self.test_success and success
if success:
self.log("Graph registered with Landscape Canvas")
# Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas')
Report.critical_result(Tests.lc_tool_opened, general.is_pane_visible('Landscape Canvas'))
# Listen for entity creation notifications so we can check if the entity created
# from adding these vegetation area nodes has the main target Vegetation Layer Component
# as well as automatically adding all required dependency components
handler = editor.EditorEntityContextNotificationBusHandler()
handler.connect()
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
# Create a new graph in Landscape Canvas
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
Report.critical_result(Tests.new_graph_created, newGraphId is not None)
# Vegetation area mapping with the key being the node name and the value is the
# expected Components that should be added to the Entity created for the node
areas = {
'SpawnerAreaNode': [
'Vegetation Layer Spawner',
'Vegetation Asset List',
'Vegetation Reference Shape'
],
'MeshBlockerAreaNode': [
'Vegetation Layer Blocker (Mesh)',
'Mesh'
],
'BlockerAreaNode': [
'Vegetation Layer Blocker',
'Vegetation Reference Shape'
]
}
# Make sure the graph we created is in Landscape Canvas
graph_registered = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
Report.result(Tests.graph_registered, graph_registered)
# Retrieve a mapping of the TypeIds for all the components
# we will be checking for
componentNames = []
for name in areas:
componentNames.extend(areas[name])
componentTypeIds = hydra.get_component_type_id_map(componentNames)
# Listen for entity creation notifications so we can check if the entity created
# from adding these vegetation area nodes has the main target Vegetation Layer Component
# as well as automatically adding all required dependency components
handler = editor.EditorEntityContextNotificationBusHandler()
handler.connect()
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
# Create nodes for the vegetation areas that have additional required dependencies and check if
# the Entity created by adding the node has the appropriate component and required
# additional components added automatically to it
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
x = 10.0
y = 10.0
for nodeName in areas:
nodePosition = math.Vector2(x, y)
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
newGraph, nodeName)
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
# Vegetation area mapping with the key being the node name and the value is the
# expected Components that should be added to the Entity created for the node
areas = {
'SpawnerAreaNode': [
'Vegetation Layer Spawner',
'Vegetation Asset List',
'Vegetation Reference Shape'
],
'MeshBlockerAreaNode': [
'Vegetation Layer Blocker (Mesh)',
'Mesh'
],
'BlockerAreaNode': [
'Vegetation Layer Blocker',
'Vegetation Reference Shape'
]
}
components = areas[nodeName]
success = False
for component in components:
componentTypeId = componentTypeIds[component]
success = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId,
componentTypeId)
if not success:
break
self.test_success = self.test_success and success
if success:
self.log("{node} created new Entity with all required components".format(node=nodeName))
# Retrieve a mapping of the TypeIds for all the components
# we will be checking for
componentNames = []
for name in areas:
componentNames.extend(areas[name])
componentTypeIds = hydra.get_component_type_id_map(componentNames)
x += 40.0
y += 40.0
# Create nodes for the vegetation areas that have additional required dependencies and check if
# the Entity created by adding the node has the appropriate component and required
# additional components added automatically to it
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
x = 10.0
y = 10.0
for nodeName in areas:
nodePosition = math.Vector2(x, y)
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
newGraph, nodeName)
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
# Stop listening for entity creation notifications
handler.disconnect()
components = areas[nodeName]
success = False
for component in components:
componentTypeId = componentTypeIds[component]
success = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId,
componentTypeId)
if not success:
break
Report.info(nodeName)
Report.result(Tests.dependencies_added, success)
x += 40.0
y += 40.0
# Stop listening for entity creation notifications
handler.disconnect()
test = TestAreaNodeComponentDependency()
test.run()
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(AreaNodes_DependentComponentsAdded)
@@ -5,125 +5,129 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import os
import sys
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.editor.graph as graph
import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.legacy.general as general
import azlmbr.math as math
import azlmbr.paths
class Tests:
lc_tool_opened = (
"Landscape Canvas tool opened",
"Failed to open Landscape Canvas tool"
)
new_graph_created = (
"Successfully created new graph",
"Failed to create new graph"
)
graph_registered = (
"Graph registered with Landscape Canvas",
"Failed to register graph"
)
component_added = (
"New entity created with the expected component",
"Expected component was not found on entity"
)
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.editor_test_helper import EditorTestHelper
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
newEntityId = None
class TestGradientNodeEntityCreate(EditorTestHelper):
def __init__(self):
EditorTestHelper.__init__(self, log_prefix="AreaNodeEntityCreate", args=["level"])
def AreaNodes_EntityCreatedOnNodeAdd():
"""
Summary:
This test verifies that the Landscape Canvas nodes can be added to a graph, and correctly create entities.
def run_test(self):
"""
Summary:
This test verifies that the Landscape Canvas nodes can be added to a graph, and correctly create entities.
Expected Behavior:
New entities are created when dragging area nodes to graph area.
Expected Behavior:
New entities are created when dragging area nodes to graph area.
Test Steps:
1) Open a simple level
2) Open Landscape Canvas and create a new graph
3) Drag each of the area nodes to the graph area, and ensure a new entity is created
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create a new graph
3) Drag each of the area nodes to the graph area, and ensure a new entity is created
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
:return: None
"""
def onEntityCreated(parameters):
global newEntityId
newEntityId = parameters[0]
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.editor.graph as graph
import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.legacy.general as general
import azlmbr.math as math
# Create a new empty level
self.test_success = self.create_level(
self.args["level"],
heightmap_resolution=128,
heightmap_meters_per_pixel=1,
terrain_texture_resolution=128,
use_terrain=False,
)
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
# Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas')
self.test_success = self.test_success and general.is_pane_visible('Landscape Canvas')
if general.is_pane_visible('Landscape Canvas'):
self.log('Landscape Canvas pane is open')
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
# Create a new graph in Landscape Canvas
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
self.test_success = self.test_success and newGraphId
if newGraphId:
self.log("New graph created")
def onEntityCreated(parameters):
global newEntityId
newEntityId = parameters[0]
# Make sure the graph we created is in Landscape Canvas
success = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
self.test_success = self.test_success and success
if success:
self.log("Graph registered with Landscape Canvas")
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
# Listen for entity creation notifications so we can check if the entity created
# from adding vegetation area nodes has the appropriate Vegetation Layer Component
handler = editor.EditorEntityContextNotificationBusHandler()
handler.connect()
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
# Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas')
Report.critical_result(Tests.lc_tool_opened, general.is_pane_visible('Landscape Canvas'))
# Vegetation Area mapping with the key being the node name and the value is the
# expected Component that should be added to the Entity created for the node
areas = {
'AreaBlenderNode': 'Vegetation Layer Blender',
'BlockerAreaNode': 'Vegetation Layer Blocker',
'MeshBlockerAreaNode': 'Vegetation Layer Blocker (Mesh)',
'SpawnerAreaNode': 'Vegetation Layer Spawner'
}
# Create a new graph in Landscape Canvas
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
Report.critical_result(Tests.new_graph_created, newGraphId is not None)
# Retrieve a mapping of the TypeIds for all the components
# we will be checking for
componentNames = []
for name in areas:
componentNames.append(areas[name])
componentTypeIds = hydra.get_component_type_id_map(componentNames)
# Make sure the graph we created is in Landscape Canvas
graph_registered = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
Report.result(Tests.graph_registered, graph_registered)
# Create nodes for all the vegetation areas we support and check if the Entity created by
# adding the node has the appropriate Component added automatically to it
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
x = 10.0
y = 10.0
for nodeName in areas:
nodePosition = math.Vector2(x, y)
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph, nodeName)
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
# Listen for entity creation notifications so we can check if the entity created
# from adding vegetation area nodes has the appropriate Vegetation Layer Component
handler = editor.EditorEntityContextNotificationBusHandler()
handler.connect()
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
areaComponent = areas[nodeName]
componentTypeId = componentTypeIds[areaComponent]
hasComponent = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId, componentTypeId)
self.test_success = self.test_success and hasComponent
if hasComponent:
self.log("{node} created new Entity with {component} Component".format(node=nodeName, component=areaComponent))
# Vegetation Area mapping with the key being the node name and the value is the
# expected Component that should be added to the Entity created for the node
areas = {
'AreaBlenderNode': 'Vegetation Layer Blender',
'BlockerAreaNode': 'Vegetation Layer Blocker',
'MeshBlockerAreaNode': 'Vegetation Layer Blocker (Mesh)',
'SpawnerAreaNode': 'Vegetation Layer Spawner'
}
x += 40.0
y += 40.0
# Retrieve a mapping of the TypeIds for all the components
# we will be checking for
componentNames = []
for name in areas:
componentNames.append(areas[name])
componentTypeIds = hydra.get_component_type_id_map(componentNames)
# Stop listening for entity creation notifications
handler.disconnect()
# Create nodes for all the vegetation areas we support and check if the Entity created by
# adding the node has the appropriate Component added automatically to it
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
x = 10.0
y = 10.0
for nodeName in areas:
nodePosition = math.Vector2(x, y)
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph, nodeName)
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
areaComponent = areas[nodeName]
componentTypeId = componentTypeIds[areaComponent]
hasComponent = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId, componentTypeId)
Report.info(f"Node: {nodeName} | Component: {areaComponent}")
Report.result(Tests.component_added, hasComponent)
x += 40.0
y += 40.0
# Stop listening for entity creation notifications
handler.disconnect()
test = TestGradientNodeEntityCreate()
test.run()
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(AreaNodes_EntityCreatedOnNodeAdd)
@@ -5,123 +5,128 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import os
import sys
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.editor.graph as graph
import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.legacy.general as general
import azlmbr.math as math
import azlmbr.paths
class Tests:
lc_tool_opened = (
"Landscape Canvas tool opened",
"Failed to open Landscape Canvas tool"
)
new_graph_created = (
"Successfully created new graph",
"Failed to create new graph"
)
graph_registered = (
"Graph registered with Landscape Canvas",
"Failed to register graph"
)
entity_deleted = (
"Entity was deleted when node was removed",
"Entity was not deleted as expected when node was removed"
)
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
from editor_python_test_tools.editor_test_helper import EditorTestHelper
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
createdEntityId = None
deletedEntityId = None
class TestAreaNodeEntityDelete(EditorTestHelper):
def AreaNodes_EntityRemovedOnNodeDelete():
"""
Summary:
This test verifies that the Landscape Canvas node deletion properly cleans up entities in the Editor.
def __init__(self):
EditorTestHelper.__init__(self, log_prefix="AreaNodeEntityDelete", args=["level"])
Expected Behavior:
Entities are removed when area nodes are deleted from a graph.
def run_test(self):
"""
Summary:
This test verifies that the Landscape Canvas node deletion properly cleans up entities in the Editor.
Test Steps:
1) Open a simple level
2) Open Landscape Canvas and create a new graph
3) Drag each of the area nodes to the graph area, and ensure a new entity is created
4) Delete the nodes, and ensure the newly created entities are removed
Expected Behavior:
Entities are removed when area nodes are deleted from a graph.
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create a new graph
3) Drag each of the area nodes to the graph area, and ensure a new entity is created
4) Delete the nodes, and ensure the newly created entities are removed
:return: None
"""
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.editor.graph as graph
import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.legacy.general as general
import azlmbr.math as math
import azlmbr.paths
:return: None
"""
def onEntityCreated(parameters):
global createdEntityId
createdEntityId = parameters[0]
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
def onEntityDeleted(parameters):
global deletedEntityId
deletedEntityId = parameters[0]
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
# Create a new empty level
self.test_success = self.create_level(
self.args["level"],
heightmap_resolution=128,
heightmap_meters_per_pixel=1,
terrain_texture_resolution=128,
use_terrain=False,
)
def onEntityCreated(parameters):
global createdEntityId
createdEntityId = parameters[0]
# Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas')
self.test_success = self.test_success and general.is_pane_visible('Landscape Canvas')
if general.is_pane_visible('Landscape Canvas'):
self.log('Landscape Canvas pane is open')
def onEntityDeleted(parameters):
global deletedEntityId
deletedEntityId = parameters[0]
# Create a new graph in Landscape Canvas
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
self.test_success = self.test_success and newGraphId
if newGraphId:
self.log("New graph created")
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
# Make sure the graph we created is in Landscape Canvas
success = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
self.test_success = self.test_success and success
if success:
self.log("Graph registered with Landscape Canvas")
# Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas')
Report.critical_result(Tests.lc_tool_opened, general.is_pane_visible('Landscape Canvas'))
# Listen for entity creation notifications so we can check if the entity created
# from adding gradient nodes has the appropriate Gradient Component
handler = editor.EditorEntityContextNotificationBusHandler()
handler.connect()
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
handler.add_callback('OnEditorEntityDeleted', onEntityDeleted)
# Create a new graph in Landscape Canvas
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
Report.critical_result(Tests.new_graph_created, newGraphId is not None)
# Vegetation Area mapping with the key being the node name and the value is the
# expected Component that should be added to the Entity created for the node
areas = [
'AreaBlenderNode',
'BlockerAreaNode',
'MeshBlockerAreaNode',
'SpawnerAreaNode',
]
# Make sure the graph we created is in Landscape Canvas
graph_registered = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
Report.result(Tests.graph_registered, graph_registered)
# Create nodes for all the gradients we support and check if the Entity created by
# adding the node has the appropriate Component added automatically to it
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
x = 10.0
y = 10.0
for nodeName in areas:
nodePosition = math.Vector2(x, y)
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph, nodeName)
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
# Listen for entity creation notifications so we can check if the entity created
# from adding gradient nodes has the appropriate Gradient Component
handler = editor.EditorEntityContextNotificationBusHandler()
handler.connect()
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
handler.add_callback('OnEditorEntityDeleted', onEntityDeleted)
removed = graph.GraphControllerRequestBus(bus.Event, 'RemoveNode', newGraphId, node)
# Vegetation Area mapping with the key being the node name and the value is the
# expected Component that should be added to the Entity created for the node
areas = [
'AreaBlenderNode',
'BlockerAreaNode',
'MeshBlockerAreaNode',
'SpawnerAreaNode',
]
# Verify that the created Entity for this node matches the Entity that gets
# deleted when the node is removed
self.test_success = self.test_success and removed and createdEntityId.invoke("Equal", deletedEntityId)
if removed and createdEntityId.invoke("Equal", deletedEntityId):
self.log("{node} corresponding Entity was deleted when node is removed".format(node=nodeName))
# Create nodes for all the gradients we support and check if the Entity created by
# adding the node has the appropriate Component added automatically to it
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
x = 10.0
y = 10.0
for nodeName in areas:
nodePosition = math.Vector2(x, y)
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph,
nodeName)
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
# Stop listening for entity creation notifications
handler.disconnect()
removed = graph.GraphControllerRequestBus(bus.Event, 'RemoveNode', newGraphId, node)
# Verify that the created Entity for this node matches the Entity that gets
# deleted when the node is removed
Report.info(f"Node: {nodeName}")
Report.result(Tests.entity_deleted, removed and createdEntityId.invoke("Equal", deletedEntityId))
# Stop listening for entity creation notifications
handler.disconnect()
test = TestAreaNodeEntityDelete()
test.run()
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(AreaNodes_EntityRemovedOnNodeDelete)
@@ -5,197 +5,209 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import os
import sys
import azlmbr.asset as asset
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.entity as entity
import azlmbr.legacy.general as general
import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.math as math
import azlmbr.slice as slice
import azlmbr.paths
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.editor_test_helper import EditorTestHelper
class Tests:
slice_instantiated = (
"Slice instantiated successfully",
"Failed to instantiate slice"
)
lc_entity_found = (
"LandscapeCanvas entity found",
"Failed to find LandscapeCanvas entity"
)
spawner_entity_found = (
"BushSpawner entity found",
"Failed to find BushSpawner entity"
)
dist_filter_component_found = (
"Vegetation Distribution Filter component on BushSpawner entity found",
"Failed to find Distribution Filter component on BushSpawner entity"
)
existing_graph_opened = (
"Opened existing graph from slice",
"Failed to open existing graph"
)
dist_filter_node_found = (
"Vegetation Distribution Filter node found on graph",
"Failed to find Distribution Filter node on graph"
)
alt_filter_component_found = (
"Vegetation Altitude Filter component on BushSpawner entity found",
"Failed to find Altitude Filter component on BushSpawner entity"
)
alt_filter_node_found = (
"Vegetation Altitude Filter node found on graph",
"Failed to find Altitude Filter node on graph"
)
dist_filter_component_removed = (
"Vegetation Distribution Filter component removed from BushSpawner entity",
"Failed to remove Distribution Filter component from BushSpawner entity"
)
dist_filter_node_removed = (
"Vegetation Distribution Filter node removed from graph",
"Failed to remove Distribution Filter node from graph"
)
child_entity_added = (
"New entity successfully added as a child of the BushSpawner entity",
"New entity added with an unexpected parent"
)
box_shape_component_found = (
"Box Shape component on Box entity found",
"Failed to find Box Shape component on Box entity"
)
box_shape_node_found = (
"Box Shape node found on graph",
"Failed to find Box Shape node on graph"
)
class TestComponentUpdatesUpdateGraph(EditorTestHelper):
def __init__(self):
EditorTestHelper.__init__(self, log_prefix="ComponentUpdatesUpdateGraph", args=["level"])
def ComponentUpdates_UpdateGraph():
"""
Summary:
This test verifies that the Landscape Canvas graphs update properly when components are added/removed outside of
Landscape Canvas.
def run_test(self):
"""
Summary:
This test verifies that the Landscape Canvas graphs update properly when components are added/removed outside of
Landscape Canvas.
Expected Behavior:
Graphs properly reflect component changes made to entities outside of Landscape Canvas.
Expected Behavior:
Graphs properly reflect component changes made to entities outside of Landscape Canvas.
Test Steps:
1. Open Level
2. Find LandscapeCanvas named entity
3. Ensure Vegetation Distribution Component is present on the BushSpawner entity
4. Open graph and ensure Distribution Filter wrapped node is present
5. Delete the Vegetation Distribution Filter component from the BushSpawner entity via Entity Inspector
6. Ensure the Vegetation Distribution Filter component was deleted from the BushSpawner entity and node is
no longer present in the graph
7. Add Vegetation Altitude Filter to the BushSpawner entity through Entity Inspector
8. Ensure Altitude Filter was added to the BushSpawner node in the open graph
9. Add a new entity with unique name as a child of the Landscape Canvas entity
10. Add a Box Shape component to the new child entity
11. Ensure Box Shape node is present on the open graph
Test Steps:
1. Open Level
2. Find LandscapeCanvas named entity
3. Ensure Vegetation Distribution Component is present on the BushSpawner entity
4. Open graph and ensure Distribution Filter wrapped node is present
5. Delete the Vegetation Distribution Filter component from the BushSpawner entity via Entity Inspector
6. Ensure the Vegetation Distribution Filter component was deleted from the BushSpawner entity and node is
no longer present in the graph
7. Add Vegetation Altitude Filter to the BushSpawner entity through Entity Inspector
8. Ensure Altitude Filter was added to the BushSpawner node in the open graph
9. Add a new entity with unique name as a child of the Landscape Canvas entity
10. Add a Box Shape component to the new child entity
11. Ensure Box Shape node is present on the open graph
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
:return: None
"""
import os
# Create a new empty level and instantiate LC_BushFlowerBlender.slice
self.test_success = self.create_level(
self.args["level"],
heightmap_resolution=128,
heightmap_meters_per_pixel=1,
terrain_texture_resolution=128,
use_terrain=False,
)
transform = math.Transform_CreateIdentity()
position = math.Vector3(64.0, 64.0, 32.0)
transform.invoke('SetPosition', position)
test_slice_path = os.path.join("Slices", "LC_BushFlowerBlender.slice")
test_slice_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", test_slice_path, math.Uuid(),
False)
test_slice = slice.SliceRequestBus(bus.Broadcast, 'InstantiateSliceFromAssetId', test_slice_id, transform)
self.test_success = self.test_success and test_slice.IsValid()
if test_slice.IsValid():
self.log("Slice spawned!")
import azlmbr.asset as asset
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.entity as entity
import azlmbr.legacy.general as general
import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.math as math
import azlmbr.slice as slice
# Find root entity in the loaded level
search_filter = entity.SearchFilter()
search_filter.names = ["LandscapeCanvas"]
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
# Allow a few seconds for matching entity to be found
self.wait_for_condition(lambda: len(entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)) > 0, 5.0)
lc_matching_entities = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)
slice_root_id = lc_matching_entities[0] #Entity with Landscape Canvas component
self.test_success = self.test_success and slice_root_id.IsValid()
if slice_root_id.IsValid():
self.log("LandscapeCanvas entity found")
# Open a simple level and instantiate LC_BushFlowerBlender.slice
helper.init_idle()
helper.open_level("Physics", "Base")
transform = math.Transform_CreateIdentity()
position = math.Vector3(64.0, 64.0, 32.0)
transform.invoke('SetPosition', position)
test_slice_path = os.path.join("Slices", "LC_BushFlowerBlender.slice")
test_slice_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", test_slice_path, math.Uuid(),
False)
test_slice = slice.SliceRequestBus(bus.Broadcast, 'InstantiateSliceFromAssetId', test_slice_id, transform)
Report.critical_result(Tests.slice_instantiated, test_slice.IsValid())
# Find the BushSpawner entity
search_filter.names = ["BushSpawner"]
spawner_matching_entities = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)
spawner_id = spawner_matching_entities[0] #Entity with Vegetation Layer Spawner component
self.test_success = self.test_success and spawner_id.IsValid()
if spawner_id.IsValid():
self.log("BushSpawner entity found")
# Find root entity in the loaded level
search_filter = entity.SearchFilter()
search_filter.names = ["LandscapeCanvas"]
# Get needed component type ids
distribution_filter_type_id = hydra.get_component_type_id("Vegetation Distribution Filter")
altitude_filter_type_id = hydra.get_component_type_id("Vegetation Altitude Filter")
box_shape_type_id = hydra.get_component_type_id("Box Shape")
# Allow a few seconds for matching entity to be found
helper.wait_for_condition(lambda: len(entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)) > 0, 5.0)
lc_matching_entities = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)
slice_root_id = lc_matching_entities[0] #Entity with Landscape Canvas component
Report.critical_result(Tests.lc_entity_found, slice_root_id.IsValid())
# Verify the BushSpawner entity has a Distribution Filter
has_distribution_filter = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', spawner_id,
distribution_filter_type_id)
self.test_success = self.test_success and has_distribution_filter
if has_distribution_filter:
self.log("Vegetation Distribution Filter on BushSpawner entity found")
# Find the BushSpawner entity
search_filter.names = ["BushSpawner"]
spawner_matching_entities = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)
spawner_id = spawner_matching_entities[0] #Entity with Vegetation Layer Spawner component
Report.critical_result(Tests.spawner_entity_found, spawner_id.IsValid())
# Open Landscape Canvas and the existing graph
general.open_pane('Landscape Canvas')
open_graph = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'OnGraphEntity', slice_root_id)
self.test_success = self.test_success and open_graph.IsValid()
if open_graph.IsValid():
self.log("Graph opened")
# Get needed component type ids
distribution_filter_type_id = hydra.get_component_type_id("Vegetation Distribution Filter")
altitude_filter_type_id = hydra.get_component_type_id("Vegetation Altitude Filter")
box_shape_type_id = hydra.get_component_type_id("Box Shape")
# Verify that Distribution Filter node is present on the graph
spawner_distribution_filter_component = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', spawner_id,
distribution_filter_type_id)
spawner_distribution_filter_component_id = spawner_distribution_filter_component.GetValue()
distribution_filter_node = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast,
'GetNodeMatchingEntityComponentInGraph',
open_graph,
spawner_distribution_filter_component_id)
self.test_success = self.test_success and distribution_filter_node is not None
if distribution_filter_node is not None:
self.log("Distribution Filter node found on graph")
else:
self.log("Distribution Filter node not found on graph")
# Verify the BushSpawner entity has a Distribution Filter
has_distribution_filter = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', spawner_id,
distribution_filter_type_id)
Report.critical_result(Tests.dist_filter_component_found, has_distribution_filter)
# Add a Vegetation Altitude Filter component to the BushSpawner entity, and verify the node is added to the graph
spawner_altitude_filter_component = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', spawner_id,
altitude_filter_type_id)
spawner_altitude_filter_component_id = spawner_altitude_filter_component.GetValue()
editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentOfType', spawner_id, altitude_filter_type_id)
has_altitude_filter = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', spawner_id,
altitude_filter_type_id)
altitude_filter_node = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'GetNodeMatchingEntityComponentInGraph',
open_graph, spawner_altitude_filter_component_id)
self.test_success = self.test_success and has_altitude_filter and altitude_filter_node is not None
if has_altitude_filter:
self.log("Vegetation Altitude Filter on BushSpawner entity found")
# Open Landscape Canvas and the existing graph
general.open_pane('Landscape Canvas')
open_graph = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'OnGraphEntity', slice_root_id)
Report.critical_result(Tests.existing_graph_opened, open_graph.IsValid())
if altitude_filter_node is not None:
self.log("Altitude Filter node found on graph")
else:
self.log("Altitude Filter node not found on graph")
# Verify that Distribution Filter node is present on the graph
spawner_distribution_filter_component = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', spawner_id,
distribution_filter_type_id)
spawner_distribution_filter_component_id = spawner_distribution_filter_component.GetValue()
distribution_filter_node = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast,
'GetNodeMatchingEntityComponentInGraph',
open_graph,
spawner_distribution_filter_component_id)
Report.critical_result(Tests.dist_filter_node_found, distribution_filter_node is not None)
# Remove the Distribution Filter
editor.EditorComponentAPIBus(bus.Broadcast, 'RemoveComponents', [spawner_distribution_filter_component_id])
general.idle_wait(1.0)
# Add a Vegetation Altitude Filter component to the BushSpawner entity, and verify the node is added to the graph
spawner_altitude_filter_component = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', spawner_id,
altitude_filter_type_id)
spawner_altitude_filter_component_id = spawner_altitude_filter_component.GetValue()
editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentOfType', spawner_id, altitude_filter_type_id)
has_altitude_filter = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', spawner_id,
altitude_filter_type_id)
altitude_filter_node = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'GetNodeMatchingEntityComponentInGraph',
open_graph, spawner_altitude_filter_component_id)
Report.result(Tests.dist_filter_component_found, has_altitude_filter)
Report.result(Tests.dist_filter_node_found, altitude_filter_node is not None)
# Verify the Distribution Filter was successfully removed from entity and the node was likewise removed
has_distribution_filter = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', spawner_id,
distribution_filter_type_id)
self.test_success = self.test_success and not has_distribution_filter
if not has_distribution_filter:
self.log("Vegetation Distribution Filter removed from BushSpawner entity")
# Remove the Distribution Filter
editor.EditorComponentAPIBus(bus.Broadcast, 'RemoveComponents', [spawner_distribution_filter_component_id])
general.idle_wait(1.0)
distribution_filter_node = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast,
'GetAllNodesMatchingEntityComponent',
spawner_distribution_filter_component_id)
self.test_success = self.test_success and not distribution_filter_node
if distribution_filter_node:
self.log("Distribution Filter node is still present on the graph")
else:
self.log("Distribution Filter node was removed from the graph")
# Verify the Distribution Filter was successfully removed from entity and the node was likewise removed
has_distribution_filter = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', spawner_id,
distribution_filter_type_id)
Report.result(Tests.dist_filter_component_removed, not has_distribution_filter)
# Add a new child entity of BushSpawner entity
box_id = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', spawner_id)
if editor.EditorEntityInfoRequestBus(bus.Event, 'GetParent', box_id) == spawner_id:
self.log("New entity successfully added as a child of the BushSpawner entity")
else:
self.log("New entity added with an unexpected parent")
distribution_filter_node = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast,
'GetAllNodesMatchingEntityComponent',
spawner_distribution_filter_component_id)
Report.result(Tests.dist_filter_node_removed, not distribution_filter_node)
# Add a Box Shape component to the new entity and verify it was properly added
editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentOfType', box_id, box_shape_type_id)
has_box_shape = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', box_id,
box_shape_type_id)
self.test_success = self.test_success and has_box_shape
if has_box_shape:
self.log("Box Shape on Box entity found")
# Add a new child entity of BushSpawner entity
box_id = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', spawner_id)
Report.result(Tests.child_entity_added, editor.EditorEntityInfoRequestBus(bus.Event, 'GetParent', box_id) ==
spawner_id)
# Verify the Box Shape node appear on the graph
box_shape_component = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', box_id,
box_shape_type_id)
# Add a Box Shape component to the new entity and verify it was properly added
editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentOfType', box_id, box_shape_type_id)
has_box_shape = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', box_id,
box_shape_type_id)
Report.result(Tests.box_shape_component_found, has_box_shape)
box_shape_component_id = box_shape_component.GetValue()
box_shape_node = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'GetAllNodesMatchingEntityComponent',
box_shape_component_id)
self.test_success = self.test_success and box_shape_node is not None
if box_shape_node is not None:
self.log("Box Shape node found on graph")
else:
self.log("Box Shape node not found on graph")
# Verify the Box Shape node appears on the graph
box_shape_component = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', box_id,
box_shape_type_id)
box_shape_component_id = box_shape_component.GetValue()
box_shape_node = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'GetAllNodesMatchingEntityComponent',
box_shape_component_id)
Report.result(Tests.box_shape_node_found, box_shape_node is not None)
test = TestComponentUpdatesUpdateGraph()
test.run()
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(ComponentUpdates_UpdateGraph)
@@ -0,0 +1,80 @@
"""
Copyright (c) Contributors to the Open 3D Engine Project.
For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
class Tests:
lc_component_added = (
"Landscape Canvas component successfully added to entity",
"Failed to add Landscape Canvas component to entity"
)
lc_component_removed = (
"Landscape Canvas component successfully removed from entity",
"Failed to remove Landscape Canvas component from entity"
)
def Component_AddedRemoved():
"""
Summary:
This test verifies that the Landscape Canvas component can be added to/removed from an entity.
Expected Behavior:
Closing a tabbed graph only closes the appropriate graph.
Test Steps:
1) Open a simple level
2) Create a new entity
3) Add a Landscape Canvas component to the entity
4) Remove the Landscape Canvas component from the entity
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.entity as entity
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
# Create an Entity at the root of the level
newEntityId = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', entity.EntityId())
# Find the component TypeId for our Landscape Canvas component
landscape_canvas_type_id = hydra.get_component_type_id("Landscape Canvas")
# Add the Landscape Canvas Component to our Entity
componentOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentsOfType', newEntityId, [landscape_canvas_type_id])
components = componentOutcome.GetValue()
landscapeCanvasComponent = components[0]
# Validate the Landscape Canvas Component exists
hasComponent = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId, landscape_canvas_type_id)
Report.result(Tests.lc_component_added, hasComponent)
# Remove the Landscape Canvas Component
editor.EditorComponentAPIBus(bus.Broadcast, 'RemoveComponents', [landscapeCanvasComponent])
# Validate the Landscape Canvas Component is no longer on our Entity
hasComponent = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId, landscape_canvas_type_id)
Report.result(Tests.lc_component_removed, not hasComponent)
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(Component_AddedRemoved)
@@ -1,106 +0,0 @@
"""
Copyright (c) Contributors to the Open 3D Engine Project.
For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import os
import sys
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.editor.graph as graph
import azlmbr.legacy.general as general
import azlmbr.paths
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.editor_test_helper import EditorTestHelper
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
new_root_entity_id = None
class TestCreateNewGraph(EditorTestHelper):
def __init__(self):
EditorTestHelper.__init__(self, log_prefix="CreateNewGraph", args=["level"])
def on_entity_created(self, parameters):
global new_root_entity_id
new_root_entity_id = parameters[0]
print("New root entity created")
def run_test(self):
"""
Summary:
This test verifies that new graphs can be created in Landscape Canvas.
Expected Behavior:
New graphs can be created, and proper entity is created to hold graph data with a Landscape Canvas component.
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create a new graph
3) Ensures the root entity created contains a Landscape Canvas component
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
self.test_success = self.create_level(
self.args["level"],
heightmap_resolution=128,
heightmap_meters_per_pixel=1,
terrain_texture_resolution=128,
use_terrain=False,
)
# Open Landscape Canvas tool and verify
general.open_pane("Landscape Canvas")
self.test_success = self.test_success and general.is_pane_visible("Landscape Canvas")
if general.is_pane_visible("Landscape Canvas"):
self.log("Landscape Canvas pane is open")
# Listen for entity creation notifications so we can check if the entity created
# with the new graph has our Landscape Canvas component automatically added
handler = editor.EditorEntityContextNotificationBusHandler()
handler.connect()
handler.add_callback("OnEditorEntityCreated", self.on_entity_created)
# Create a new graph in Landscape Canvas
newGraphId = graph.AssetEditorRequestBus(bus.Event, "CreateNewGraph", editorId)
self.test_success = self.test_success and newGraphId
if newGraphId:
self.log("New graph created")
# Make sure the graph we created is in Landscape Canvas
success = graph.AssetEditorRequestBus(bus.Event, "ContainsGraph", editorId, newGraphId)
self.test_success = self.test_success and success
if success:
self.log("Graph registered with Landscape Canvas")
# Check if the entity created when we create a new graph has the
# Landscape Canvas component already added to it
landscape_canvas_type_id = hydra.get_component_type_id("Landscape Canvas")
success = editor.EditorComponentAPIBus(bus.Broadcast, "HasComponentOfType", new_root_entity_id,
landscape_canvas_type_id)
self.test_success = self.test_success and success
if success:
self.log("Root entity has Landscape Canvas component")
# Close Landscape Canvas tool and verify
general.close_pane("Landscape Canvas")
self.test_success = self.test_success and not general.is_pane_visible("Landscape Canvas")
if not general.is_pane_visible("Landscape Canvas"):
self.log("Landscape Canvas pane is closed")
# Stop listening for entity creation notifications
handler.disconnect()
test = TestCreateNewGraph()
test.run()
@@ -5,131 +5,132 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import os
import sys
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.editor.graph as graph
import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.legacy.general as general
import azlmbr.math as math
import azlmbr.paths
class Tests:
lc_tool_opened = (
"Landscape Canvas tool opened",
"Failed to open Landscape Canvas tool"
)
new_graph_created = (
"Successfully created new graph",
"Failed to create new graph"
)
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.editor_test_helper import EditorTestHelper
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
newEntityId = None
class TestDisabledNodeDuplication(EditorTestHelper):
def __init__(self):
EditorTestHelper.__init__(self, log_prefix="DisabledNodeDuplication", args=["level"])
def Edit_DisabledNodeDuplication():
"""
Summary:
This test verifies Editor stability after duplicating disabled Landscape Canvas nodes.
def run_test(self):
"""
Summary:
This test verifies Editor stability after duplicating disabled Landscape Canvas nodes.
Expected Behavior:
Editor remains stable and free of crashes.
Expected Behavior:
Editor remains stable and free of crashes.
Test Steps:
1) Open a simple level
2) Open Landscape Canvas and create a new graph
3) Create several new nodes, disable the nodes via disabling/deleting components, and duplicate the nodes
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create a new graph
3) Create several new nodes, disable the nodes via disabling/deleting components, and duplicate the nodes
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
:return: None
"""
def onEntityCreated(parameters):
global newEntityId
newEntityId = parameters[0]
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.editor.graph as graph
import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.legacy.general as general
import azlmbr.math as math
# Create a new empty level
self.test_success = self.create_level(
self.args["level"],
heightmap_resolution=128,
heightmap_meters_per_pixel=1,
terrain_texture_resolution=128,
use_terrain=False,
)
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
# Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas')
self.test_success = self.test_success and general.is_pane_visible('Landscape Canvas')
if general.is_pane_visible('Landscape Canvas'):
self.log('Landscape Canvas pane is open')
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
# Create a new graph in Landscape Canvas
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
self.test_success = self.test_success and newGraphId
if newGraphId:
self.log("New graph created")
def onEntityCreated(parameters):
global newEntityId
newEntityId = parameters[0]
# Listen for entity creation notifications so when we add a new node
# we can access the corresponding Entity that was created so that we
# can disable/remove components on that Entity
handler = editor.EditorEntityContextNotificationBusHandler()
handler.connect()
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
# Mapping of our Landscape Canvas nodes with corresponding dependent components
# that we can disable/remove to reproduce the crash
nodes = {
'SpawnerAreaNode': 'Vegetation Asset List',
'MeshBlockerAreaNode': 'Mesh',
'BlockerAreaNode': 'Vegetation Reference Shape',
'FastNoiseGradientNode': 'Gradient Transform Modifier',
'ImageGradientNode': 'Gradient Transform Modifier',
'PerlinNoiseGradientNode': 'Gradient Transform Modifier',
'RandomNoiseGradientNode': 'Gradient Transform Modifier'
}
# Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas')
Report.critical_result(Tests.lc_tool_opened, general.is_pane_visible('Landscape Canvas'))
# Retrieve a mapping of the TypeIds for all the components
# we will be checking for
componentNames = list(set(nodes.values())) # Convert to set then back to list to remove any duplicates
componentTypeIds = hydra.get_component_type_id_map(componentNames)
# Create a new graph in Landscape Canvas
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
Report.critical_result(Tests.new_graph_created, newGraphId is not None)
# Iterate through creating our nodes and then disabling/deleting required components
# and then duplicating the node to reproduce the crash
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
x = 10.0
y = 10.0
for nodeName in nodes:
nodePosition = math.Vector2(x, y)
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph, nodeName)
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
# Listen for entity creation notifications so when we add a new node
# we can access the corresponding Entity that was created so that we
# can disable/remove components on that Entity
handler = editor.EditorEntityContextNotificationBusHandler()
handler.connect()
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
dependentComponentName = nodes[nodeName]
componentTypeId = componentTypeIds[dependentComponentName]
componentOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', newEntityId, componentTypeId)
component = componentOutcome.GetValue()
# Mapping of our Landscape Canvas nodes with corresponding dependent components
# that we can disable/remove to reproduce the crash
nodes = {
'SpawnerAreaNode': 'Vegetation Asset List',
'MeshBlockerAreaNode': 'Mesh',
'BlockerAreaNode': 'Vegetation Reference Shape',
'FastNoiseGradientNode': 'Gradient Transform Modifier',
'ImageGradientNode': 'Gradient Transform Modifier',
'PerlinNoiseGradientNode': 'Gradient Transform Modifier',
'RandomNoiseGradientNode': 'Gradient Transform Modifier'
}
# First make sure we can duplicate a node with a dependent component that is disabled
editor.EditorComponentAPIBus(bus.Broadcast, 'DisableComponents', [component])
general.idle_wait(1.0)
graph.SceneRequestBus(bus.Event, 'DuplicateSelection', newGraphId) # This duplication would cause a crash without the fix
self.log("{node} duplicated with disabled component".format(node=nodeName))
# Retrieve a mapping of the TypeIds for all the components
# we will be checking for
componentNames = list(set(nodes.values())) # Convert to set then back to list to remove any duplicates
componentTypeIds = hydra.get_component_type_id_map(componentNames)
# Then, make sure we can duplicate the node with a dependent component that is deleted
editor.EditorComponentAPIBus(bus.Broadcast, 'RemoveComponents', [component])
general.idle_wait(1.0)
graph.SceneRequestBus(bus.Event, 'DuplicateSelection', newGraphId) # This duplication would cause a crash without the fix
self.log("{node} duplicated with deleted component".format(node=nodeName))
# Iterate through creating our nodes and then disabling/deleting required components
# and then duplicating the node to reproduce the crash
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
x = 10.0
y = 10.0
for nodeName in nodes:
nodePosition = math.Vector2(x, y)
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph, nodeName)
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
x += 40.0
y += 40.0
dependentComponentName = nodes[nodeName]
componentTypeId = componentTypeIds[dependentComponentName]
componentOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', newEntityId, componentTypeId)
component = componentOutcome.GetValue()
# Stop listening for entity creation notifications
handler.disconnect()
# First make sure we can duplicate a node with a dependent component that is disabled
editor.EditorComponentAPIBus(bus.Broadcast, 'DisableComponents', [component])
helper.wait_for_condition(lambda: not editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled',
[component]), 1.0)
graph.SceneRequestBus(bus.Event, 'DuplicateSelection', newGraphId) # This duplication would cause a crash without the fix
Report.info("{node} duplicated with disabled component".format(node=nodeName))
# Then, make sure we can duplicate the node with a dependent component that is deleted
editor.EditorComponentAPIBus(bus.Broadcast, 'RemoveComponents', [component])
helper.wait_for_condition(lambda: not editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType',
componentTypeIds[dependentComponentName]), 1.0)
graph.SceneRequestBus(bus.Event, 'DuplicateSelection', newGraphId) # This duplication would cause a crash without the fix
Report.info("{node} duplicated with deleted component".format(node=nodeName))
x += 40.0
y += 40.0
# Stop listening for entity creation notifications
handler.disconnect()
test = TestDisabledNodeDuplication()
test.run()
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(Edit_DisabledNodeDuplication)
@@ -5,133 +5,134 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import os
import sys
import azlmbr.asset as asset
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.entity as entity
import azlmbr.legacy.general as general
import azlmbr.editor.graph as graph
import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.math as math
import azlmbr.slice as slice
import azlmbr.paths
class Tests:
slice_spawned = (
"Slice instantiated successfully",
"Failed to instantiate slice"
)
lc_entity_found = (
"Landscape Canvas entity found",
"Failed to find Landscape Canvas entity"
)
spawner_entity_found = (
"Spawner entity found",
"Failed to find Spawner entity"
)
graph_opened = (
"Graph successfully opened",
"Graph failed to open"
)
spawner_node_found = (
"Vegetation Layer Spawner node found on graph",
"Failed to find Vegetation Layer Spawner node on graph"
)
spawner_node_removed = (
"Vegetation Layer Spawner node was successfully removed",
"Failed to remove Vegetation Layer Spawner node"
)
def Edit_UndoNodeDelete_SliceEntity():
"""
Summary:
This test verifies Editor stability after undoing the deletion of nodes on a slice entity.
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.editor_test_helper import EditorTestHelper
Expected Behavior:
Editor remains stable and free of crashes.
Test Steps:
1) Open a simple level
2) Instantiate a slice with a Landscape Canvas setup
3) Find a specific node on the graph, and delete it
4) Restore the node with Undo
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
import os
import azlmbr.asset as asset
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.entity as entity
import azlmbr.legacy.general as general
import azlmbr.editor.graph as graph
import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.math as math
import azlmbr.slice as slice
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
# Instantiate slice
transform = math.Transform_CreateIdentity()
position = math.Vector3(64.0, 64.0, 32.0)
transform.invoke('SetPosition', position)
test_slice_path = os.path.join("Slices", "LC_BushFlowerBlender.slice")
test_slice_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", test_slice_path, math.Uuid(),
False)
test_slice = slice.SliceRequestBus(bus.Broadcast, 'InstantiateSliceFromAssetId', test_slice_id, transform)
Report.result(Tests.slice_spawned, test_slice.IsValid())
# Find root entity in the loaded level
search_filter = entity.SearchFilter()
search_filter.names = ["LandscapeCanvas"]
# Allow a few seconds for matching entity to be found
helper.wait_for_condition(lambda: len(entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)) > 0, 5.0)
lc_matching_entities = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)
slice_root_id = lc_matching_entities[0] # Entity with Landscape Canvas component
Report.result(Tests.lc_entity_found, slice_root_id.IsValid())
# Find the BushSpawner entity
search_filter.names = ["BushSpawner"]
spawner_matching_entities = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)
spawner_id = spawner_matching_entities[0] # Entity with Vegetation Layer Spawner component
Report.result(Tests.spawner_entity_found, spawner_id.IsValid())
# Open Landscape Canvas and the existing graph
general.open_pane('Landscape Canvas')
open_graph = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'OnGraphEntity', slice_root_id)
Report.result(Tests.graph_opened, open_graph.IsValid())
# Get needed component type ids
layer_spawner_type_id = hydra.get_component_type_id("Vegetation Layer Spawner")
# Find the Vegetation Layer Spawner node on the BushSpawner entity
layer_spawner_component = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', spawner_id,
layer_spawner_type_id)
layer_spawner_component_component_id = layer_spawner_component.GetValue()
layer_spawner_node = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'GetAllNodesMatchingEntityComponent',
layer_spawner_component_component_id)
Report.result(Tests.spawner_node_found, layer_spawner_node is not None)
# Remove the Layer Spawner node
graph.GraphControllerRequestBus(bus.Event, "RemoveNode", open_graph, layer_spawner_node[0])
# Verify node was removed
layer_spawner_node = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'GetAllNodesMatchingEntityComponent',
layer_spawner_component_component_id)
Report.result(Tests.spawner_node_removed, not layer_spawner_node)
# Undo the Node deletion. This is required to be executed twice to hit the node removal.
general.undo()
general.undo()
# self.log a line to the Console to verify the Editor is still active
Report.info("Editor is still responsive")
class TestUndoNodeDeleteSlice(EditorTestHelper):
def __init__(self):
EditorTestHelper.__init__(self, log_prefix="UndoNodeDeleteSlice", args=["level"])
if __name__ == "__main__":
def run_test(self):
"""
Summary:
This test verifies Editor stability after undoing the deletion of nodes on a slice entity.
from editor_python_test_tools.utils import Report
Report.start_test(Edit_UndoNodeDelete_SliceEntity)
Expected Behavior:
Editor remains stable and free of crashes.
Test Steps:
1) Create a new level
2) Instantiate a slice with a Landscape Canvas setup
3) Find a specific node on the graph, and delete it
4) Restore the node with Undo
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
# Create a new empty level and instantiate LC_BushFlowerBlender.slice
self.test_success = self.create_level(
self.args["level"],
heightmap_resolution=128,
heightmap_meters_per_pixel=1,
terrain_texture_resolution=128,
use_terrain=False,
)
transform = math.Transform_CreateIdentity()
position = math.Vector3(64.0, 64.0, 32.0)
transform.invoke('SetPosition', position)
test_slice_path = os.path.join("Slices", "LC_BushFlowerBlender.slice")
test_slice_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", test_slice_path, math.Uuid(),
False)
test_slice = slice.SliceRequestBus(bus.Broadcast, 'InstantiateSliceFromAssetId', test_slice_id, transform)
self.test_success = self.test_success and test_slice.IsValid()
if test_slice.IsValid():
self.log("Slice spawned!")
# Find root entity in the loaded level
search_filter = entity.SearchFilter()
search_filter.names = ["LandscapeCanvas"]
# Allow a few seconds for matching entity to be found
self.wait_for_condition(lambda: len(entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)) > 0,
5.0)
lc_matching_entities = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)
slice_root_id = lc_matching_entities[0] # Entity with Landscape Canvas component
self.test_success = self.test_success and slice_root_id.IsValid()
if slice_root_id.IsValid():
self.log("LandscapeCanvas entity found")
# Find the BushSpawner entity
search_filter.names = ["BushSpawner"]
spawner_matching_entities = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)
spawner_id = spawner_matching_entities[0] # Entity with Vegetation Layer Spawner component
self.test_success = self.test_success and spawner_id.IsValid()
if spawner_id.IsValid():
self.log("BushSpawner entity found")
# Open Landscape Canvas and the existing graph
general.open_pane('Landscape Canvas')
open_graph = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'OnGraphEntity', slice_root_id)
self.test_success = self.test_success and open_graph.IsValid()
if open_graph.IsValid():
self.log("Graph opened")
# Get needed component type ids
layer_spawner_type_id = hydra.get_component_type_id("Vegetation Layer Spawner")
# Find the Vegetation Layer Spawner node on the BushSpawner entity
layer_spawner_component = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', spawner_id,
layer_spawner_type_id)
layer_spawner_component_component_id = layer_spawner_component.GetValue()
layer_spawner_node = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'GetAllNodesMatchingEntityComponent',
layer_spawner_component_component_id)
self.test_success = self.test_success and layer_spawner_node
if layer_spawner_node:
self.log("Vegetation Layer Spawner node found on graph")
else:
self.log("Vegetation Layer Spawner node not found")
# Remove the Layer Spawner node
graph.GraphControllerRequestBus(bus.Event, "RemoveNode", open_graph, layer_spawner_node[0])
# Verify node was removed
layer_spawner_node = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'GetAllNodesMatchingEntityComponent',
layer_spawner_component_component_id)
self.test_success = self.test_success and not layer_spawner_node
if not layer_spawner_node:
self.log("Vegetation Layer Spawner node was removed")
else:
self.log("Vegetation Layer Spawner node was not removed")
# Undo the Node deletion. This is required to be executed twice to hit the node removal.
general.undo()
general.undo()
# self.log a line to the Console to verify the Editor is still active
self.log("Editor is still responsive")
test = TestUndoNodeDeleteSlice()
test.run()
@@ -5,190 +5,205 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import os
import sys
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.editor.graph as graph
import azlmbr.entity as entity
import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.legacy.general as general
import azlmbr.math as math
import azlmbr.paths
class Tests:
lc_tool_opened = (
"Landscape Canvas tool opened",
"Failed to open Landscape Canvas tool"
)
new_graph_created = (
"Successfully created new graph",
"Failed to create new graph"
)
graph_registered = (
"Graph registered with Landscape Canvas",
"Failed to register graph"
)
preview_entity_set = (
"Perlin Noise Gradient component Preview Entity property set to Box Shape EntityId",
"Unexpected entity set in Perlin Noise Gradient Preview Entity property"
)
mixer_inbound_gradient_set_a = (
"Gradient Mixer component Inbound Gradient extendable property set to Perlin Noise Gradient EntityId",
"Unexpected entity set in Gradient Mixer's Inbound Gradient property"
)
mixer_inbound_gradient_set_b = (
"Gradient Mixer component Inbound Gradient extendable property set to FastNoise Gradient EntityId",
"Unexpected entity set in Gradient Mixer's Inbound Gradient property"
)
mixer_operation_a = (
"Layer 1 Operation is set to Initialize",
"Layer 1 Operation is not set to Initialize as expected"
)
mixer_operation_b = (
"Layer 2 Operation is set to Average",
"Layer 2 Operation is not set to Average as expected"
)
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.editor_test_helper import EditorTestHelper
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
newEntityId = None
class TestGradientMixerNodeConstruction(EditorTestHelper):
def __init__(self):
EditorTestHelper.__init__(self, log_prefix="GradientMixerNodeConstruction", args=["level"])
def GradientMixer_NodeConstruction():
"""
Summary:
This test verifies a Gradient Mixer vegetation setup can be constructed through Landscape Canvas.
def run_test(self):
"""
Summary:
This test verifies a Gradient Mixer vegetation setup can be constructed through Landscape Canvas.
Expected Behavior:
Entities contain all required components and component references after creating nodes and setting connections
on a Landscape Canvas graph.
Expected Behavior:
Entities contain all required components and component references after creating nodes and setting connections
on a Landscape Canvas graph.
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create a new graph
3) Add all necessary nodes to the graph and set connections to form a Gradient Mixer setup
4) Verify all components and component references were properly set during graph construction
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create a new graph
3) Add all necessary nodes to the graph and set connections to form a Gradient Mixer setup
4) Verify all components and component references were properly set during graph construction
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
:return: None
"""
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.editor.graph as graph
import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.legacy.general as general
import azlmbr.math as math
import azlmbr.paths
def onEntityCreated(parameters):
global newEntityId
newEntityId = parameters[0]
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
# Create a new empty level
self.test_success = self.create_level(
self.args["level"],
heightmap_resolution=1024,
heightmap_meters_per_pixel=1,
terrain_texture_resolution=4096,
use_terrain=False,
)
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
# Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas')
self.test_success = self.test_success and general.is_pane_visible('Landscape Canvas')
if general.is_pane_visible('Landscape Canvas'):
self.log('Landscape Canvas pane is open')
def onEntityCreated(parameters):
global newEntityId
newEntityId = parameters[0]
# Create a new graph in Landscape Canvas
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
self.test_success = self.test_success and newGraphId
if newGraphId:
self.log("New graph created")
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
# Make sure the graph we created is in Landscape Canvas
success = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
self.test_success = self.test_success and success
if success:
self.log("Graph registered with Landscape Canvas")
# Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas')
Report.critical_result(Tests.lc_tool_opened, general.is_pane_visible('Landscape Canvas'))
# Listen for entity creation notifications so we can verify the component EntityId
# references are set correctly when connecting slots on the nodes
handler = editor.EditorEntityContextNotificationBusHandler()
handler.connect()
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
# Create a new graph in Landscape Canvas
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
Report.critical_result(Tests.new_graph_created, newGraphId is not None)
positionX = 10.0
positionY = 10.0
offsetX = 340.0
offsetY = 100.0
# Make sure the graph we created is in Landscape Canvas
graph_registered = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
Report.result(Tests.graph_registered, graph_registered)
# Add a Box Shape node to the graph
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
boxShapeNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph,
'BoxShapeNode')
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, boxShapeNode, math.Vector2(positionX, positionY))
boxShapeEntityId = newEntityId
# Listen for entity creation notifications so we can verify the component EntityId
# references are set correctly when connecting slots on the nodes
handler = editor.EditorEntityContextNotificationBusHandler()
handler.connect()
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
positionX += offsetX
positionY += offsetY
positionX = 10.0
positionY = 10.0
offsetX = 340.0
offsetY = 100.0
# Add a Random Noise Gradient node to the graph
perlinNoiseNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph,
'PerlinNoiseGradientNode')
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, perlinNoiseNode, math.Vector2(positionX, positionY))
perlinNoiseEntityId = newEntityId
# Add a Box Shape node to the graph
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
boxShapeNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph,
'BoxShapeNode')
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, boxShapeNode, math.Vector2(positionX, positionY))
boxShapeEntityId = newEntityId
positionX += offsetX
positionY += offsetY
positionX += offsetX
positionY += offsetY
# Add a FastNoise Gradient node to the graph
fastNoiseNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph,
'FastNoiseGradientNode')
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, fastNoiseNode, math.Vector2(positionX, positionY))
fastNoiseEntityId = newEntityId
# Add a Random Noise Gradient node to the graph
perlinNoiseNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph,
'PerlinNoiseGradientNode')
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, perlinNoiseNode, math.Vector2(positionX, positionY))
perlinNoiseEntityId = newEntityId
positionX += offsetX
positionY += offsetY
positionX += offsetX
positionY += offsetY
# Add a Gradient Mixer node to the graph
gradientMixerNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph,
'GradientMixerNode')
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, gradientMixerNode, math.Vector2(positionX, positionY))
gradientMixerEntityId = newEntityId
# Add a FastNoise Gradient node to the graph
fastNoiseNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph,
'FastNoiseGradientNode')
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, fastNoiseNode, math.Vector2(positionX, positionY))
fastNoiseEntityId = newEntityId
boundsSlotId = graph.GraphModelSlotId('Bounds')
previewBoundsSlotId = graph.GraphModelSlotId('PreviewBounds')
inboundGradientSlotId = graph.GraphModelSlotId('InboundGradient')
outboundGradientSlotId = graph.GraphModelSlotId('OutboundGradient')
inboundGradientSlotId2 = graph.GraphControllerRequestBus(bus.Event, 'ExtendSlot', newGraphId, gradientMixerNode,
'InboundGradient')
positionX += offsetX
positionY += offsetY
# Connect slots on our nodes to construct a Gradient Mixer hierarchy
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, boxShapeNode, boundsSlotId,
perlinNoiseNode, previewBoundsSlotId)
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, boxShapeNode, boundsSlotId,
fastNoiseNode, previewBoundsSlotId)
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, boxShapeNode, boundsSlotId,
gradientMixerNode, previewBoundsSlotId)
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, perlinNoiseNode, outboundGradientSlotId,
gradientMixerNode, inboundGradientSlotId)
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, fastNoiseNode, outboundGradientSlotId,
gradientMixerNode, inboundGradientSlotId2)
# Add a Gradient Mixer node to the graph
gradientMixerNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph,
'GradientMixerNode')
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, gradientMixerNode, math.Vector2(positionX, positionY))
gradientMixerEntityId = newEntityId
# Delay to allow all the underlying component properties to be updated after the slot connections are made
general.idle_wait(1.0)
boundsSlotId = graph.GraphModelSlotId('Bounds')
previewBoundsSlotId = graph.GraphModelSlotId('PreviewBounds')
inboundGradientSlotId = graph.GraphModelSlotId('InboundGradient')
outboundGradientSlotId = graph.GraphModelSlotId('OutboundGradient')
inboundGradientSlotId2 = graph.GraphControllerRequestBus(bus.Event, 'ExtendSlot', newGraphId, gradientMixerNode,
'InboundGradient')
# Get component info
gradientMixerTypeId = hydra.get_component_type_id("Gradient Mixer")
perlinNoiseTypeId = hydra.get_component_type_id("Perlin Noise Gradient")
gradientMixerOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', gradientMixerEntityId,
gradientMixerTypeId)
gradientMixerComponent = gradientMixerOutcome.GetValue()
perlinNoiseOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', perlinNoiseEntityId,
perlinNoiseTypeId)
perlinNoiseComponent = perlinNoiseOutcome.GetValue()
# Connect slots on our nodes to construct a Gradient Mixer hierarchy
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, boxShapeNode, boundsSlotId,
perlinNoiseNode, previewBoundsSlotId)
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, boxShapeNode, boundsSlotId,
fastNoiseNode, previewBoundsSlotId)
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, boxShapeNode, boundsSlotId,
gradientMixerNode, previewBoundsSlotId)
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, perlinNoiseNode, outboundGradientSlotId,
gradientMixerNode, inboundGradientSlotId)
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, fastNoiseNode, outboundGradientSlotId,
gradientMixerNode, inboundGradientSlotId2)
# Verify the Preview EntityId property on our Perlin Noise Gradient component has been set to our Box Shape's EntityId
previewEntityId = hydra.get_component_property_value(perlinNoiseComponent, 'Preview Settings|Pin Preview to Shape')
self.test_success = self.test_success and previewEntityId and boxShapeEntityId.invoke("Equal", previewEntityId)
if previewEntityId and boxShapeEntityId.invoke("Equal", previewEntityId):
self.log("Perlin Noise Gradient component Preview Entity property set to Box Shape EntityId")
# Delay to allow all the underlying component properties to be updated after the slot connections are made
general.idle_wait(1.0)
# Verify the 1st Inbound Gradient EntityId property on our Gradient Mixer component has been set to our Perlin Noise
# Gradient's EntityId
inboundGradientEntityId = hydra.get_component_property_value(gradientMixerComponent,
'Configuration|Layers|[0]|Gradient|Gradient Entity Id')
self.test_success = self.test_success and inboundGradientEntityId and perlinNoiseEntityId.invoke("Equal", inboundGradientEntityId)
if inboundGradientEntityId and perlinNoiseEntityId.invoke("Equal", inboundGradientEntityId):
self.log("Gradient Mixer component Inbound Gradient extendable property set to Perlin Noise Gradient EntityId")
# Get component info
gradientMixerTypeId = hydra.get_component_type_id("Gradient Mixer")
perlinNoiseTypeId = hydra.get_component_type_id("Perlin Noise Gradient")
gradientMixerOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', gradientMixerEntityId,
gradientMixerTypeId)
gradientMixerComponent = gradientMixerOutcome.GetValue()
perlinNoiseOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', perlinNoiseEntityId,
perlinNoiseTypeId)
perlinNoiseComponent = perlinNoiseOutcome.GetValue()
# Verify the 2nd Inbound Gradient EntityId property on our Gradient Mixer component has been set to our FastNoise
# Gradient Modifier's EntityId
inboundGradientEntityId2 = hydra.get_component_property_value(gradientMixerComponent,
'Configuration|Layers|[1]|Gradient|Gradient Entity Id')
self.test_success = self.test_success and inboundGradientEntityId2 and fastNoiseEntityId.invoke("Equal", inboundGradientEntityId2)
if inboundGradientEntityId2 and fastNoiseEntityId.invoke("Equal", inboundGradientEntityId2):
self.log("Gradient Mixer component Inbound Gradient extendable property set to FastNoise Gradient EntityId")
# Verify the Preview EntityId property on our Perlin Noise Gradient component has been set to our Box Shape's EntityId
previewEntityId = hydra.get_component_property_value(perlinNoiseComponent, 'Preview Settings|Pin Preview to Shape')
Report.result(Tests.preview_entity_set, previewEntityId and boxShapeEntityId.invoke("Equal", previewEntityId))
# Verify that Gradient Mixer Layer Operations are properly set
hydra.get_component_property_value(gradientMixerComponent, 'Configuration|Layers|[0]|Operation')
hydra.get_component_property_value(gradientMixerComponent, 'Configuration|Layers|[1]|Operation')
# Verify the 1st Inbound Gradient EntityId property on our Gradient Mixer component has been set to our Perlin Noise
# Gradient's EntityId
inboundGradientEntityId = hydra.get_component_property_value(gradientMixerComponent,
'Configuration|Layers|[0]|Gradient|Gradient Entity Id')
Report.result(Tests.mixer_inbound_gradient_set_a, inboundGradientEntityId and perlinNoiseEntityId.invoke("Equal", inboundGradientEntityId))
# Stop listening for entity creation notifications
handler.disconnect()
# Verify the 2nd Inbound Gradient EntityId property on our Gradient Mixer component has been set to our FastNoise
# Gradient Modifier's EntityId
inboundGradientEntityId2 = hydra.get_component_property_value(gradientMixerComponent,
'Configuration|Layers|[1]|Gradient|Gradient Entity Id')
Report.result(Tests.mixer_inbound_gradient_set_b, inboundGradientEntityId2 and fastNoiseEntityId.invoke("Equal", inboundGradientEntityId2))
# Verify that Gradient Mixer Layer Operations are properly set
mixer_operation_a = hydra.get_component_property_value(gradientMixerComponent, 'Configuration|Layers|[0]|Operation')
mixer_operation_b = hydra.get_component_property_value(gradientMixerComponent, 'Configuration|Layers|[1]|Operation')
Report.result(Tests.mixer_operation_a, mixer_operation_a == 0)
Report.result(Tests.mixer_operation_b, mixer_operation_b == 6)
# Stop listening for entity creation notifications
handler.disconnect()
test = TestGradientMixerNodeConstruction()
test.run()
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(GradientMixer_NodeConstruction)
@@ -5,132 +5,134 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import os
import sys
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.editor.graph as graph
import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.legacy.general as general
import azlmbr.math as math
import azlmbr.paths
class Tests:
lc_tool_opened = (
"Landscape Canvas tool opened",
"Failed to open Landscape Canvas tool"
)
new_graph_created = (
"Successfully created new graph",
"Failed to create new graph"
)
graph_registered = (
"Graph registered with Landscape Canvas",
"Failed to register graph"
)
component_added = (
"New entity created with the expected component",
"Expected component was not found on entity"
)
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.editor_test_helper import EditorTestHelper
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
newEntityId = None
class TestGradientModifierNodeEntityCreate(EditorTestHelper):
def __init__(self):
EditorTestHelper.__init__(self, log_prefix="GradientModifierNodeEntityCreate", args=["level"])
def GradientModifierNodes_EntityCreatedOnNodeAdd():
"""
Summary:
This test verifies that the Landscape Canvas nodes can be added to a graph, and correctly create entities.
def run_test(self):
"""
Summary:
This test verifies that the Landscape Canvas nodes can be added to a graph, and correctly create entities.
Expected Behavior:
New entities are created when dragging Gradient Modifier nodes to graph area.
Expected Behavior:
New entities are created when dragging Gradient Modifier nodes to graph area.
Test Steps:
1) Open a simple level
2) Open Landscape Canvas and create a new graph
3) Drag each of the Gradient Modifier nodes to the graph area, and ensure a new entity is created
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create a new graph
3) Drag each of the Gradient Modifier nodes to the graph area, and ensure a new entity is created
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
:return: None
"""
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.editor.graph as graph
import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.legacy.general as general
import azlmbr.math as math
def onEntityCreated(parameters):
global newEntityId
newEntityId = parameters[0]
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
# Create a new empty level
self.test_success = self.create_level(
self.args["level"],
heightmap_resolution=128,
heightmap_meters_per_pixel=1,
terrain_texture_resolution=128,
use_terrain=False,
)
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
# Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas')
self.test_success = self.test_success and general.is_pane_visible('Landscape Canvas')
if general.is_pane_visible('Landscape Canvas'):
self.log('Landscape Canvas pane is open')
def onEntityCreated(parameters):
global newEntityId
newEntityId = parameters[0]
# Create a new graph in Landscape Canvas
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
self.test_success = self.test_success and newGraphId
if newGraphId:
self.log("New graph created")
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
# Make sure the graph we created is in Landscape Canvas
success = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
self.test_success = self.test_success and success
if success:
self.log("Graph registered with Landscape Canvas")
# Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas')
Report.critical_result(Tests.lc_tool_opened, general.is_pane_visible('Landscape Canvas'))
# Listen for entity creation notifications so we can check if the entity created
# from adding gradient modifier nodes has the appropriate Gradient Modifier Component
handler = editor.EditorEntityContextNotificationBusHandler()
handler.connect()
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
# Create a new graph in Landscape Canvas
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
Report.critical_result(Tests.new_graph_created, newGraphId is not None)
# Gradient modifier mapping with the key being the node name and the value is the
# expected Component that should be added to the Entity created for the node
gradientModifiers = {
'DitherGradientModifierNode': 'Dither Gradient Modifier',
'GradientMixerNode': 'Gradient Mixer',
'InvertGradientModifierNode': 'Invert Gradient Modifier',
'LevelsGradientModifierNode': 'Levels Gradient Modifier',
'PosterizeGradientModifierNode': 'Posterize Gradient Modifier',
'SmoothStepGradientModifierNode': 'Smooth-Step Gradient Modifier',
'ThresholdGradientModifierNode': 'Threshold Gradient Modifier'
}
# Make sure the graph we created is in Landscape Canvas
graph_registered = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
Report.result(Tests.graph_registered, graph_registered)
# Retrieve a mapping of the TypeIds for all the components
# we will be checking for
componentNames = []
for name in gradientModifiers:
componentNames.append(gradientModifiers[name])
componentTypeIds = hydra.get_component_type_id_map(componentNames)
# Listen for entity creation notifications so we can check if the entity created
# from adding gradient modifier nodes has the appropriate Gradient Modifier Component
handler = editor.EditorEntityContextNotificationBusHandler()
handler.connect()
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
# Create nodes for all the gradients modifiers we support and check if the Entity created by
# adding the node has the appropriate Component added automatically to it
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
x = 10.0
y = 10.0
for nodeName in gradientModifiers:
nodePosition = math.Vector2(x, y)
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
newGraph, nodeName)
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
# Gradient modifier mapping with the key being the node name and the value is the
# expected Component that should be added to the Entity created for the node
gradientModifiers = {
'DitherGradientModifierNode': 'Dither Gradient Modifier',
'GradientMixerNode': 'Gradient Mixer',
'InvertGradientModifierNode': 'Invert Gradient Modifier',
'LevelsGradientModifierNode': 'Levels Gradient Modifier',
'PosterizeGradientModifierNode': 'Posterize Gradient Modifier',
'SmoothStepGradientModifierNode': 'Smooth-Step Gradient Modifier',
'ThresholdGradientModifierNode': 'Threshold Gradient Modifier'
}
gradientComponent = gradientModifiers[nodeName]
componentTypeId = componentTypeIds[gradientComponent]
hasComponent = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId,
componentTypeId)
self.test_success = self.test_success and hasComponent
if hasComponent:
self.log("{node} created new Entity with {component} Component".format(node=nodeName,
component=gradientComponent))
# Retrieve a mapping of the TypeIds for all the components
# we will be checking for
componentNames = []
for name in gradientModifiers:
componentNames.append(gradientModifiers[name])
componentTypeIds = hydra.get_component_type_id_map(componentNames)
x += 40.0
y += 40.0
# Create nodes for all the gradients modifiers we support and check if the Entity created by
# adding the node has the appropriate Component added automatically to it
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
x = 10.0
y = 10.0
for nodeName in gradientModifiers:
nodePosition = math.Vector2(x, y)
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
newGraph, nodeName)
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
# Stop listening for entity creation notifications
handler.disconnect()
gradientComponent = gradientModifiers[nodeName]
componentTypeId = componentTypeIds[gradientComponent]
hasComponent = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId,
componentTypeId)
Report.info(f"Node: {nodeName} | Component: {gradientComponent}")
Report.result(Tests.component_added, hasComponent)
x += 40.0
y += 40.0
# Stop listening for entity creation notifications
handler.disconnect()
test = TestGradientModifierNodeEntityCreate()
test.run()
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(GradientModifierNodes_EntityCreatedOnNodeAdd)
@@ -5,126 +5,129 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import os
import sys
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.editor.graph as graph
import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.legacy.general as general
import azlmbr.math as math
import azlmbr.paths
class Tests:
lc_tool_opened = (
"Landscape Canvas tool opened",
"Failed to open Landscape Canvas tool"
)
new_graph_created = (
"Successfully created new graph",
"Failed to create new graph"
)
graph_registered = (
"Graph registered with Landscape Canvas",
"Failed to register graph"
)
entity_deleted = (
"Entity was deleted when node was removed",
"Entity was not deleted as expected when node was removed"
)
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
from editor_python_test_tools.editor_test_helper import EditorTestHelper
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
createdEntityId = None
deletedEntityId = None
class TestGradientModifierNodeEntityDelete(EditorTestHelper):
def GradientModifierNodes_EntityRemovedOnNodeDelete():
"""
Summary:
This test verifies that the Landscape Canvas node deletion properly cleans up entities in the Editor.
def __init__(self):
EditorTestHelper.__init__(self, log_prefix="GradientModifierNodeEntityDelete", args=["level"])
Expected Behavior:
Entities are removed when Gradient Modifier nodes are deleted from a graph.
def run_test(self):
"""
Summary:
This test verifies that the Landscape Canvas node deletion properly cleans up entities in the Editor.
Test Steps:
1) Open a simple level
2) Open Landscape Canvas and create a new graph
3) Drag each of the Gradient Modifier nodes to the graph area, and ensure a new entity is created
4) Delete the nodes, and ensure the newly created entities are removed
Expected Behavior:
Entities are removed when Gradient Modifier nodes are deleted from a graph.
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create a new graph
3) Drag each of the Gradient Modifier nodes to the graph area, and ensure a new entity is created
4) Delete the nodes, and ensure the newly created entities are removed
:return: None
"""
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.editor.graph as graph
import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.legacy.general as general
import azlmbr.math as math
:return: None
"""
def onEntityCreated(parameters):
global createdEntityId
createdEntityId = parameters[0]
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
def onEntityDeleted(parameters):
global deletedEntityId
deletedEntityId = parameters[0]
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
# Create a new empty level
self.test_success = self.create_level(
self.args["level"],
heightmap_resolution=128,
heightmap_meters_per_pixel=1,
terrain_texture_resolution=128,
use_terrain=False,
)
def onEntityCreated(parameters):
global createdEntityId
createdEntityId = parameters[0]
# Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas')
self.test_success = self.test_success and general.is_pane_visible('Landscape Canvas')
if general.is_pane_visible('Landscape Canvas'):
self.log('Landscape Canvas pane is open')
def onEntityDeleted(parameters):
global deletedEntityId
deletedEntityId = parameters[0]
# Create a new graph in Landscape Canvas
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
self.test_success = self.test_success and newGraphId
if newGraphId:
self.log("New graph created")
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
# Make sure the graph we created is in Landscape Canvas
success = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
self.test_success = self.test_success and success
if success:
self.log("Graph registered with Landscape Canvas")
# Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas')
Report.critical_result(Tests.lc_tool_opened, general.is_pane_visible('Landscape Canvas'))
# Listen for entity creation notifications so we can check if the entity created
# from adding gradient nodes has the appropriate Gradient Component
handler = editor.EditorEntityContextNotificationBusHandler()
handler.connect()
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
handler.add_callback('OnEditorEntityDeleted', onEntityDeleted)
# Create a new graph in Landscape Canvas
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
Report.critical_result(Tests.new_graph_created, newGraphId is not None)
# Vegetation Area mapping with the key being the node name and the value is the
# expected Component that should be added to the Entity created for the node
gradientModifiers = [
'DitherGradientModifierNode',
'GradientMixerNode',
'InvertGradientModifierNode',
'LevelsGradientModifierNode',
'PosterizeGradientModifierNode',
'SmoothStepGradientModifierNode',
'ThresholdGradientModifierNode'
]
# Make sure the graph we created is in Landscape Canvas
graph_registered = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
Report.result(Tests.graph_registered, graph_registered)
# Create nodes for all the gradients we support and check if the Entity created by
# adding the node has the appropriate Component added automatically to it
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
x = 10.0
y = 10.0
for nodeName in gradientModifiers:
nodePosition = math.Vector2(x, y)
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph, nodeName)
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
# Listen for entity creation notifications so we can check if the entity created
# from adding gradient nodes has the appropriate Gradient Component
handler = editor.EditorEntityContextNotificationBusHandler()
handler.connect()
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
handler.add_callback('OnEditorEntityDeleted', onEntityDeleted)
removed = graph.GraphControllerRequestBus(bus.Event, 'RemoveNode', newGraphId, node)
# Vegetation Area mapping with the key being the node name and the value is the
# expected Component that should be added to the Entity created for the node
gradientModifiers = [
'DitherGradientModifierNode',
'GradientMixerNode',
'InvertGradientModifierNode',
'LevelsGradientModifierNode',
'PosterizeGradientModifierNode',
'SmoothStepGradientModifierNode',
'ThresholdGradientModifierNode'
]
# Verify that the created Entity for this node matches the Entity that gets
# deleted when the node is removed
self.test_success = self.test_success and removed and createdEntityId.invoke("Equal", deletedEntityId)
if removed and createdEntityId.invoke("Equal", deletedEntityId):
self.log("{node} corresponding Entity was deleted when node is removed".format(node=nodeName))
# Create nodes for all the gradients we support and check if the Entity created by
# adding the node has the appropriate Component added automatically to it
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
x = 10.0
y = 10.0
for nodeName in gradientModifiers:
nodePosition = math.Vector2(x, y)
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph, nodeName)
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
# Stop listening for entity creation notifications
handler.disconnect()
removed = graph.GraphControllerRequestBus(bus.Event, 'RemoveNode', newGraphId, node)
# Verify that the created Entity for this node matches the Entity that gets
# deleted when the node is removed
Report.info(f"Node: {nodeName}")
Report.result(Tests.entity_deleted, removed and createdEntityId.invoke("Equal", deletedEntityId))
# Stop listening for entity creation notifications
handler.disconnect()
test = TestGradientModifierNodeEntityDelete()
test.run()
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(GradientModifierNodes_EntityRemovedOnNodeDelete)
@@ -5,141 +5,143 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import os
import sys
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.editor.graph as graph
import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.legacy.general as general
import azlmbr.math as math
import azlmbr.paths
class Tests:
lc_tool_opened = (
"Landscape Canvas tool opened",
"Failed to open Landscape Canvas tool"
)
new_graph_created = (
"Successfully created new graph",
"Failed to create new graph"
)
graph_registered = (
"Graph registered with Landscape Canvas",
"Failed to register graph"
)
dependencies_added = (
"Node created new Entity with all required components",
"Failed to create node with all required components"
)
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.editor_test_helper import EditorTestHelper
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
newEntityId = None
class TestGradientNodeComponentDependency(EditorTestHelper):
def __init__(self):
EditorTestHelper.__init__(self, log_prefix="GradientNodeComponentDependency", args=["level"])
def GradientNodes_DependentComponentsAdded():
"""
Summary:
This test verifies that the Landscape Canvas nodes can be added to a graph, and correctly create entities with
proper dependent components.
def run_test(self):
"""
Summary:
This test verifies that the Landscape Canvas nodes can be added to a graph, and correctly create entities with
proper dependent components.
Expected Behavior:
All expected component dependencies are met when adding a Gradient Modifier node to a graph.
Expected Behavior:
All expected component dependencies are met when adding a Gradient Modifier node to a graph.
Test Steps:
1) Open a simple level
2) Open Landscape Canvas and create a new graph
3) Drag each of the Gradient Modifier nodes to the graph area, and ensure the proper dependent components are
added
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create a new graph
3) Drag each of the Gradient Modifier nodes to the graph area, and ensure the proper dependent components are
added
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
:return: None
"""
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.editor.graph as graph
import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.legacy.general as general
import azlmbr.math as math
def onEntityCreated(parameters):
global newEntityId
newEntityId = parameters[0]
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
# Create a new empty level
self.test_success = self.create_level(
self.args["level"],
heightmap_resolution=1024,
heightmap_meters_per_pixel=1,
terrain_texture_resolution=4096,
use_terrain=False,
)
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
# Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas')
self.test_success = self.test_success and general.is_pane_visible('Landscape Canvas')
if general.is_pane_visible('Landscape Canvas'):
self.log('Landscape Canvas pane is open')
def onEntityCreated(parameters):
global newEntityId
newEntityId = parameters[0]
# Create a new graph in Landscape Canvas
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
self.test_success = self.test_success and newGraphId
if newGraphId:
self.log("New graph created")
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
# Make sure the graph we created is in Landscape Canvas
success = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
self.test_success = self.test_success and success
if success:
self.log("Graph registered with Landscape Canvas")
# Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas')
Report.critical_result(Tests.lc_tool_opened, general.is_pane_visible('Landscape Canvas'))
# Listen for entity creation notifications so we can check if the entity created
# from adding these gradients nodes has the main target Gradient Component
# as well as automatically adding all required dependency components
handler = editor.EditorEntityContextNotificationBusHandler()
handler.connect()
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
# Create a new graph in Landscape Canvas
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
Report.critical_result(Tests.new_graph_created, newGraphId is not None)
# Gradient mapping with the key being the node name and the value is the
# expected Component that should be added to the Entity created for the node
gradients = {
'FastNoiseGradientNode': 'FastNoise Gradient',
'ImageGradientNode': 'Image Gradient',
'PerlinNoiseGradientNode': 'Perlin Noise Gradient',
'RandomNoiseGradientNode': 'Random Noise Gradient'
}
# Make sure the graph we created is in Landscape Canvas
graph_registered = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
Report.result(Tests.graph_registered, graph_registered)
# Retrieve a mapping of the TypeIds for all the components
# we will be checking for
commonComponents = [
'Gradient Transform Modifier',
'Vegetation Reference Shape'
]
componentNames = []
for name in gradients:
componentNames.append(gradients[name])
componentNames.extend(commonComponents)
componentTypeIds = hydra.get_component_type_id_map(componentNames)
# Listen for entity creation notifications so we can check if the entity created
# from adding these gradients nodes has the main target Gradient Component
# as well as automatically adding all required dependency components
handler = editor.EditorEntityContextNotificationBusHandler()
handler.connect()
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
# Create nodes for the gradients that have additional required dependencies and check if
# the Entity created by adding the node has the appropriate Component and required
# Gradient Transform Modifier and Vegetation Reference Shape components added automatically to it
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
x = 10.0
y = 10.0
for nodeName in gradients:
nodePosition = math.Vector2(x, y)
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph, nodeName)
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
# Gradient mapping with the key being the node name and the value is the
# expected Component that should be added to the Entity created for the node
gradients = {
'FastNoiseGradientNode': 'FastNoise Gradient',
'ImageGradientNode': 'Image Gradient',
'PerlinNoiseGradientNode': 'Perlin Noise Gradient',
'RandomNoiseGradientNode': 'Random Noise Gradient'
}
gradientComponent = gradients[nodeName]
components = [gradientComponent] + commonComponents
success = False
for component in components:
componentTypeId = componentTypeIds[component]
success = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId, componentTypeId)
self.test_success = self.test_success and success
if not success:
break
# Retrieve a mapping of the TypeIds for all the components
# we will be checking for
commonComponents = [
'Gradient Transform Modifier',
'Vegetation Reference Shape'
]
componentNames = []
for name in gradients:
componentNames.append(gradients[name])
componentNames.extend(commonComponents)
componentTypeIds = hydra.get_component_type_id_map(componentNames)
if success:
self.log("{node} created new Entity with all required components".format(node=nodeName))
# Create nodes for the gradients that have additional required dependencies and check if
# the Entity created by adding the node has the appropriate Component and required
# Gradient Transform Modifier and Vegetation Reference Shape components added automatically to it
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
x = 10.0
y = 10.0
for nodeName in gradients:
nodePosition = math.Vector2(x, y)
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph, nodeName)
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
x += 40.0
y += 40.0
gradientComponent = gradients[nodeName]
components = [gradientComponent] + commonComponents
success = False
for component in components:
componentTypeId = componentTypeIds[component]
success = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId, componentTypeId)
if not success:
break
Report.info(nodeName)
Report.result(Tests.dependencies_added, success)
# Stop listening for entity creation notifications
handler.disconnect()
x += 40.0
y += 40.0
# Stop listening for entity creation notifications
handler.disconnect()
test = TestGradientNodeComponentDependency()
test.run()
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(GradientNodes_DependentComponentsAdded)
@@ -5,130 +5,134 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import os, sys
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.editor.graph as graph
import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.legacy.general as general
import azlmbr.math as math
import azlmbr.paths
class Tests:
lc_tool_opened = (
"Landscape Canvas tool opened",
"Failed to open Landscape Canvas tool"
)
new_graph_created = (
"Successfully created new graph",
"Failed to create new graph"
)
graph_registered = (
"Graph registered with Landscape Canvas",
"Failed to register graph"
)
component_added = (
"New entity created with the expected component",
"Expected component was not found on entity"
)
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.editor_test_helper import EditorTestHelper
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
newEntityId = None
class TestGradientNodeEntityCreate(EditorTestHelper):
def __init__(self):
EditorTestHelper.__init__(self, log_prefix="GradientNodeEntityCreate", args=["level"])
def GradientNodes_EntityCreatedOnNodeAdd():
"""
Summary:
This test verifies that the Landscape Canvas nodes can be added to a graph, and correctly create entities.
def run_test(self):
"""
Summary:
This test verifies that the Landscape Canvas nodes can be added to a graph, and correctly create entities.
Expected Behavior:
New entities are created when dragging Gradient nodes to graph area.
Expected Behavior:
New entities are created when dragging Gradient nodes to graph area.
Test Steps:
1) Open a simple level
2) Open Landscape Canvas and create a new graph
3) Drag each of the Gradient nodes to the graph area, and ensure a new entity is created
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create a new graph
3) Drag each of the Gradient nodes to the graph area, and ensure a new entity is created
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
:return: None
"""
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.editor.graph as graph
import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.legacy.general as general
import azlmbr.math as math
def onEntityCreated(parameters):
global newEntityId
newEntityId = parameters[0]
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
# Create a new empty level
self.test_success = self.create_level(
self.args["level"],
heightmap_resolution=1024,
heightmap_meters_per_pixel=1,
terrain_texture_resolution=4096,
use_terrain=False,
)
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
# Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas')
self.test_success = self.test_success and general.is_pane_visible('Landscape Canvas')
if general.is_pane_visible('Landscape Canvas'):
self.log('Landscape Canvas pane is open')
def onEntityCreated(parameters):
global newEntityId
newEntityId = parameters[0]
# Create a new graph in Landscape Canvas
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
self.test_success = self.test_success and newGraphId
if newGraphId:
self.log("New graph created")
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
# Make sure the graph we created is in Landscape Canvas
success = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
self.test_success = self.test_success and success
if success:
self.log("Graph registered with Landscape Canvas")
# Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas')
Report.critical_result(Tests.lc_tool_opened, general.is_pane_visible('Landscape Canvas'))
# Listen for entity creation notifications so we can check if the entity created
# from adding gradient nodes has the appropriate Gradient Component
handler = editor.EditorEntityContextNotificationBusHandler()
handler.connect()
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
# Create a new graph in Landscape Canvas
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
Report.critical_result(Tests.new_graph_created, newGraphId is not None)
# Gradient mapping with the key being the node name and the value is the
# expected Component that should be added to the Entity created for the node
gradients = {
'AltitudeGradientNode': 'Altitude Gradient',
'ConstantGradientNode': 'Constant Gradient',
'FastNoiseGradientNode': 'FastNoise Gradient',
'ImageGradientNode': 'Image Gradient',
'PerlinNoiseGradientNode': 'Perlin Noise Gradient',
'RandomNoiseGradientNode': 'Random Noise Gradient',
'ShapeAreaFalloffGradientNode': 'Shape Falloff Gradient',
'SlopeGradientNode': 'Slope Gradient',
'SurfaceMaskGradientNode': 'Surface Mask Gradient',
}
# Make sure the graph we created is in Landscape Canvas
graph_registered = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
Report.result(Tests.graph_registered, graph_registered)
# Retrieve a mapping of the TypeIds for all the components
# we will be checking for
componentNames = []
for name in gradients:
componentNames.append(gradients[name])
componentTypeIds = hydra.get_component_type_id_map(componentNames)
# Listen for entity creation notifications so we can check if the entity created
# from adding gradient nodes has the appropriate Gradient Component
handler = editor.EditorEntityContextNotificationBusHandler()
handler.connect()
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
# Create nodes for all the gradients we support and check if the Entity created by
# adding the node has the appropriate Component added automatically to it
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
x = 10.0
y = 10.0
for nodeName in gradients:
nodePosition = math.Vector2(x, y)
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph, nodeName)
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
# Gradient mapping with the key being the node name and the value is the
# expected Component that should be added to the Entity created for the node
gradients = {
'AltitudeGradientNode': 'Altitude Gradient',
'ConstantGradientNode': 'Constant Gradient',
'FastNoiseGradientNode': 'FastNoise Gradient',
'ImageGradientNode': 'Image Gradient',
'PerlinNoiseGradientNode': 'Perlin Noise Gradient',
'RandomNoiseGradientNode': 'Random Noise Gradient',
'ShapeAreaFalloffGradientNode': 'Shape Falloff Gradient',
'SlopeGradientNode': 'Slope Gradient',
'SurfaceMaskGradientNode': 'Surface Mask Gradient',
}
gradientComponent = gradients[nodeName]
componentTypeId = componentTypeIds[gradientComponent]
hasComponent = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId, componentTypeId)
self.test_success = self.test_success and hasComponent
if hasComponent:
self.log("{node} created new Entity with {component} Component".format(node=nodeName, component=gradientComponent))
# Retrieve a mapping of the TypeIds for all the components
# we will be checking for
componentNames = []
for name in gradients:
componentNames.append(gradients[name])
componentTypeIds = hydra.get_component_type_id_map(componentNames)
x += 40.0
y += 40.0
# Create nodes for all the gradients we support and check if the Entity created by
# adding the node has the appropriate Component added automatically to it
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
x = 10.0
y = 10.0
for nodeName in gradients:
nodePosition = math.Vector2(x, y)
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph, nodeName)
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
# Stop listening for entity creation notifications
handler.disconnect()
gradientComponent = gradients[nodeName]
componentTypeId = componentTypeIds[gradientComponent]
hasComponent = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId, componentTypeId)
Report.info(f"Node: {nodeName} | Component: {gradientComponent}")
Report.result(Tests.component_added, hasComponent)
x += 40.0
y += 40.0
# Stop listening for entity creation notifications
handler.disconnect()
test = TestGradientNodeEntityCreate()
test.run()
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(GradientNodes_EntityCreatedOnNodeAdd)
@@ -5,129 +5,131 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import os
import sys
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.editor.graph as graph
import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.legacy.general as general
import azlmbr.math as math
import azlmbr.paths
class Tests:
lc_tool_opened = (
"Landscape Canvas tool opened",
"Failed to open Landscape Canvas tool"
)
new_graph_created = (
"Successfully created new graph",
"Failed to create new graph"
)
graph_registered = (
"Graph registered with Landscape Canvas",
"Failed to register graph"
)
entity_deleted = (
"Entity was deleted when node was removed",
"Entity was not deleted as expected when node was removed"
)
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
from editor_python_test_tools.editor_test_helper import EditorTestHelper
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
createdEntityId = None
deletedEntityId = None
class TestGradientNodeEntityDelete(EditorTestHelper):
def GradientNodes_EntityRemovedOnNodeDelete():
"""
Summary:
This test verifies that the Landscape Canvas node deletion properly cleans up entities in the Editor.
def __init__(self):
EditorTestHelper.__init__(self, log_prefix="GradientNodeEntityDelete", args=["level"])
Expected Behavior:
Entities are removed when Gradient nodes are deleted from a graph.
def run_test(self):
"""
Summary:
This test verifies that the Landscape Canvas node deletion properly cleans up entities in the Editor.
Test Steps:
1) Open a simple level
2) Open Landscape Canvas and create a new graph
3) Drag each of the Gradient nodes to the graph area, and ensure a new entity is created
4) Delete the nodes, and ensure the newly created entities are removed
Expected Behavior:
Entities are removed when Gradient nodes are deleted from a graph.
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create a new graph
3) Drag each of the Gradient nodes to the graph area, and ensure a new entity is created
4) Delete the nodes, and ensure the newly created entities are removed
:return: None
"""
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.editor.graph as graph
import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.legacy.general as general
import azlmbr.math as math
:return: None
"""
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
def onEntityCreated(parameters):
global createdEntityId
createdEntityId = parameters[0]
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
def onEntityDeleted(parameters):
global deletedEntityId
deletedEntityId = parameters[0]
def onEntityCreated(parameters):
global createdEntityId
createdEntityId = parameters[0]
# Create a new empty level
self.test_success = self.create_level(
self.args["level"],
heightmap_resolution=1024,
heightmap_meters_per_pixel=1,
terrain_texture_resolution=4096,
use_terrain=False,
)
def onEntityDeleted(parameters):
global deletedEntityId
deletedEntityId = parameters[0]
# Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas')
self.test_success = self.test_success and general.is_pane_visible('Landscape Canvas')
if general.is_pane_visible('Landscape Canvas'):
self.log('Landscape Canvas pane is open')
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
# Create a new graph in Landscape Canvas
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
self.test_success = self.test_success and newGraphId
if newGraphId:
self.log("New graph created")
# Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas')
Report.critical_result(Tests.lc_tool_opened, general.is_pane_visible('Landscape Canvas'))
# Make sure the graph we created is in Landscape Canvas
success = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
self.test_success = self.test_success and success
if success:
self.log("Graph registered with Landscape Canvas")
# Create a new graph in Landscape Canvas
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
Report.critical_result(Tests.new_graph_created, newGraphId is not None)
# Listen for entity creation notifications so we can check if the entity created
# from adding gradient nodes has the appropriate Gradient Component
handler = editor.EditorEntityContextNotificationBusHandler()
handler.connect()
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
handler.add_callback('OnEditorEntityDeleted', onEntityDeleted)
# Make sure the graph we created is in Landscape Canvas
graph_registered = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
Report.result(Tests.graph_registered, graph_registered)
# Gradient mapping with the key being the node name and the value is the
# expected Component that should be added to the Entity created for the node
gradients = [
'AltitudeGradientNode',
'ConstantGradientNode',
'FastNoiseGradientNode',
'ImageGradientNode',
'PerlinNoiseGradientNode',
'RandomNoiseGradientNode',
'ShapeAreaFalloffGradientNode',
'SlopeGradientNode',
'SurfaceMaskGradientNode',
]
# Listen for entity creation notifications so we can check if the entity created
# from adding gradient nodes has the appropriate Gradient Component
handler = editor.EditorEntityContextNotificationBusHandler()
handler.connect()
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
handler.add_callback('OnEditorEntityDeleted', onEntityDeleted)
# Create nodes for all the gradients we support and check if the Entity created by
# adding the node has the appropriate Component added automatically to it
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
x = 10.0
y = 10.0
for nodeName in gradients:
nodePosition = math.Vector2(x, y)
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph, nodeName)
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
# Gradient mapping with the key being the node name and the value is the
# expected Component that should be added to the Entity created for the node
gradients = [
'AltitudeGradientNode',
'ConstantGradientNode',
'FastNoiseGradientNode',
'ImageGradientNode',
'PerlinNoiseGradientNode',
'RandomNoiseGradientNode',
'ShapeAreaFalloffGradientNode',
'SlopeGradientNode',
'SurfaceMaskGradientNode',
]
removed = graph.GraphControllerRequestBus(bus.Event, 'RemoveNode', newGraphId, node)
# Create nodes for all the gradients we support and check if the Entity created by
# adding the node has the appropriate Component added automatically to it
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
x = 10.0
y = 10.0
for nodeName in gradients:
nodePosition = math.Vector2(x, y)
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph, nodeName)
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
# Verify that the created Entity for this node matches the Entity that gets
# deleted when the node is removed
self.test_success = self.test_success and removed and createdEntityId.invoke("Equal", deletedEntityId)
if removed and createdEntityId.invoke("Equal", deletedEntityId):
self.log("{node} corresponding Entity was deleted when node is removed".format(node=nodeName))
removed = graph.GraphControllerRequestBus(bus.Event, 'RemoveNode', newGraphId, node)
# Stop listening for entity creation notifications
handler.disconnect()
# Verify that the created Entity for this node matches the Entity that gets
# deleted when the node is removed
Report.info(f"Node: {nodeName}")
Report.result(Tests.entity_deleted, removed and createdEntityId.invoke("Equal", deletedEntityId))
# Stop listening for entity creation notifications
handler.disconnect()
test = TestGradientNodeEntityDelete()
test.run()
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(GradientNodes_EntityRemovedOnNodeDelete)
@@ -5,100 +5,99 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import os
import sys
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.editor.graph as graph
import azlmbr.legacy.general as general
import azlmbr.paths
class Tests:
lc_tool_opened = (
"Landscape Canvas tool opened",
"Failed to open Landscape Canvas tool"
)
graph_registered = (
"Graph registered with Landscape Canvas",
"Failed to register graph"
)
graph_closed = (
"Graph closed on entity delete",
"Graph is still open after entity delete"
)
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
from editor_python_test_tools.editor_test_helper import EditorTestHelper
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
newRootEntityId = None
class TestGraphClosedOnEntityDelete(EditorTestHelper):
def GraphClosed_OnEntityDelete():
"""
Summary:
This test verifies that Landscape Canvas graphs are auto-closed when the corresponding entity is deleted.
def __init__(self):
EditorTestHelper.__init__(self, log_prefix="GraphClosedOnEntityDelete", args=["level"])
Expected Behavior:
When a Landscape Canvas root entity is deleted, the corresponding graph automatically closes.
def run_test(self):
"""
Summary:
This test verifies that Landscape Canvas graphs are auto-closed when the corresponding entity is deleted.
Test Steps:
1) Open a simple level
2) Open Landscape Canvas and create a new graph
3) Delete the automatically created entity
4) Verify the open graph is closed
Expected Behavior:
When a Landscape Canvas root entity is deleted, the corresponding graph automatically closes.
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create a new graph
3) Delete the automatically created entity
4) Verify the open graph is closed
:return: None
"""
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.editor.graph as graph
import azlmbr.legacy.general as general
:return: None
"""
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
def onEntityCreated(parameters):
global newRootEntityId
newRootEntityId = parameters[0]
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
# Create a new empty level
self.test_success = self.create_level(
self.args["level"],
heightmap_resolution=128,
heightmap_meters_per_pixel=1,
terrain_texture_resolution=128,
use_terrain=False,
)
def onEntityCreated(parameters):
global newRootEntityId
newRootEntityId = parameters[0]
# Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas')
self.test_success = self.test_success and general.is_pane_visible('Landscape Canvas')
if general.is_pane_visible('Landscape Canvas'):
self.log('Landscape Canvas pane is open')
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
# Listen for entity creation notifications so we can store the top-level Entity created
# when a new graph is created, and then delete it to test if the graph is closed
handler = editor.EditorEntityContextNotificationBusHandler()
handler.connect()
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
# Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas')
Report.critical_result(Tests.lc_tool_opened, general.is_pane_visible('Landscape Canvas'))
# Create a new graph in Landscape Canvas and verify
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
graphIsOpen = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
self.test_success = self.test_success and graphIsOpen
if graphIsOpen:
self.log("Graph registered with Landscape Canvas")
# Listen for entity creation notifications so we can store the top-level Entity created
# when a new graph is created, and then delete it to test if the graph is closed
handler = editor.EditorEntityContextNotificationBusHandler()
handler.connect()
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
# Delete the top-level Entity created by the new graph
editor.ToolsApplicationRequestBus(bus.Broadcast, 'DeleteEntityById', newRootEntityId)
# Create a new graph in Landscape Canvas and verify
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
graphIsOpen = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
Report.result(Tests.graph_registered, graphIsOpen)
# We need to delay here because the closing of the graph due to Entity deletion
# is actually queued in order to workaround an undo/redo issue
# Alternatively, we could add a notifications bus for AssetEditorRequests
# that could trigger when graphs are opened/closed and then do the check there
general.idle_enable(True)
general.idle_wait(1.0)
# Delete the top-level Entity created by the new graph
editor.ToolsApplicationRequestBus(bus.Broadcast, 'DeleteEntityById', newRootEntityId)
# Verify that the corresponding graph is no longer open
graphIsClosed = not graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
self.test_success = self.test_success and graphIsClosed
if graphIsClosed:
self.log("The graph is no longer open after deleting the Entity")
# We need to delay here because the closing of the graph due to Entity deletion
# is actually queued in order to workaround an undo/redo issue
# Alternatively, we could add a notifications bus for AssetEditorRequests
# that could trigger when graphs are opened/closed and then do the check there
general.idle_enable(True)
general.idle_wait(1.0)
# Stop listening for entity creation notifications
handler.disconnect()
# Verify that the corresponding graph is no longer open
graphIsClosed = not graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
Report.result(Tests.graph_closed, graphIsClosed)
# Stop listening for entity creation notifications
handler.disconnect()
test = TestGraphClosedOnEntityDelete()
test.run()
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(GraphClosed_OnEntityDelete)
@@ -5,82 +5,82 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import os
import sys
import azlmbr.bus as bus
import azlmbr.editor.graph as graph
import azlmbr.legacy.general as general
import azlmbr.paths
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
from editor_python_test_tools.editor_test_helper import EditorTestHelper
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
class Tests:
lc_tool_opened = (
"Landscape Canvas tool opened",
"Failed to open Landscape Canvas tool"
)
new_graph_created = (
"Successfully created new graph",
"Failed to create new graph"
)
graph_registered = (
"Graph registered with Landscape Canvas",
"Failed to register graph"
)
graph_closed = (
"Graph closed on level change",
"Graph is still open after level change"
)
class TestGraphClosedOnLevelChange(EditorTestHelper):
def GraphClosed_OnLevelChange():
"""
Summary:
This test verifies that Landscape Canvas graphs are auto-closed when the currently open level changes.
def __init__(self):
EditorTestHelper.__init__(self, log_prefix="GraphClosedOnLevelChange", args=["level"])
Expected Behavior:
When a new level is loaded in the Editor, open Landscape Canvas graphs are automatically closed.
def run_test(self):
"""
Summary:
This test verifies that Landscape Canvas graphs are auto-closed when the currently open level changes.
Test Steps:
1) Open a simple level
2) Open Landscape Canvas and create a new graph
3) Open a different level
4) Verify the open graph is closed
Expected Behavior:
When a new level is loaded in the Editor, open Landscape Canvas graphs are automatically closed.
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create a new graph
3) Open a different level
4) Verify the open graph is closed
:return: None
"""
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
import azlmbr.bus as bus
import azlmbr.editor.graph as graph
import azlmbr.legacy.general as general
:return: None
"""
# Create a new empty level
self.test_success = self.create_level(
self.args["level"],
heightmap_resolution=128,
heightmap_meters_per_pixel=1,
terrain_texture_resolution=128,
use_terrain=False,
)
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
# Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas')
self.test_success = self.test_success and general.is_pane_visible('Landscape Canvas')
if general.is_pane_visible('Landscape Canvas'):
self.log('Landscape Canvas pane is open')
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
# Create a new graph in Landscape Canvas
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
self.test_success = self.test_success and newGraphId
if newGraphId:
self.log("New graph created")
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
# Make sure the graph we created is in Landscape Canvas
graphIsOpen = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
self.test_success = self.test_success and graphIsOpen
if graphIsOpen:
self.log("Graph registered with Landscape Canvas")
# Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas')
Report.critical_result(Tests.lc_tool_opened, general.is_pane_visible('Landscape Canvas'))
# Open a different level, which should close any open Landscape Canvas graphs
general.open_level_no_prompt('WhiteBox/EmptyLevel')
# Create a new graph in Landscape Canvas
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
Report.critical_result(Tests.new_graph_created, newGraphId is not None)
# Make sure the graph we created is now closed
graphIsOpen = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
self.test_success = self.test_success and not graphIsOpen
if not graphIsOpen:
self.log("Graph is no longer open in Landscape Canvas")
# Make sure the graph we created is in Landscape Canvas
graph_registered = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
Report.result(Tests.graph_registered, graph_registered)
# Open a different level, which should close any open Landscape Canvas graphs
general.open_level_no_prompt('WhiteBox/EmptyLevel')
# Make sure the graph we created is now closed
graphIsOpen = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
Report.result(Tests.graph_closed, not graphIsOpen)
test = TestGraphClosedOnLevelChange()
test.run()
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(GraphClosed_OnLevelChange)
@@ -5,95 +5,93 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import os
import sys
import azlmbr.bus as bus
import azlmbr.editor.graph as graph
import azlmbr.legacy.general as general
import azlmbr.paths
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
from editor_python_test_tools.editor_test_helper import EditorTestHelper
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
class Tests:
lc_tool_opened = (
"Landscape Canvas tool opened",
"Failed to open Landscape Canvas tool"
)
new_graph_created = (
"Successfully created new graph",
"Failed to create new graph"
)
graph_open = (
"Graph is open in Landscape Canvas",
"Graph is not open in Landscape Canvas"
)
tabbed_graph_closed = (
"Tabbed graph closed independently",
"Closing tabbed graph resulted in unexpected graphs closing"
)
class TestGraphClosedTabbedGraph(EditorTestHelper):
def GraphClosed_TabbedGraphClosesIndependently():
"""
Summary:
This test verifies that Landscape Canvas tabbed graphs can be independently closed.
def __init__(self):
EditorTestHelper.__init__(self, log_prefix="GraphClosedTabbedGraph", args=["level"])
Expected Behavior:
Closing a tabbed graph only closes the appropriate graph.
def run_test(self):
"""
Summary:
This test verifies that Landscape Canvas tabbed graphs can be independently closed.
Test Steps:
1) Open a simple level
2) Open Landscape Canvas and create several new graphs
3) Close one of the open graphs
4) Ensure the graph properly closed, and other open graphs remain open
Expected Behavior:
Closing a tabbed graph only closes the appropriate graph.
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create several new graphs
3) Close one of the open graphs
4) Ensure the graph properly closed, and other open graphs remain open
:return: None
"""
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
import azlmbr.bus as bus
import azlmbr.editor.graph as graph
import azlmbr.legacy.general as general
:return: None
"""
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
# Create a new empty level
self.test_success = self.create_level(
self.args["level"],
heightmap_resolution=128,
heightmap_meters_per_pixel=1,
terrain_texture_resolution=128,
use_terrain=False,
)
editor_id = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
# Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas')
self.test_success = self.test_success and general.is_pane_visible('Landscape Canvas')
if general.is_pane_visible('Landscape Canvas'):
self.log('Landscape Canvas pane is open')
def create_new_graph():
new_graph_id = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editor_id)
return new_graph_id
# Create 3 new graphs in Landscape Canvas
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
self.test_success = self.test_success and newGraphId
if newGraphId:
self.log("New graph created")
def is_graph_open(graph_id):
graph_open = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editor_id, graph_id)
return graph_open
newGraphId2 = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
self.test_success = self.test_success and newGraphId2
if newGraphId2:
self.log("2nd new graph created")
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
newGraphId3 = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
self.test_success = self.test_success and newGraphId3
if newGraphId3:
self.log("3rd new graph created")
# Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas')
Report.critical_result(Tests.lc_tool_opened, general.is_pane_visible('Landscape Canvas'))
# Make sure the graphs we created are open in Landscape Canvas
success = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
success2 = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId2)
success3 = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId3)
self.test_success = self.test_success and success and success2 and success3
if success and success2 and success3:
self.log("Graphs registered with Landscape Canvas")
# Create 3 new graphs in Landscape Canvas and make sure the graphs we created are open in Landscape Canvas
graph1 = create_new_graph()
Report.result(Tests.new_graph_created, graph1 is not None)
Report.result(Tests.graph_open, is_graph_open(graph1))
# Close a single graph and verify it was properly closed and other graphs remain open
success4 = graph.AssetEditorRequestBus(bus.Event, 'CloseGraph', editorId, newGraphId2)
success = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
success2 = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId2)
success3 = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId3)
self.test_success = self.test_success and success and success3 and success4 and not success2
if success and success3 and success4 and not success2:
self.log("Graph 2 was successfully closed")
graph2 = create_new_graph()
Report.result(Tests.new_graph_created, graph2 is not None)
Report.result(Tests.graph_open, is_graph_open(graph2))
graph3 = create_new_graph()
Report.result(Tests.new_graph_created, graph3 is not None)
Report.result(Tests.graph_open, is_graph_open(graph3))
# Close a single graph and verify it was properly closed and other graphs remain open
graph.AssetEditorRequestBus(bus.Event, 'CloseGraph', editor_id, graph2)
Report.result(Tests.tabbed_graph_closed, not is_graph_open(graph2) and is_graph_open(graph1) and
is_graph_open(graph3))
test = TestGraphClosedTabbedGraph()
test.run()
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(GraphClosed_TabbedGraphClosesIndependently)
@@ -5,155 +5,151 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import os
import sys
import azlmbr.asset as asset
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.entity as entity
import azlmbr.legacy.general as general
import azlmbr.editor.graph as graph
import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.math as math
import azlmbr.slice as slice
import azlmbr.paths
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.editor_test_helper import EditorTestHelper
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
import automatedtesting_shared.landscape_canvas_utils as lc
class Tests:
slice_instantiated = (
"Slice instantiated successfully",
"Failed to instantiate slice"
)
existing_graph_opened = (
"Opened existing graph from slice",
"Failed to open existing graph"
)
node_removed = (
"Rotation Modifier node was removed",
"Failed to remove Rotation Modifier node"
)
component_removed = (
"Rotation Modifier component was removed from entity",
"Rotation Modifier component is still present on entity"
)
entity_deleted = (
"BushSpawner entity was deleted",
"Failed to delete BushSpawner entity"
)
entity_reference_updated = (
"Gradient Entity Id reference was properly updated",
"Gradient Entity Id reference was not updated properly"
)
class TestGraphUpdatesUpdateComponents(EditorTestHelper):
def __init__(self):
EditorTestHelper.__init__(self, log_prefix="GraphUpdatesUpdateComponents", args=["level"])
def GraphUpdates_UpdateComponent():
"""
Summary:
This test verifies that components are properly updated as nodes are added/removed/updated.
def run_test(self):
"""
Summary:
This test verifies that components are properly updated as nodes are added/removed/updated.
Expected Behavior:
Landscape Canvas node CRUD properly updates component entities.
Expected Behavior:
Landscape Canvas node CRUD properly updates component entities.
Test Steps:
1. Open Level.
2. Open the graph on LC_BushFlowerBlender.slice
3. Find the Rotation Modifier node on the BushSpawner entity
4. Delete the Rotation Modifier node
5. Ensure the Vegetation Rotation Modifier component is removed from the BushSpawner entity
6. Delete the Vegetation Layer Spawner node from the graph
7. Ensure BushSpawner entity is deleted
8. Change connection from second Rotation Modifier node to a different Gradient
9. Ensure Gradient reference on component is updated
Test Steps:
1. Open Level.
2. Open the graph on LC_BushFlowerBlender.slice
3. Find the Rotation Modifier node on the BushSpawner entity
4. Delete the Rotation Modifier node
5. Ensure the Vegetation Rotation Modifier component is removed from the BushSpawner entity
6. Delete the Vegetation Layer Spawner node from the graph
7. Ensure BushSpawner entity is deleted
8. Change connection from second Rotation Modifier node to a different Gradient
9. Ensure Gradient reference on component is updated
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
:return: None
"""
# Create a new empty level and instantiate LC_BushFlowerBlender.slice
self.test_success = self.create_level(
self.args["level"],
heightmap_resolution=128,
heightmap_meters_per_pixel=1,
terrain_texture_resolution=128,
use_terrain=False,
)
transform = math.Transform_CreateIdentity()
position = math.Vector3(64.0, 64.0, 32.0)
transform.invoke('SetPosition', position)
test_slice_path = os.path.join("Slices", "LC_BushFlowerBlender.slice")
test_slice_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", test_slice_path, math.Uuid(),
False)
test_slice = slice.SliceRequestBus(bus.Broadcast, 'InstantiateSliceFromAssetId', test_slice_id, transform)
self.test_success = self.test_success and test_slice.IsValid()
if test_slice.IsValid():
self.log("Slice spawned!")
import os
# Search for root entity to ensure slice is loaded
search_filter = entity.SearchFilter()
search_filter.names = ["LandscapeCanvas"]
self.wait_for_condition(lambda: len(entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)) > 0, 5.0)
import azlmbr.asset as asset
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.entity as entity
import azlmbr.legacy.general as general
import azlmbr.editor.graph as graph
import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.math as math
import azlmbr.slice as slice
# Find needed entities in the loaded level
slice_root_id = hydra.find_entity_by_name('LandscapeCanvas')
bush_spawner_id = hydra.find_entity_by_name('BushSpawner')
flower_spawner_id = hydra.find_entity_by_name('FlowerSpawner')
inverted_perlin_noise_id = hydra.find_entity_by_name('Invert')
import automatedtesting_shared.landscape_canvas_utils as lc
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
# Open Landscape Canvas and the existing graph
general.open_pane('Landscape Canvas')
open_graph_id = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'OnGraphEntity', slice_root_id)
self.test_success = self.test_success and open_graph_id.IsValid()
if open_graph_id.IsValid():
self.log('Graph opened')
# Open a simple level and instantiate LC_BushFlowerBlender.slice
helper.init_idle()
helper.open_level("Physics", "Base")
transform = math.Transform_CreateIdentity()
position = math.Vector3(64.0, 64.0, 32.0)
transform.invoke('SetPosition', position)
test_slice_path = os.path.join("Slices", "LC_BushFlowerBlender.slice")
test_slice_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", test_slice_path, math.Uuid(),
False)
test_slice = slice.SliceRequestBus(bus.Broadcast, 'InstantiateSliceFromAssetId', test_slice_id, transform)
Report.critical_result(Tests.slice_instantiated, test_slice.IsValid())
# Find the Rotation Modifier node on the BushSpawner entity
rotation_modifier_node = lc.find_nodes_matching_entity_component('Vegetation Rotation Modifier', bush_spawner_id)
# Search for root entity to ensure slice is loaded
search_filter = entity.SearchFilter()
search_filter.names = ["LandscapeCanvas"]
helper.wait_for_condition(lambda: len(entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)) > 0, 5.0)
# Remove the Rotation Modifier node
graph.GraphControllerRequestBus(bus.Event, 'RemoveNode', open_graph_id, rotation_modifier_node[0])
# Find needed entities in the loaded level
slice_root_id = hydra.find_entity_by_name('LandscapeCanvas')
bush_spawner_id = hydra.find_entity_by_name('BushSpawner')
flower_spawner_id = hydra.find_entity_by_name('FlowerSpawner')
inverted_perlin_noise_id = hydra.find_entity_by_name('Invert')
# Verify node was removed
rotation_modifier_node = lc.find_nodes_matching_entity_component('Vegetation Rotation Modifier', bush_spawner_id)
self.test_success = self.test_success and not rotation_modifier_node
if not rotation_modifier_node:
self.log('Rotation Modifier node was removed')
else:
self.log('Rotation Modifier node was not removed')
# Open Landscape Canvas and the existing graph
general.open_pane('Landscape Canvas')
open_graph_id = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'OnGraphEntity', slice_root_id)
Report.critical_result(Tests.existing_graph_opened, open_graph_id.IsValid())
# Verify the component was removed from the BushSpawner entity
has_rotation_modifier = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', bush_spawner_id,
hydra.get_component_type_id('Vegetation Rotation Modifier'))
self.test_success = self.test_success and not has_rotation_modifier
if not has_rotation_modifier:
self.log('Rotation Modifier component was removed from entity')
else:
self.log('Rotation Modifier component is still present on entity')
# Find the Rotation Modifier node on the BushSpawner entity
rotation_modifier_node = lc.find_nodes_matching_entity_component('Vegetation Rotation Modifier', bush_spawner_id)
# Find the Vegetation Layer Spawner node on the BushSpawner entity
layer_spawner_node = lc.find_nodes_matching_entity_component('Vegetation Layer Spawner', bush_spawner_id)
# Remove the Rotation Modifier node
graph.GraphControllerRequestBus(bus.Event, 'RemoveNode', open_graph_id, rotation_modifier_node[0])
# Remove the Vegetation Layer Spawner node and verify the corresponding entity is deleted
graph.GraphControllerRequestBus(bus.Event, 'RemoveNode', open_graph_id, layer_spawner_node[0])
bush_spawner_id = hydra.find_entity_by_name('BushSpawner')
self.test_success = self.test_success and not bush_spawner_id
if not bush_spawner_id:
self.log('BushSpawner entity was deleted')
else:
self.log('Failed to delete BushSpawner entity')
# Verify node was removed
rotation_modifier_node = lc.find_nodes_matching_entity_component('Vegetation Rotation Modifier', bush_spawner_id)
Report.result(Tests.node_removed, not rotation_modifier_node)
# Connect the FlowerSpawner's Rotation Modifier node to the Invert Gradient Modifier node
rotation_modifier_node = lc.find_nodes_matching_entity_component('Vegetation Rotation Modifier', flower_spawner_id)
invert_node = lc.find_nodes_matching_entity_component('Invert Gradient Modifier', inverted_perlin_noise_id)
# Verify the component was removed from the BushSpawner entity
has_rotation_modifier = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', bush_spawner_id,
hydra.get_component_type_id('Vegetation Rotation Modifier'))
Report.result(Tests.component_removed, not has_rotation_modifier)
inbound_gradient_z_slot = graph.GraphModelSlotId('InboundGradientZ')
outbound_gradient_slot = graph.GraphModelSlotId('OutboundGradient')
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', open_graph_id, invert_node[0],
outbound_gradient_slot, rotation_modifier_node[0], inbound_gradient_z_slot)
# Find the Vegetation Layer Spawner node on the BushSpawner entity
layer_spawner_node = lc.find_nodes_matching_entity_component('Vegetation Layer Spawner', bush_spawner_id)
general.idle_wait(1.0) # Add a small wait to ensure component property has time to update
# Remove the Vegetation Layer Spawner node and verify the corresponding entity is deleted
graph.GraphControllerRequestBus(bus.Event, 'RemoveNode', open_graph_id, layer_spawner_node[0])
bush_spawner_id = hydra.find_entity_by_name('BushSpawner')
Report.result(Tests.entity_deleted, not bush_spawner_id)
# Verify the Gradient Entity Id reference on the Rotation Modifier component was properly set
rotation_type_id = hydra.get_component_type_id('Vegetation Rotation Modifier')
rotation_outcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', flower_spawner_id,
rotation_type_id)
rotation_component = rotation_outcome.GetValue()
gradient_reference = hydra.get_component_property_value(rotation_component,
'Configuration|Rotation Z|Gradient|Gradient Entity Id')
gradient_reference_success = gradient_reference == inverted_perlin_noise_id
self.test_success = self.test_success and gradient_reference_success
if gradient_reference_success:
self.log('Gradient Entity Id reference was properly updated')
else:
self.log(f'Gradient Entity Id was not updated properly: Expected {inverted_perlin_noise_id.ToString()} -- Got '
f'{gradient_reference.ToString()}.')
# Connect the FlowerSpawner's Rotation Modifier node to the Invert Gradient Modifier node
rotation_modifier_node = lc.find_nodes_matching_entity_component('Vegetation Rotation Modifier', flower_spawner_id)
invert_node = lc.find_nodes_matching_entity_component('Invert Gradient Modifier', inverted_perlin_noise_id)
inbound_gradient_z_slot = graph.GraphModelSlotId('InboundGradientZ')
outbound_gradient_slot = graph.GraphModelSlotId('OutboundGradient')
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', open_graph_id, invert_node[0],
outbound_gradient_slot, rotation_modifier_node[0], inbound_gradient_z_slot)
general.idle_wait(1.0) # Add a small wait to ensure component property has time to update
# Verify the Gradient Entity Id reference on the Rotation Modifier component was properly set
rotation_type_id = hydra.get_component_type_id('Vegetation Rotation Modifier')
rotation_outcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', flower_spawner_id,
rotation_type_id)
rotation_component = rotation_outcome.GetValue()
gradient_reference = hydra.get_component_property_value(rotation_component,
'Configuration|Rotation Z|Gradient|Gradient Entity Id')
Report.result(Tests.entity_reference_updated, gradient_reference == inverted_perlin_noise_id)
test = TestGraphUpdatesUpdateComponents()
test.run()
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(GraphUpdates_UpdateComponent)
@@ -1,87 +0,0 @@
"""
Copyright (c) Contributors to the Open 3D Engine Project.
For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import os
import sys
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.entity as entity
import azlmbr.paths
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.editor_test_helper import EditorTestHelper
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
class TestLandscapeCanvasComponentAddedRemoved(EditorTestHelper):
def __init__(self):
EditorTestHelper.__init__(self, log_prefix="LandscapeCanvasComponentAddedRemoved", args=["level"])
def run_test(self):
"""
Summary:
This test verifies that the Landscape Canvas component can be added to/removed from an entity.
Expected Behavior:
Closing a tabbed graph only closes the appropriate graph.
Test Steps:
1) Create a new level
2) Create a new entity
3) Add a Landscape Canvas component to the entity
4) Remove the Landscape Canvas component from the entity
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
# Create a new empty level
self.test_success = self.create_level(
self.args["level"],
heightmap_resolution=128,
heightmap_meters_per_pixel=1,
terrain_texture_resolution=128,
use_terrain=False,
)
# Create an Entity at the root of the level
newEntityId = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', entity.EntityId())
# Find the component TypeId for our Landscape Canvas component
landscape_canvas_type_id = hydra.get_component_type_id("Landscape Canvas")
# Add the Landscape Canvas Component to our Entity
componentOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentsOfType', newEntityId, [landscape_canvas_type_id])
components = componentOutcome.GetValue()
landscapeCanvasComponent = components[0]
# Validate the Landscape Canvas Component exists
hasComponent = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId, landscape_canvas_type_id)
self.test_success = self.test_success and hasComponent
if hasComponent:
self.log("Landscape Canvas Component added to Entity")
# Remove the Landscape Canvas Component
editor.EditorComponentAPIBus(bus.Broadcast, 'RemoveComponents', [landscapeCanvasComponent])
# Validate the Landscape Canvas Component is no longer on our Entity
hasComponent = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId, landscape_canvas_type_id)
self.test_success = self.test_success and not hasComponent
if not hasComponent:
self.log("Landscape Canvas Component removed from Entity")
test = TestLandscapeCanvasComponentAddedRemoved()
test.run()
@@ -1,82 +0,0 @@
"""
Copyright (c) Contributors to the Open 3D Engine Project.
For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import os
import sys
import azlmbr.math as math
import azlmbr.paths
import azlmbr.bus as bus
import azlmbr.asset as asset
import azlmbr.slice as slice
sys.path.append(os.path.join(azlmbr.paths.devroot, "AutomatedTesting", "Gem", "PythonTests"))
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.editor_test_helper import EditorTestHelper
class TestLandscapeCanvasSliceCreateInstantiate(EditorTestHelper):
def __init__(self):
EditorTestHelper.__init__(self, log_prefix="LandscapeCanvas_SliceCreateInstantiate", args=["level"])
def run_test(self):
"""
Summary:
A slice containing the LandscapeCanvas component can be created/instantiated.
Expected Result:
Slice is created/processed/instantiated successfully and free of errors/warnings.
Test Steps:
1) Create a new level
2) Create a new entity with a Landscape Canvas component
3) Create a slice of the new entity
4) Instantiate a new copy of the slice
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
def path_is_valid_asset(asset_path):
asset_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", asset_path, math.Uuid(), False)
return asset_id.invoke("IsValid")
# Create empty level
self.test_success = self.create_level(
self.args["level"],
heightmap_resolution=1024,
heightmap_meters_per_pixel=1,
terrain_texture_resolution=4096,
use_terrain=False,
)
# Create entity with LandScape Canvas component
position = math.Vector3(512.0, 512.0, 32.0)
landscape_canvas = hydra.Entity("landscape_canvas_entity")
landscape_canvas.create_entity(position, ["Landscape Canvas"])
# Create slice from the created entity
slice_path = os.path.join("slices", "TestSlice.slice")
slice.SliceRequestBus(bus.Broadcast, "CreateNewSlice", landscape_canvas.id, slice_path)
# Verify if slice is created
self.wait_for_condition(lambda: path_is_valid_asset(slice_path), 5.0)
self.log(f"Slice has been created successfully: {path_is_valid_asset(slice_path)}")
# Instantiate slice
transform = math.Transform_CreateIdentity()
asset_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", slice_path, math.Uuid(), False)
test_slice = slice.SliceRequestBus(bus.Broadcast, "InstantiateSliceFromAssetId", asset_id, transform)
self.wait_for_condition(lambda: test_slice.IsValid(), 3.0)
self.log(f"Slice instantiated: {test_slice.IsValid()}")
test = TestLandscapeCanvasSliceCreateInstantiate()
test.run()
@@ -5,157 +5,160 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import os
import sys
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.editor.graph as graph
import azlmbr.entity as entity
import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.legacy.general as general
import azlmbr.math as math
import azlmbr.paths
class Tests:
lc_tool_opened = (
"Landscape Canvas tool opened",
"Failed to open Landscape Canvas tool"
)
new_graph_created = (
"Successfully created new graph",
"Failed to create new graph"
)
graph_registered = (
"Graph registered with Landscape Canvas",
"Failed to register graph"
)
blender_first_layer_set = (
"Spawner entity set as the first layer of the Vegetation Layer Blender component",
"Unexpected entity set as the first layer of the Vegetation Layer Blender component"
)
blender_second_layer_set = (
"Blocker entity set as the second layer of the Vegetation Layer Blender component",
"Unexpected entity set as the second layer of the Vegetation Layer Blender component"
)
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.editor_test_helper import EditorTestHelper
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
newEntityId = None
class TestLayerBlenderNodeConstruction(EditorTestHelper):
def __init__(self):
EditorTestHelper.__init__(self, log_prefix="LayerBlenderNodeConstruction", args=["level"])
def LayerBlender_NodeConstruction():
"""
Summary:
This test verifies a Layer Blender vegetation setup can be constructed through Landscape Canvas.
def run_test(self):
"""
Summary:
This test verifies a Layer Blender vegetation setup can be constructed through Landscape Canvas.
Expected Behavior:
Entities contain all required components and component references after creating nodes and setting connections
on a Landscape Canvas graph.
Expected Behavior:
Entities contain all required components and component references after creating nodes and setting connections
on a Landscape Canvas graph.
Test Steps:
1) Open a simple level
2) Open Landscape Canvas and create a new graph
3) Add all necessary nodes to the graph and set connections to form a Layer Blender setup
4) Verify all components and component references were properly set during graph construction
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create a new graph
3) Add all necessary nodes to the graph and set connections to form a Layer Blender setup
4) Verify all components and component references were properly set during graph construction
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
:return: None
"""
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.editor.graph as graph
import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.legacy.general as general
import azlmbr.math as math
def onEntityCreated(parameters):
global newEntityId
newEntityId = parameters[0]
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
# Create a new empty level
self.test_success = self.create_level(
self.args["level"],
heightmap_resolution=1024,
heightmap_meters_per_pixel=1,
terrain_texture_resolution=4096,
use_terrain=False,
)
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
# Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas')
self.test_success = self.test_success and general.is_pane_visible('Landscape Canvas')
if general.is_pane_visible('Landscape Canvas'):
self.log('Landscape Canvas pane is open')
def onEntityCreated(parameters):
global newEntityId
newEntityId = parameters[0]
# Create a new graph in Landscape Canvas
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
self.test_success = self.test_success and newGraphId
if newGraphId:
self.log("New graph created")
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
# Make sure the graph we created is in Landscape Canvas
success = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
self.test_success = self.test_success and success
if success:
self.log("Graph registered with Landscape Canvas")
# Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas')
Report.critical_result(Tests.lc_tool_opened, general.is_pane_visible('Landscape Canvas'))
# Listen for entity creation notifications so we can verify the component EntityId
# references are set correctly when connecting slots on the nodes
handler = editor.EditorEntityContextNotificationBusHandler()
handler.connect()
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
# Create a new graph in Landscape Canvas
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
Report.critical_result(Tests.new_graph_created, newGraphId is not None)
positionX = 10.0
positionY = 10.0
offsetX = 340.0
offsetY = 100.0
# Make sure the graph we created is in Landscape Canvas
graph_registered = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
Report.result(Tests.graph_registered, graph_registered)
# Add a Vegetation Layer Spawner node to the graph
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
layerSpawnerNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
newGraph, 'SpawnerAreaNode')
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, layerSpawnerNode, math.Vector2(positionX, positionY))
layerSpawnerEntityId = newEntityId
# Listen for entity creation notifications so we can verify the component EntityId
# references are set correctly when connecting slots on the nodes
handler = editor.EditorEntityContextNotificationBusHandler()
handler.connect()
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
positionX += offsetX
positionY += offsetY
positionX = 10.0
positionY = 10.0
offsetX = 340.0
offsetY = 100.0
# Add a Vegetation Layer Blocker node to the graph
layerBlockerNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
newGraph, 'BlockerAreaNode')
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, layerBlockerNode, math.Vector2(positionX, positionY))
layerBlockerEntityId = newEntityId
# Add a Vegetation Layer Spawner node to the graph
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
layerSpawnerNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
newGraph, 'SpawnerAreaNode')
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, layerSpawnerNode, math.Vector2(positionX, positionY))
layerSpawnerEntityId = newEntityId
positionX += offsetX
positionY += offsetY
positionX += offsetX
positionY += offsetY
# Add a Vegetation Layer Blender node to the graph
layerBlenderNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
newGraph, 'AreaBlenderNode')
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, layerBlenderNode, math.Vector2(positionX, positionY))
layerBlenderNodeEntityId = newEntityId
# Add a Vegetation Layer Blocker node to the graph
layerBlockerNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
newGraph, 'BlockerAreaNode')
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, layerBlockerNode, math.Vector2(positionX, positionY))
layerBlockerEntityId = newEntityId
positionX += offsetX
positionY += offsetY
positionX += offsetX
positionY += offsetY
outboundAreaSlotId = graph.GraphModelSlotId('OutboundArea')
inboundAreaSlotId = graph.GraphModelSlotId('InboundArea')
inboundAreaSlotId2 = graph.GraphControllerRequestBus(bus.Event, 'ExtendSlot', newGraphId, layerBlenderNode,
'InboundArea')
# Add a Vegetation Layer Blender node to the graph
layerBlenderNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
newGraph, 'AreaBlenderNode')
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, layerBlenderNode, math.Vector2(positionX, positionY))
layerBlenderNodeEntityId = newEntityId
# Connect slots on our nodes to construct a Vegetation Layer Blender hierarchy
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, layerSpawnerNode, outboundAreaSlotId,
layerBlenderNode, inboundAreaSlotId)
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, layerBlockerNode, outboundAreaSlotId,
layerBlenderNode, inboundAreaSlotId2)
positionX += offsetX
positionY += offsetY
# Delay to allow all the underlying component properties to be updated after the slot connections are made
general.idle_wait(1.0)
outboundAreaSlotId = graph.GraphModelSlotId('OutboundArea')
inboundAreaSlotId = graph.GraphModelSlotId('InboundArea')
inboundAreaSlotId2 = graph.GraphControllerRequestBus(bus.Event, 'ExtendSlot', newGraphId, layerBlenderNode,
'InboundArea')
# Get component info
layerBlenderTypeId = hydra.get_component_type_id("Vegetation Layer Blender")
vegetationLayerBlenderOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType',
layerBlenderNodeEntityId, layerBlenderTypeId)
layerBlenderComponent = vegetationLayerBlenderOutcome.GetValue()
# Connect slots on our nodes to construct a Vegetation Layer Blender hierarchy
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, layerSpawnerNode, outboundAreaSlotId,
layerBlenderNode, inboundAreaSlotId)
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, layerBlockerNode, outboundAreaSlotId,
layerBlenderNode, inboundAreaSlotId2)
# Verify the Vegetation Areas properties on our Vegetation Layer Blender component have been set to our area EntityIds
area1EntityId = hydra.get_component_property_value(layerBlenderComponent, 'Configuration|Vegetation Areas|[0]')
self.test_success = self.test_success and area1EntityId and layerSpawnerEntityId.invoke("Equal", area1EntityId)
if area1EntityId and layerSpawnerEntityId.invoke("Equal", area1EntityId):
self.log("Vegetation Layer Blender component Vegetation Areas[0] property set to Vegetation Layer Spawner EntityId")
# Delay to allow all the underlying component properties to be updated after the slot connections are made
general.idle_wait(1.0)
area2EntityId = hydra.get_component_property_value(layerBlenderComponent, 'Configuration|Vegetation Areas|[1]')
self.test_success = self.test_success and area2EntityId and layerBlockerEntityId.invoke("Equal", area2EntityId)
if area2EntityId and layerBlockerEntityId.invoke("Equal", area2EntityId):
self.log("Vegetation Layer Blender component Vegetation Areas[1] property set to Vegetation Layer Blocker EntityId")
# Get component info
layerBlenderTypeId = hydra.get_component_type_id("Vegetation Layer Blender")
vegetationLayerBlenderOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType',
layerBlenderNodeEntityId, layerBlenderTypeId)
layerBlenderComponent = vegetationLayerBlenderOutcome.GetValue()
# Stop listening for entity creation notifications
handler.disconnect()
# Verify the Vegetation Areas properties on our Vegetation Layer Blender component have been set to our area EntityIds
area1EntityId = hydra.get_component_property_value(layerBlenderComponent, 'Configuration|Vegetation Areas|[0]')
Report.result(Tests.blender_first_layer_set, area1EntityId and layerSpawnerEntityId.invoke("Equal", area1EntityId))
area2EntityId = hydra.get_component_property_value(layerBlenderComponent, 'Configuration|Vegetation Areas|[1]')
Report.result(Tests.blender_second_layer_set, area2EntityId and layerBlockerEntityId.invoke("Equal", area2EntityId))
# Stop listening for entity creation notifications
handler.disconnect()
test = TestLayerBlenderNodeConstruction()
test.run()
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(LayerBlender_NodeConstruction)
@@ -5,164 +5,170 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import os
import sys
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.editor.graph as graph
import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.legacy.general as general
import azlmbr.math as math
import azlmbr.paths
class Tests:
lc_tool_opened = (
"Landscape Canvas tool opened",
"Failed to open Landscape Canvas tool"
)
new_graph_created = (
"Successfully created new graph",
"Failed to create new graph"
)
graph_registered = (
"Graph registered with Landscape Canvas",
"Failed to register graph"
)
component_added = (
"Expected component is present on entity",
"Expected component was not found on entity"
)
component_removed = (
"Expected component was removed from entity",
"Component is unexpectedly still present on entity"
)
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.editor_test_helper import EditorTestHelper
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
newEntityId = None
class TestLayerExtenderNodeComponentEntitySync(EditorTestHelper):
def LayerExtenderNodes_ComponentEntitySync():
"""
Summary:
This test verifies that all wrapped nodes can be successfully added to/removed from parent nodes.
def __init__(self):
EditorTestHelper.__init__(self, log_prefix="LayerExtenderNodeComponentEntitySync", args=["level"])
Expected Behavior:
All wrapped extender nodes can be added to/removed from appropriate parent nodes.
def run_test(self):
"""
Summary:
This test verifies that all wrapped nodes can be successfully added to/removed from parent nodes.
Test Steps:
1) Open a simple level
2) Open Landscape Canvas and create a new graph
3) Add Area Blender and Layer Spawner nodes to the graph, and add/remove each extender node to/from each
Expected Behavior:
All wrapped extender nodes can be added to/removed from appropriate parent nodes.
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create a new graph
3) Add Area Blender and Layer Spawner nodes to the graph, and add/remove each extender node to/from each
:return: None
"""
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.editor.graph as graph
import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.legacy.general as general
import azlmbr.math as math
import azlmbr.paths
:return: None
"""
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
def onEntityCreated(parameters):
global newEntityId
newEntityId = parameters[0]
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
# Create a new empty level
self.test_success = self.create_level(
self.args["level"],
heightmap_resolution=128,
heightmap_meters_per_pixel=1,
terrain_texture_resolution=128,
use_terrain=False,
)
def onEntityCreated(parameters):
global newEntityId
newEntityId = parameters[0]
# Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas')
self.test_success = self.test_success and general.is_pane_visible('Landscape Canvas')
if general.is_pane_visible('Landscape Canvas'):
self.log('Landscape Canvas pane is open')
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
# Create a new graph in Landscape Canvas
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
self.test_success = self.test_success and newGraphId
if newGraphId:
self.log("New graph created")
# Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas')
Report.critical_result(Tests.lc_tool_opened, general.is_pane_visible('Landscape Canvas'))
# Make sure the graph we created is in Landscape Canvas
success = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
self.test_success = self.test_success and success
if success:
self.log("Graph registered with Landscape Canvas")
# Create a new graph in Landscape Canvas
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
Report.critical_result(Tests.new_graph_created, newGraphId is not None)
# Listen for entity creation notifications so we can check if the
# proper components are added when we add nodes
handler = editor.EditorEntityContextNotificationBusHandler()
handler.connect()
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
# Make sure the graph we created is in Landscape Canvas
graph_registered = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
Report.result(Tests.graph_registered, graph_registered)
# Extender mapping with the key being the node name and the value is the
# expected Component that should be added to the layer Entity for that wrapped node
extenders = {
'AltitudeFilterNode': 'Vegetation Altitude Filter',
'DistanceBetweenFilterNode': 'Vegetation Distance Between Filter',
'DistributionFilterNode': 'Vegetation Distribution Filter',
'ShapeIntersectionFilterNode': 'Vegetation Shape Intersection Filter',
'SlopeFilterNode': 'Vegetation Slope Filter',
'SurfaceMaskDepthFilterNode': 'Vegetation Surface Mask Depth Filter',
'SurfaceMaskFilterNode': 'Vegetation Surface Mask Filter',
'PositionModifierNode': 'Vegetation Position Modifier',
'RotationModifierNode': 'Vegetation Rotation Modifier',
'ScaleModifierNode': 'Vegetation Scale Modifier',
'SlopeAlignmentModifierNode': 'Vegetation Slope Alignment Modifier',
'AssetWeightSelectorNode': 'Vegetation Asset Weight Selector'
}
# Listen for entity creation notifications so we can check if the
# proper components are added when we add nodes
handler = editor.EditorEntityContextNotificationBusHandler()
handler.connect()
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
# Retrieve a mapping of the TypeIds for all the components
# we will be checking for
componentNames = []
for name in extenders:
componentNames.append(extenders[name])
componentTypeIds = hydra.get_component_type_id_map(componentNames)
# Extender mapping with the key being the node name and the value is the
# expected Component that should be added to the layer Entity for that wrapped node
extenders = {
'AltitudeFilterNode': 'Vegetation Altitude Filter',
'DistanceBetweenFilterNode': 'Vegetation Distance Between Filter',
'DistributionFilterNode': 'Vegetation Distribution Filter',
'ShapeIntersectionFilterNode': 'Vegetation Shape Intersection Filter',
'SlopeFilterNode': 'Vegetation Slope Filter',
'SurfaceMaskDepthFilterNode': 'Vegetation Surface Mask Depth Filter',
'SurfaceMaskFilterNode': 'Vegetation Surface Mask Filter',
'PositionModifierNode': 'Vegetation Position Modifier',
'RotationModifierNode': 'Vegetation Rotation Modifier',
'ScaleModifierNode': 'Vegetation Scale Modifier',
'SlopeAlignmentModifierNode': 'Vegetation Slope Alignment Modifier',
'AssetWeightSelectorNode': 'Vegetation Asset Weight Selector'
}
areas = [
'AreaBlenderNode',
'SpawnerAreaNode'
]
# Retrieve a mapping of the TypeIds for all the components
# we will be checking for
componentNames = []
for name in extenders:
componentNames.append(extenders[name])
componentTypeIds = hydra.get_component_type_id_map(componentNames)
# Add/remove all our supported extender nodes to the Layer Areas and check if the appropriate
# Components are added/removed to the wrapper node's Entity
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
x = 10.0
y = 10.0
for areaName in areas:
nodePosition = math.Vector2(x, y)
areaNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
newGraph, areaName)
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, areaNode, nodePosition)
areas = [
'AreaBlenderNode',
'SpawnerAreaNode'
]
success = True
for extenderName in extenders:
# Add the wrapped node for the extender
extenderNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast,
'CreateNodeForTypeName', newGraph,
extenderName)
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, extenderNode, nodePosition)
graph.GraphControllerRequestBus(bus.Event, 'WrapNode', newGraphId, areaNode, extenderNode)
# Add/remove all our supported extender nodes to the Layer Areas and check if the appropriate
# Components are added/removed to the wrapper node's Entity
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
x = 10.0
y = 10.0
for areaName in areas:
nodePosition = math.Vector2(x, y)
areaNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
newGraph, areaName)
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, areaNode, nodePosition)
# Check that the appropriate Component was added when the extender node was added
extenderComponent = extenders[extenderName]
componentTypeId = componentTypeIds[extenderComponent]
success = success and editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId,
success = True
for extenderName in extenders:
# Add the wrapped node for the extender
extenderNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast,
'CreateNodeForTypeName', newGraph,
extenderName)
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, extenderNode, nodePosition)
graph.GraphControllerRequestBus(bus.Event, 'WrapNode', newGraphId, areaNode, extenderNode)
# Check that the appropriate Component was added when the extender node was added
extenderComponent = extenders[extenderName]
componentTypeId = componentTypeIds[extenderComponent]
success = success and editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId,
componentTypeId)
Report.info(f"Component: {extenderComponent}")
Report.result(Tests.component_added, success)
if not success:
break
# Check that the appropriate Component was removed when the extender node was removed
graph.GraphControllerRequestBus(bus.Event, 'RemoveNode', newGraphId, extenderNode)
success = success and not editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId,
componentTypeId)
self.test_success = self.test_success and success
if not success:
self.log("{node} failed to add {component} Component".format(node=areaName,
component=extenderComponent))
break
Report.info(f"Component: {extenderComponent}")
Report.result(Tests.component_removed, success)
if not success:
break
# Check that the appropriate Component was removed when the extender node was removed
graph.GraphControllerRequestBus(bus.Event, 'RemoveNode', newGraphId, extenderNode)
success = success and not editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId,
componentTypeId)
self.test_success = self.test_success and success
if not success:
self.log("{node} failed to remove {component} Component".format(node=areaName,
component=extenderComponent))
break
if success:
Report.info(f"{areaName} successfully added and removed all filters/modifiers/selectors")
if success:
self.log("{node} successfully added and removed all filters/modifiers/selectors".format(node=areaName))
# Stop listening for entity creation notifications
handler.disconnect()
# Stop listening for entity creation notifications
handler.disconnect()
test = TestLayerExtenderNodeComponentEntitySync()
test.run()
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(LayerExtenderNodes_ComponentEntitySync)
@@ -0,0 +1,111 @@
"""
Copyright (c) Contributors to the Open 3D Engine Project.
For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
class Tests:
lc_tool_opened = (
"Landscape Canvas tool opened",
"Failed to open Landscape Canvas tool"
)
new_graph_created = (
"Successfully created new graph",
"Failed to create new graph"
)
graph_registered = (
"Graph registered with Landscape Canvas",
"Failed to register graph"
)
lc_component_added = (
"Root entity created with the Landscape Canvas component",
"Landscape Canvas component was not found on the root entity"
)
lc_tool_closed = (
"Landscape Canvas tool closed",
"Failed to close Landscape Canvas tool"
)
new_root_entity_id = None
def NewGraph_CreatedSuccessfully():
"""
Summary:
This test verifies that new graphs can be created in Landscape Canvas.
Expected Behavior:
New graphs can be created, and proper entity is created to hold graph data with a Landscape Canvas component.
Test Steps:
1) Open a simple level
2) Open Landscape Canvas and create a new graph
3) Ensures the root entity created contains a Landscape Canvas component
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.editor.graph as graph
import azlmbr.legacy.general as general
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
def on_entity_created(parameters):
global new_root_entity_id
new_root_entity_id = parameters[0]
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
# Listen for entity creation notifications so we can check if the entity created
# with the new graph has our Landscape Canvas component automatically added
handler = editor.EditorEntityContextNotificationBusHandler()
handler.connect()
handler.add_callback("OnEditorEntityCreated", on_entity_created)
# Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas')
Report.critical_result(Tests.lc_tool_opened, general.is_pane_visible('Landscape Canvas'))
# Create a new graph in Landscape Canvas
new_graph_id = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
Report.critical_result(Tests.new_graph_created, new_graph_id is not None)
# Make sure the graph we created is in Landscape Canvas
graph_registered = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, new_graph_id)
Report.result(Tests.graph_registered, graph_registered)
# Check if the entity created when we create a new graph has the
# Landscape Canvas component already added to it
landscape_canvas_type_id = hydra.get_component_type_id("Landscape Canvas")
success = editor.EditorComponentAPIBus(bus.Broadcast, "HasComponentOfType", new_root_entity_id,
landscape_canvas_type_id)
Report.result(Tests.lc_component_added, success)
# Close Landscape Canvas tool and verify
general.close_pane("Landscape Canvas")
Report.result(Tests.lc_tool_closed, not general.is_pane_visible("Landscape Canvas"))
# Stop listening for entity creation notifications
handler.disconnect()
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(NewGraph_CreatedSuccessfully)
@@ -5,133 +5,136 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import os
import sys
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.editor.graph as graph
import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.legacy.general as general
import azlmbr.math as math
import azlmbr.paths
class Tests:
lc_tool_opened = (
"Landscape Canvas tool opened",
"Failed to open Landscape Canvas tool"
)
new_graph_created = (
"Successfully created new graph",
"Failed to create new graph"
)
graph_registered = (
"Graph registered with Landscape Canvas",
"Failed to register graph"
)
component_added = (
"New entity created with the expected component",
"Expected component was not found on entity"
)
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.editor_test_helper import EditorTestHelper
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
newEntityId = None
class TestShapeNodeEntityCreate(EditorTestHelper):
def __init__(self):
EditorTestHelper.__init__(self, log_prefix="ShapeNodeEntityCreate", args=["level"])
def ShapeNodes_EntityCreatedOnNodeAdd():
"""
Summary:
This test verifies that the Landscape Canvas nodes can be added to a graph, and correctly create entities.
def run_test(self):
"""
Summary:
This test verifies that the Landscape Canvas nodes can be added to a graph, and correctly create entities.
Expected Behavior:
New entities are created when dragging shape nodes to graph area.
Expected Behavior:
New entities are created when dragging shape nodes to graph area.
Test Steps:
1) Open a simple level
2) Open Landscape Canvas and create a new graph
3) Drag each of the shape nodes to the graph area, and ensure a new entity is created
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create a new graph
3) Drag each of the shape nodes to the graph area, and ensure a new entity is created
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
:return: None
"""
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.editor.graph as graph
import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.legacy.general as general
import azlmbr.math as math
def onEntityCreated(parameters):
global newEntityId
newEntityId = parameters[0]
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
# Create a new empty level
self.test_success = self.create_level(
self.args["level"],
heightmap_resolution=128,
heightmap_meters_per_pixel=1,
terrain_texture_resolution=128,
use_terrain=False,
)
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
# Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas')
self.test_success = self.test_success and general.is_pane_visible('Landscape Canvas')
if general.is_pane_visible('Landscape Canvas'):
self.log('Landscape Canvas pane is open')
def onEntityCreated(parameters):
global newEntityId
newEntityId = parameters[0]
# Create a new graph in Landscape Canvas
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
self.test_success = self.test_success and newGraphId
if newGraphId:
self.log("New graph created")
# Open an existing simple level
# Make sure the graph we created is in Landscape Canvas
success = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
self.test_success = self.test_success and success
if success:
self.log("Graph registered with Landscape Canvas")
helper.init_idle()
helper.open_level("Physics", "Base")
# Listen for entity creation notifications so we can check if the entity created
# from adding shape nodes has the appropriate Shape Component
handler = editor.EditorEntityContextNotificationBusHandler()
handler.connect()
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
# Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas')
Report.critical_result(Tests.lc_tool_opened, general.is_pane_visible('Landscape Canvas'))
# Shape mapping with the key being the node name and the value is the
# expected Component that should be added to the Entity created for the node
shapes = {
'BoxShapeNode': 'Box Shape',
'CapsuleShapeNode': 'Capsule Shape',
'CompoundShapeNode': 'Compound Shape',
'CylinderShapeNode': 'Cylinder Shape',
'PolygonPrismShapeNode': 'Polygon Prism Shape',
'SphereShapeNode': 'Sphere Shape',
'TubeShapeNode': 'Tube Shape',
'DiskShapeNode': 'Disk Shape'
}
# Create a new graph in Landscape Canvas
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
Report.critical_result(Tests.new_graph_created, newGraphId is not None)
# Retrieve a mapping of the TypeIds for all the components
# we will be checking for
componentNames = []
for name in shapes:
componentNames.append(shapes[name])
componentTypeIds = hydra.get_component_type_id_map(componentNames)
# Make sure the graph we created is in Landscape Canvas
graph_registered = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
Report.result(Tests.graph_registered, graph_registered)
# Create nodes for all the shapes we support and check if the Entity created by
# adding the node has the appropriate Component added automatically to it
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
x = 10.0
y = 10.0
for nodeName in shapes:
nodePosition = math.Vector2(x, y)
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
newGraph, nodeName)
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
# Listen for entity creation notifications so we can check if the entity created
# from adding shape nodes has the appropriate Shape Component
handler = editor.EditorEntityContextNotificationBusHandler()
handler.connect()
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
shapeComponent = shapes[nodeName]
componentTypeId = componentTypeIds[shapeComponent]
hasComponent = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId,
componentTypeId)
self.test_success = self.test_success and hasComponent
if hasComponent:
self.log("{node} created new Entity with {component} Component".format(node=nodeName,
component=shapeComponent))
# Shape mapping with the key being the node name and the value is the
# expected Component that should be added to the Entity created for the node
shapes = {
'BoxShapeNode': 'Box Shape',
'CapsuleShapeNode': 'Capsule Shape',
'CompoundShapeNode': 'Compound Shape',
'CylinderShapeNode': 'Cylinder Shape',
'PolygonPrismShapeNode': 'Polygon Prism Shape',
'SphereShapeNode': 'Sphere Shape',
'TubeShapeNode': 'Tube Shape',
'DiskShapeNode': 'Disk Shape'
}
x += 40.0
y += 40.0
# Retrieve a mapping of the TypeIds for all the components
# we will be checking for
componentNames = []
for name in shapes:
componentNames.append(shapes[name])
componentTypeIds = hydra.get_component_type_id_map(componentNames)
# Stop listening for entity creation notifications
handler.disconnect()
# Create nodes for all the shapes we support and check if the Entity created by
# adding the node has the appropriate Component added automatically to it
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
x = 10.0
y = 10.0
for nodeName in shapes:
nodePosition = math.Vector2(x, y)
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
newGraph, nodeName)
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
shapeComponent = shapes[nodeName]
componentTypeId = componentTypeIds[shapeComponent]
hasComponent = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId,
componentTypeId)
Report.info(f"Node: {nodeName} | Component: {shapeComponent}")
Report.result(Tests.component_added, hasComponent)
x += 40.0
y += 40.0
# Stop listening for entity creation notifications
handler.disconnect()
test = TestShapeNodeEntityCreate()
test.run()
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(ShapeNodes_EntityCreatedOnNodeAdd)
@@ -5,127 +5,129 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import os
import sys
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.editor.graph as graph
import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.legacy.general as general
import azlmbr.math as math
import azlmbr.paths
class Tests:
lc_tool_opened = (
"Landscape Canvas tool opened",
"Failed to open Landscape Canvas tool"
)
new_graph_created = (
"Successfully created new graph",
"Failed to create new graph"
)
graph_registered = (
"Graph registered with Landscape Canvas",
"Failed to register graph"
)
entity_deleted = (
"Entity was deleted when node was removed",
"Entity was not deleted as expected when node was removed"
)
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
from editor_python_test_tools.editor_test_helper import EditorTestHelper
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
createdEntityId = None
deletedEntityId = None
class TestShapeNodeEntityDelete(EditorTestHelper):
def ShapeNodes_EntityRemovedOnNodeDelete():
"""
Summary:
This test verifies that the Landscape Canvas node deletion properly cleans up entities in the Editor.
def __init__(self):
EditorTestHelper.__init__(self, log_prefix="ShapeNodeEntityDelete", args=["level"])
Expected Behavior:
Entities are removed when shape nodes are deleted from a graph.
def run_test(self):
"""
Summary:
This test verifies that the Landscape Canvas node deletion properly cleans up entities in the Editor.
Test Steps:
1) Open a simple level
2) Open Landscape Canvas and create a new graph
3) Drag each of the shape nodes to the graph area, and ensure a new entity is created
4) Delete the nodes, and ensure the newly created entities are removed
Expected Behavior:
Entities are removed when shape nodes are deleted from a graph.
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create a new graph
3) Drag each of the shape nodes to the graph area, and ensure a new entity is created
4) Delete the nodes, and ensure the newly created entities are removed
:return: None
"""
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.editor.graph as graph
import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.legacy.general as general
import azlmbr.math as math
:return: None
"""
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
def onEntityCreated(parameters):
global createdEntityId
createdEntityId = parameters[0]
def onEntityDeleted(parameters):
global deletedEntityId
deletedEntityId = parameters[0]
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
# Create a new empty level
self.test_success = self.create_level(
self.args["level"],
heightmap_resolution=128,
heightmap_meters_per_pixel=1,
terrain_texture_resolution=128,
use_terrain=False,
)
# Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas')
self.test_success = self.test_success and general.is_pane_visible('Landscape Canvas')
if general.is_pane_visible('Landscape Canvas'):
self.log('Landscape Canvas pane is open')
# Create a new graph in Landscape Canvas
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
self.test_success = self.test_success and newGraphId
if newGraphId:
self.log("New graph created")
# Make sure the graph we created is in Landscape Canvas
success = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
self.test_success = self.test_success and success
if success:
self.log("Graph registered with Landscape Canvas")
# Listen for entity creation/deletion notifications so we can verify the
# Entity created when adding a new also gets deleted when the node is deleted
handler = editor.EditorEntityContextNotificationBusHandler()
handler.connect()
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
handler.add_callback('OnEditorEntityDeleted', onEntityDeleted)
# All of the shape nodes that we support
shapes = [
'BoxShapeNode',
'CapsuleShapeNode',
'CompoundShapeNode',
'CylinderShapeNode',
'PolygonPrismShapeNode',
'SphereShapeNode',
'TubeShapeNode',
'DiskShapeNode'
]
# Create nodes for all the shapes we support and check if the Entity is created
# and then deleted when the node is removed
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
x = 10.0
y = 10.0
for nodeName in shapes:
nodePosition = math.Vector2(x, y)
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph, nodeName)
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
removed = graph.GraphControllerRequestBus(bus.Event, 'RemoveNode', newGraphId, node)
# Verify that the created Entity for this node matches the Entity that gets
# deleted when the node is removed
self.test_success = self.test_success and removed and createdEntityId.invoke("Equal", deletedEntityId)
if removed and createdEntityId.invoke("Equal", deletedEntityId):
self.log("{node} corresponding Entity was deleted when node is removed".format(node=nodeName))
# Stop listening for entity creation/deletion notifications
handler.disconnect()
def onEntityCreated(parameters):
global createdEntityId
createdEntityId = parameters[0]
def onEntityDeleted(parameters):
global deletedEntityId
deletedEntityId = parameters[0]
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
# Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas')
Report.critical_result(Tests.lc_tool_opened, general.is_pane_visible('Landscape Canvas'))
# Create a new graph in Landscape Canvas
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
Report.critical_result(Tests.new_graph_created, newGraphId is not None)
# Make sure the graph we created is in Landscape Canvas
graph_registered = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
Report.result(Tests.graph_registered, graph_registered)
# Listen for entity creation/deletion notifications so we can verify the
# Entity created when adding a new also gets deleted when the node is deleted
handler = editor.EditorEntityContextNotificationBusHandler()
handler.connect()
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
handler.add_callback('OnEditorEntityDeleted', onEntityDeleted)
# All of the shape nodes that we support
shapes = [
'BoxShapeNode',
'CapsuleShapeNode',
'CompoundShapeNode',
'CylinderShapeNode',
'PolygonPrismShapeNode',
'SphereShapeNode',
'TubeShapeNode',
'DiskShapeNode'
]
# Create nodes for all the shapes we support and check if the Entity is created
# and then deleted when the node is removed
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
x = 10.0
y = 10.0
for nodeName in shapes:
nodePosition = math.Vector2(x, y)
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph, nodeName)
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
removed = graph.GraphControllerRequestBus(bus.Event, 'RemoveNode', newGraphId, node)
# Verify that the created Entity for this node matches the Entity that gets
# deleted when the node is removed
Report.info(f"Node: {nodeName}")
Report.result(Tests.entity_deleted, removed and createdEntityId.invoke("Equal", deletedEntityId))
# Stop listening for entity creation/deletion notifications
handler.disconnect()
test = TestShapeNodeEntityDelete()
test.run()
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(ShapeNodes_EntityRemovedOnNodeDelete)
@@ -0,0 +1,84 @@
"""
Copyright (c) Contributors to the Open 3D Engine Project.
For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
class Tests:
slice_created = (
"Slice created successfully",
"Failed to create slice"
)
slice_instantiated = (
"Slice instantiated successfully",
"Failed to instantiate slice"
)
def Slice_CreateInstantiate():
"""
Summary:
A slice containing the LandscapeCanvas component can be created/instantiated.
Expected Result:
Slice is created/processed/instantiated successfully and free of errors/warnings.
Test Steps:
1) Open a simple level
2) Create a new entity with a Landscape Canvas component
3) Create a slice of the new entity
4) Instantiate a new copy of the slice
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
import os
import azlmbr.math as math
import azlmbr.bus as bus
import azlmbr.asset as asset
import azlmbr.slice as slice
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
def path_is_valid_asset(asset_path):
asset_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", asset_path, math.Uuid(), False)
return asset_id.invoke("IsValid")
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
# Create entity with Landscape Canvas component
position = math.Vector3(512.0, 512.0, 32.0)
landscape_canvas = hydra.Entity("landscape_canvas_entity")
landscape_canvas.create_entity(position, ["Landscape Canvas"])
# Create slice from the created entity
slice_path = os.path.join("slices", "TestSlice.slice")
slice.SliceRequestBus(bus.Broadcast, "CreateNewSlice", landscape_canvas.id, slice_path)
# Verify if slice is created
helper.wait_for_condition(lambda: path_is_valid_asset(slice_path), 5.0)
Report.result(Tests.slice_created, path_is_valid_asset(slice_path))
# Instantiate slice
transform = math.Transform_CreateIdentity()
asset_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", slice_path, math.Uuid(), False)
test_slice = slice.SliceRequestBus(bus.Broadcast, "InstantiateSliceFromAssetId", asset_id, transform)
helper.wait_for_condition(lambda: test_slice.IsValid(), 5.0)
Report.result(Tests.slice_instantiated, test_slice.IsValid())
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(Slice_CreateInstantiate)
@@ -5,210 +5,217 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import os
import sys
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.editor.graph as graph
import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.legacy.general as general
import azlmbr.math as math
import azlmbr.paths
class Tests:
lc_tool_opened = (
"Landscape Canvas tool opened",
"Failed to open Landscape Canvas tool"
)
new_graph_created = (
"Successfully created new graph",
"Failed to create new graph"
)
graph_registered = (
"Graph registered with Landscape Canvas",
"Failed to register graph"
)
preview_entity_set = (
"Random Noise Gradient component Preview Entity property set to Box Shape EntityId",
"Unexpected entity set in Random Noise Gradient Preview Entity property"
)
dither_inbound_gradient_set = (
"Dither Gradient Modifier component Inbound Gradient property set to Random Noise Gradient EntityId",
"Unexpected entity set in Dither Gradient's Inbound Gradient property"
)
mixer_inbound_gradient_set = (
"Gradient Mixer component Inbound Gradient extendable property set to Dither Gradient Modifier EntityId",
"Unexpected entity set in Gradient Mixer's Inbound Gradient property"
)
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.editor_test_helper import EditorTestHelper
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
newEntityId = None
class TestSlotConnectionsUpdateComponents(EditorTestHelper):
def __init__(self):
EditorTestHelper.__init__(self, log_prefix="SlotConnectionsUpdateComponents", args=["level"])
def SlotConnections_UpdateComponentReferences():
"""
Summary:
This test verifies that the Landscape Canvas slot connections properly update component references.
def run_test(self):
"""
Summary:
This test verifies that the Landscape Canvas slot connections properly update component references.
Expected Behavior:
A reference created through slot connections in Landscape Canvas is reflected in the Entity Inspector.
Expected Behavior:
A reference created through slot connections in Landscape Canvas is reflected in the Entity Inspector.
Test Steps:
1) Open an existing level
2) Open Landscape Canvas and create a new graph
3) Several nodes are added to a graph, and connections are set between the nodes
4) Component references are verified via Entity Inspector
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create a new graph
3) Several nodes are added to a graph, and connections are set between the nodes
4) Component references are verified via Entity Inspector
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.editor.graph as graph
import azlmbr.landscapecanvas as landscapecanvas
import azlmbr.legacy.general as general
import azlmbr.math as math
import azlmbr.paths
:return: None
"""
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
# Retrieve the proper component TypeIds per component name
componentNames = [
'Random Noise Gradient',
'Dither Gradient Modifier',
'Gradient Mixer'
]
componentTypeIds = hydra.get_component_type_id_map(componentNames)
# Helper method for retrieving an EntityId from a specific property on a component
def getEntityIdFromComponentProperty(targetEntityId, componentTypeName, propertyPath):
componentOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', targetEntityId,
componentTypeIds[componentTypeName])
if not componentOutcome.IsSuccess():
return None
component = componentOutcome.GetValue()
propertyOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentProperty', component,
propertyPath)
if not propertyOutcome.IsSuccess():
return None
return propertyOutcome.GetValue()
def onEntityCreated(parameters):
global newEntityId
newEntityId = parameters[0]
# Create a new empty level
self.test_success = self.create_level(
self.args["level"],
heightmap_resolution=128,
heightmap_meters_per_pixel=1,
terrain_texture_resolution=128,
use_terrain=False,
)
# Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas')
self.test_success = self.test_success and general.is_pane_visible('Landscape Canvas')
if general.is_pane_visible('Landscape Canvas'):
self.log('Landscape Canvas pane is open')
# Create a new graph in Landscape Canvas
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
self.test_success = self.test_success and newGraphId
if newGraphId:
self.log("New graph created")
# Make sure the graph we created is in Landscape Canvas
success = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
self.test_success = self.test_success and success
if success:
self.log("Graph registered with Landscape Canvas")
# Listen for entity creation notifications so we can verify the component EntityId
# references are set correctly when connecting slots on the nodes
handler = editor.EditorEntityContextNotificationBusHandler()
handler.connect()
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
positionX = 10.0
positionY = 10.0
offsetX = 340.0
offsetY = 100.0
# Add a box shape node to the graph
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
boxShapeNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
newGraph, 'BoxShapeNode')
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, boxShapeNode, math.Vector2(positionX,
positionY))
boxShapeEntityId = newEntityId
positionX += offsetX
positionY += offsetY
# Add a random noise gradient node to the graph
randomNoiseNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
newGraph, 'RandomNoiseGradientNode')
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, randomNoiseNode, math.Vector2(positionX,
positionY))
randomNoiseEntityId = newEntityId
positionX += offsetX
positionY += offsetY
# Add a dither gradient modifier node to the graph
ditherNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
newGraph, 'DitherGradientModifierNode')
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, ditherNode, math.Vector2(positionX,
positionY))
ditherEntityId = newEntityId
positionX += offsetX
positionY += offsetY
# Add a gradient mixer node to the graph
gradientMixerNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
newGraph, 'GradientMixerNode')
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, gradientMixerNode, math.Vector2(positionX,
positionY))
gradientMixerEntityId = newEntityId
boundsSlotId = graph.GraphModelSlotId('Bounds')
previewBoundsSlotId = graph.GraphModelSlotId('PreviewBounds')
inboundGradientSlotId = graph.GraphModelSlotId('InboundGradient')
outboundGradientSlotId = graph.GraphModelSlotId('OutboundGradient')
# Connect slots on our nodes to test all slot types like so:
# Shape -> Gradient -> Gradient Modifier -> Gradient Mixer
#
# Which tests the following slot types:
# * Shape -> Preview Bounds
# * Gradient Output -> Gradient Modifier
# * Gradient Output -> Gradient Mixer (extendable slots)
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, boxShapeNode, boundsSlotId,
randomNoiseNode, previewBoundsSlotId)
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, randomNoiseNode,
outboundGradientSlotId, ditherNode, inboundGradientSlotId)
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, ditherNode,
outboundGradientSlotId, gradientMixerNode, inboundGradientSlotId)
# Delay to allow all the underlying component properties to be updated after the slot connections are made
general.idle_wait(1.0)
# Verify the Preview EntityId property on our Random Noise Gradient component has been set to our Box Shape's
# EntityId
previewEntityId = getEntityIdFromComponentProperty(randomNoiseEntityId, 'Random Noise Gradient',
'Preview Settings|Pin Preview to Shape')
random_gradient_success = previewEntityId and boxShapeEntityId.invoke("Equal", previewEntityId)
self.test_success = self.test_success and random_gradient_success
if random_gradient_success:
self.log("Random Noise Gradient component Preview Entity property set to Box Shape EntityId")
# Verify the Inbound Gradient EntityId property on our Dither Gradient Modifier component has been set to our
# Random Noise Gradient's EntityId
inboundGradientEntityId = getEntityIdFromComponentProperty(ditherEntityId, 'Dither Gradient Modifier',
'Configuration|Gradient|Gradient Entity Id')
dither_gradient_success = inboundGradientEntityId and randomNoiseEntityId.invoke("Equal",
inboundGradientEntityId)
self.test_success = self.test_success and dither_gradient_success
if dither_gradient_success:
self.log("Dither Gradient Modifier component Inbound Gradient property set to Random Noise Gradient "
"EntityId")
# Verify the Inbound Gradient Mixer EntityId property on our Gradient Mixer component has been set to our
# Dither Gradient Modifier's EntityId
inboundGradientMixerEntityId = getEntityIdFromComponentProperty(gradientMixerEntityId, 'Gradient Mixer',
'Configuration|Layers|[0]|Gradient|Gradient Entity Id')
gradient_mixer_success = inboundGradientMixerEntityId and ditherEntityId.invoke("Equal",
inboundGradientMixerEntityId)
self.test_success = self.test_success and gradient_mixer_success
if gradient_mixer_success:
self.log("Gradient Mixer component Inbound Gradient extendable property set to Dither Gradient Modifier "
"EntityId")
# Stop listening for entity creation notifications
handler.disconnect()
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
test = TestSlotConnectionsUpdateComponents()
test.run()
# Retrieve the proper component TypeIds per component name
componentNames = [
'Random Noise Gradient',
'Dither Gradient Modifier',
'Gradient Mixer'
]
componentTypeIds = hydra.get_component_type_id_map(componentNames)
# Helper method for retrieving an EntityId from a specific property on a component
def getEntityIdFromComponentProperty(targetEntityId, componentTypeName, propertyPath):
componentOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', targetEntityId,
componentTypeIds[componentTypeName])
if not componentOutcome.IsSuccess():
return None
component = componentOutcome.GetValue()
propertyOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentProperty', component,
propertyPath)
if not propertyOutcome.IsSuccess():
return None
return propertyOutcome.GetValue()
def onEntityCreated(parameters):
global newEntityId
newEntityId = parameters[0]
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
# Open Landscape Canvas tool and verify
general.open_pane('Landscape Canvas')
Report.critical_result(Tests.lc_tool_opened, general.is_pane_visible('Landscape Canvas'))
# Create a new graph in Landscape Canvas
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
Report.critical_result(Tests.new_graph_created, newGraphId is not None)
# Make sure the graph we created is in Landscape Canvas
graph_registered = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
Report.result(Tests.graph_registered, graph_registered)
# Listen for entity creation notifications so we can verify the component EntityId
# references are set correctly when connecting slots on the nodes
handler = editor.EditorEntityContextNotificationBusHandler()
handler.connect()
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
positionX = 10.0
positionY = 10.0
offsetX = 340.0
offsetY = 100.0
# Add a box shape node to the graph
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
boxShapeNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
newGraph, 'BoxShapeNode')
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, boxShapeNode, math.Vector2(positionX,
positionY))
boxShapeEntityId = newEntityId
positionX += offsetX
positionY += offsetY
# Add a random noise gradient node to the graph
randomNoiseNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
newGraph, 'RandomNoiseGradientNode')
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, randomNoiseNode, math.Vector2(positionX,
positionY))
randomNoiseEntityId = newEntityId
positionX += offsetX
positionY += offsetY
# Add a dither gradient modifier node to the graph
ditherNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
newGraph, 'DitherGradientModifierNode')
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, ditherNode, math.Vector2(positionX,
positionY))
ditherEntityId = newEntityId
positionX += offsetX
positionY += offsetY
# Add a gradient mixer node to the graph
gradientMixerNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
newGraph, 'GradientMixerNode')
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, gradientMixerNode, math.Vector2(positionX,
positionY))
gradientMixerEntityId = newEntityId
boundsSlotId = graph.GraphModelSlotId('Bounds')
previewBoundsSlotId = graph.GraphModelSlotId('PreviewBounds')
inboundGradientSlotId = graph.GraphModelSlotId('InboundGradient')
outboundGradientSlotId = graph.GraphModelSlotId('OutboundGradient')
# Connect slots on our nodes to test all slot types like so:
# Shape -> Gradient -> Gradient Modifier -> Gradient Mixer
#
# Which tests the following slot types:
# * Shape -> Preview Bounds
# * Gradient Output -> Gradient Modifier
# * Gradient Output -> Gradient Mixer (extendable slots)
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, boxShapeNode, boundsSlotId,
randomNoiseNode, previewBoundsSlotId)
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, randomNoiseNode,
outboundGradientSlotId, ditherNode, inboundGradientSlotId)
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, ditherNode,
outboundGradientSlotId, gradientMixerNode, inboundGradientSlotId)
# Delay to allow all the underlying component properties to be updated after the slot connections are made
general.idle_wait(1.0)
# Verify the Preview EntityId property on our Random Noise Gradient component has been set to our Box Shape's
# EntityId
previewEntityId = getEntityIdFromComponentProperty(randomNoiseEntityId, 'Random Noise Gradient',
'Preview Settings|Pin Preview to Shape')
random_gradient_success = previewEntityId and boxShapeEntityId.invoke("Equal", previewEntityId)
Report.result(Tests.preview_entity_set, random_gradient_success)
# Verify the Inbound Gradient EntityId property on our Dither Gradient Modifier component has been set to our
# Random Noise Gradient's EntityId
inboundGradientEntityId = getEntityIdFromComponentProperty(ditherEntityId, 'Dither Gradient Modifier',
'Configuration|Gradient|Gradient Entity Id')
dither_gradient_success = inboundGradientEntityId and randomNoiseEntityId.invoke("Equal",
inboundGradientEntityId)
Report.result(Tests.dither_inbound_gradient_set, dither_gradient_success)
# Verify the Inbound Gradient Mixer EntityId property on our Gradient Mixer component has been set to our
# Dither Gradient Modifier's EntityId
inboundGradientMixerEntityId = getEntityIdFromComponentProperty(gradientMixerEntityId, 'Gradient Mixer',
'Configuration|Layers|[0]|Gradient|Gradient Entity Id')
gradient_mixer_success = inboundGradientMixerEntityId and ditherEntityId.invoke("Equal",
inboundGradientMixerEntityId)
Report.result(Tests.mixer_inbound_gradient_set, gradient_mixer_success)
# Stop listening for entity creation notifications
handler.disconnect()
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(SlotConnections_UpdateComponentReferences)
@@ -0,0 +1,29 @@
"""
Copyright (c) Contributors to the Open 3D Engine Project.
For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import os
import pytest
import sys
import ly_test_tools.environment.file_system as file_system
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../../automatedtesting_shared')
from base import TestAutomationBase
@pytest.mark.SUITE_main
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
@pytest.mark.parametrize("project", ["AutomatedTesting"])
class TestAutomation(TestAutomationBase):
def test_LandscapeCanvas_SlotConnections_UpdateComponentReferences(self, request, workspace, editor, launcher_platform):
from .EditorScripts import SlotConnections_UpdateComponentReferences as test_module
self._run_test(request, workspace, editor, test_module)
def test_LandscapeCanvas_GradientMixer_NodeConstruction(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientMixer_NodeConstruction as test_module
self._run_test(request, workspace, editor, test_module)
@@ -0,0 +1,22 @@
"""
Copyright (c) Contributors to the Open 3D Engine Project.
For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import pytest
from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite
@pytest.mark.SUITE_periodic
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
@pytest.mark.parametrize("project", ["AutomatedTesting"])
class TestAutomation(EditorTestSuite):
class test_LandscapeCanvas_SlotConnections_UpdateComponentReferences(EditorSharedTest):
from .EditorScripts import SlotConnections_UpdateComponentReferences as test_module
class test_LandscapeCanvas_GradientMixer_NodeConstruction(EditorSharedTest):
from .EditorScripts import GradientMixer_NodeConstruction as test_module
@@ -0,0 +1,121 @@
"""
Copyright (c) Contributors to the Open 3D Engine Project.
For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import os
import pytest
import sys
import ly_test_tools.environment.file_system as file_system
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../../automatedtesting_shared')
from base import TestAutomationBase
@pytest.fixture
def remove_test_slice(request, workspace, project):
file_system.delete([os.path.join(workspace.paths.engine_root(), project, "slices", "TestSlice.slice")], True, True)
def teardown():
file_system.delete([os.path.join(workspace.paths.engine_root(), project, "slices", "TestSlice.slice")], True,
True)
request.addfinalizer(teardown)
@pytest.mark.SUITE_periodic
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
@pytest.mark.parametrize("project", ["AutomatedTesting"])
class TestAutomation(TestAutomationBase):
def test_LandscapeCanvas_AreaNodes_DependentComponentsAdded(self, request, workspace, editor, launcher_platform):
from .EditorScripts import AreaNodes_DependentComponentsAdded as test_module
self._run_test(request, workspace, editor, test_module)
def test_LandscapeCanvas_AreaNodes_EntityCreatedOnNodeAdd(self, request, workspace, editor, launcher_platform):
from .EditorScripts import AreaNodes_EntityCreatedOnNodeAdd as test_module
self._run_test(request, workspace, editor, test_module)
def test_LandscapeCanvas_AreaNodes_EntityRemovedOnNodeDelete(self, request, workspace, editor, launcher_platform):
from .EditorScripts import AreaNodes_EntityRemovedOnNodeDelete as test_module
self._run_test(request, workspace, editor, test_module)
def test_LandscapeCanvas_LayerExtenderNodes_ComponentEntitySync(self, request, workspace, editor, launcher_platform):
from .EditorScripts import LayerExtenderNodes_ComponentEntitySync as test_module
self._run_test(request, workspace, editor, test_module)
def test_LandscapeCanvas_Edit_DisabledNodeDuplication(self, request, workspace, editor, launcher_platform):
from .EditorScripts import Edit_DisabledNodeDuplication as test_module
self._run_test(request, workspace, editor, test_module)
def test_LandscapeCanvas_Edit_UndoNodeDelete_SliceEntity(self, request, workspace, editor, launcher_platform):
from .EditorScripts import Edit_UndoNodeDelete_SliceEntity as test_module
self._run_test(request, workspace, editor, test_module)
def test_LandscapeCanvas_NewGraph_CreatedSuccessfully(self, request, workspace, editor, launcher_platform):
from .EditorScripts import NewGraph_CreatedSuccessfully as test_module
self._run_test(request, workspace, editor, test_module)
def test_LandscapeCanvas_Component_AddedRemoved(self, request, workspace, editor, launcher_platform):
from .EditorScripts import Component_AddedRemoved as test_module
self._run_test(request, workspace, editor, test_module)
def test_LandscapeCanvas_GraphClosed_OnLevelChange(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GraphClosed_OnLevelChange as test_module
self._run_test(request, workspace, editor, test_module)
@pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/2201")
def test_LandscapeCanvas_GraphClosed_OnEntityDelete(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GraphClosed_OnEntityDelete as test_module
self._run_test(request, workspace, editor, test_module)
def test_LandscapeCanvas_GraphClosed_TabbedGraphClosesIndependently(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GraphClosed_TabbedGraph as test_module
self._run_test(request, workspace, editor, test_module)
def test_LandscapeCanvas_Slice_CreateInstantiate(self, request, workspace, editor, remove_test_slice, launcher_platform):
from .EditorScripts import Slice_CreateInstantiate as test_module
self._run_test(request, workspace, editor, test_module)
def test_LandscapeCanvas_GradientModifierNodes_EntityCreatedOnNodeAdd(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientModifierNodes_EntityCreatedOnNodeAdd as test_module
self._run_test(request, workspace, editor, test_module)
def test_LandscapeCanvas_GradientModifierNodes_EntityRemovedOnNodeDelete(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientModifierNodes_EntityRemovedOnNodeDelete as test_module
self._run_test(request, workspace, editor, test_module)
def test_LandscapeCanvas_GradientNodes_DependentComponentsAdded(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientNodes_DependentComponentsAdded as test_module
self._run_test(request, workspace, editor, test_module)
def test_LandscapeCanvas_GradientNodes_EntityCreatedOnNodeAdd(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientNodes_EntityCreatedOnNodeAdd as test_module
self._run_test(request, workspace, editor, test_module)
def test_LandscapeCanvas_GradientNodes_EntityRemovedOnNodeDelete(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientNodes_EntityRemovedOnNodeDelete as test_module
self._run_test(request, workspace, editor, test_module)
def test_LandscapeCanvas_GraphUpdates_UpdateComponents(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GraphUpdates_UpdateComponents as test_module
self._run_test(request, workspace, editor, test_module)
def test_LandscapeCanvas_ComponentUpdates_UpdateGraph(self, request, workspace, editor, launcher_platform):
from .EditorScripts import ComponentUpdates_UpdateGraph as test_module
self._run_test(request, workspace, editor, test_module)
def test_LandscapeCanvas_LayerBlender_NodeConstruction(self, request, workspace, editor, launcher_platform):
from .EditorScripts import LayerBlender_NodeConstruction as test_module
self._run_test(request, workspace, editor, test_module)
def test_LandscapeCanvas_ShapeNodes_EntityCreatedOnNodeAdd(self, request, workspace, editor, launcher_platform):
from .EditorScripts import ShapeNodes_EntityCreatedOnNodeAdd as test_module
self._run_test(request, workspace, editor, test_module)
def test_LandscapeCanvas_ShapeNodes_EntityRemovedOnNodeDelete(self, request, workspace, editor, launcher_platform):
from .EditorScripts import ShapeNodes_EntityRemovedOnNodeDelete as test_module
self._run_test(request, workspace, editor, test_module)
@@ -0,0 +1,89 @@
"""
Copyright (c) Contributors to the Open 3D Engine Project.
For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import os
import pytest
import ly_test_tools.environment.file_system as file_system
from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite
@pytest.mark.SUITE_periodic
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
@pytest.mark.parametrize("project", ["AutomatedTesting"])
class TestAutomation(EditorTestSuite):
class test_LandscapeCanvas_AreaNodes_DependentComponentsAdded(EditorSharedTest):
from .EditorScripts import AreaNodes_DependentComponentsAdded as test_module
class test_LandscapeCanvas_AreaNodes_EntityCreatedOnNodeAdd(EditorSharedTest):
from .EditorScripts import AreaNodes_EntityCreatedOnNodeAdd as test_module
class test_LandscapeCanvas_AreaNodes_EntityRemovedOnNodeDelete(EditorSharedTest):
from .EditorScripts import AreaNodes_EntityRemovedOnNodeDelete as test_module
class test_LandscapeCanvas_LayerExtenderNodes_ComponentEntitySync(EditorSharedTest):
from .EditorScripts import LayerExtenderNodes_ComponentEntitySync as test_module
class test_LandscapeCanvas_Edit_DisabledNodeDuplication(EditorSharedTest):
from .EditorScripts import Edit_DisabledNodeDuplication as test_module
class test_LandscapeCanvas_Edit_UndoNodeDelete_SliceEntity(EditorSharedTest):
from .EditorScripts import Edit_UndoNodeDelete_SliceEntity as test_module
class test_LandscapeCanvas_NewGraph_CreatedSuccessfully(EditorSharedTest):
from .EditorScripts import NewGraph_CreatedSuccessfully as test_module
class test_LandscapeCanvas_Component_AddedRemoved(EditorSharedTest):
from .EditorScripts import Component_AddedRemoved as test_module
class test_LandscapeCanvas_GraphClosed_OnLevelChange(EditorSharedTest):
from .EditorScripts import GraphClosed_OnLevelChange as test_module
@pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/2201")
class test_LandscapeCanvas_GraphClosed_OnEntityDelete(EditorSharedTest):
from .EditorScripts import GraphClosed_OnEntityDelete as test_module
class test_LandscapeCanvas_GraphClosed_TabbedGraphClosesIndependently(EditorSharedTest):
from .EditorScripts import GraphClosed_TabbedGraph as test_module
class test_LandscapeCanvas_Slice_CreateInstantiate(EditorSingleTest):
# Custom teardown to remove slice asset created during test
def teardown(self, request, workspace, editor, editor_test_results, launcher_platform):
file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "slices",
"TestSlice.slice")], True, True)
from .EditorScripts import Slice_CreateInstantiate as test_module
class test_LandscapeCanvas_GradientModifierNodes_EntityCreatedOnNodeAdd(EditorSharedTest):
from .EditorScripts import GradientModifierNodes_EntityCreatedOnNodeAdd as test_module
class test_LandscapeCanvas_GradientModifierNodes_EntityRemovedOnNodeDelete(EditorSharedTest):
from .EditorScripts import GradientModifierNodes_EntityRemovedOnNodeDelete as test_module
class test_LandscapeCanvas_GradientNodes_DependentComponentsAdded(EditorSharedTest):
from .EditorScripts import GradientNodes_DependentComponentsAdded as test_module
class test_LandscapeCanvas_GradientNodes_EntityCreatedOnNodeAdd(EditorSharedTest):
from .EditorScripts import GradientNodes_EntityCreatedOnNodeAdd as test_module
class test_LandscapeCanvas_GradientNodes_EntityRemovedOnNodeDelete(EditorSharedTest):
from .EditorScripts import GradientNodes_EntityRemovedOnNodeDelete as test_module
class test_LandscapeCanvas_GraphUpdates_UpdateComponents(EditorSharedTest):
from .EditorScripts import GraphUpdates_UpdateComponents as test_module
class test_LandscapeCanvas_ComponentUpdates_UpdateGraph(EditorSharedTest):
from .EditorScripts import ComponentUpdates_UpdateGraph as test_module
class test_LandscapeCanvas_LayerBlender_NodeConstruction(EditorSharedTest):
from .EditorScripts import LayerBlender_NodeConstruction as test_module
class test_LandscapeCanvas_ShapeNodes_EntityCreatedOnNodeAdd(EditorSharedTest):
from .EditorScripts import ShapeNodes_EntityCreatedOnNodeAdd as test_module
class test_LandscapeCanvas_ShapeNodes_EntityRemovedOnNodeDelete(EditorSharedTest):
from .EditorScripts import ShapeNodes_EntityRemovedOnNodeDelete as test_module