Merge remote-tracking branch 'upstream/development' into nvsickle/GenericDomJson

This commit is contained in:
Nicholas Van Sickle
2021-11-29 09:40:56 -08:00
2916 changed files with 268517 additions and 32443 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
---
name: ar_bug_report.md
name: Automated Review bug report
about: Create a bug for a an issue found in the Automated Review
title: 'AR Bug Report'
labels: 'needs-triage,kind/bug,kind/automation'
+1 -1
View File
@@ -3,7 +3,7 @@
.vscode/
__pycache__
AssetProcessorTemp/**
[Bb]uild/**
[Bb]uild/
[Oo]ut/**
CMakeUserPresets.json
[Cc]ache/
@@ -62164,7 +62164,7 @@ An Entity can be selected by using the pick button, or by dragging an Entity fro
<message id="HANDLER_TAGGLOBALNOTIFICATIONBUS_ONENTITYTAGADDED_OUTPUT0_NAME">
<source>HANDLER_TAGGLOBALNOTIFICATIONBUS_ONENTITYTAGADDED_OUTPUT0_NAME</source>
<comment>Simple Type: EntityID C++ Type: const EntityId&amp;</comment>
<translation type="unfinished">Entity</translation>
<translation type="unfinished">EntityID</translation>
</message>
<message id="HANDLER_TAGGLOBALNOTIFICATIONBUS_ONENTITYTAGADDED_OUTPUT0_TOOLTIP">
<source>HANDLER_TAGGLOBALNOTIFICATIONBUS_ONENTITYTAGADDED_OUTPUT0_TOOLTIP</source>
@@ -62202,7 +62202,7 @@ An Entity can be selected by using the pick button, or by dragging an Entity fro
<message id="HANDLER_TAGGLOBALNOTIFICATIONBUS_ONENTITYTAGREMOVED_OUTPUT0_NAME">
<source>HANDLER_TAGGLOBALNOTIFICATIONBUS_ONENTITYTAGREMOVED_OUTPUT0_NAME</source>
<comment>Simple Type: EntityID C++ Type: const EntityId&amp;</comment>
<translation type="unfinished">Entity</translation>
<translation type="unfinished">EntityId</translation>
</message>
<message id="HANDLER_TAGGLOBALNOTIFICATIONBUS_ONENTITYTAGREMOVED_OUTPUT0_TOOLTIP">
<source>HANDLER_TAGGLOBALNOTIFICATIONBUS_ONENTITYTAGREMOVED_OUTPUT0_TOOLTIP</source>
@@ -81852,7 +81852,7 @@ The element is removed from its current parent and added as a child of the new p
<message id="HANDLER_SPAWNERCOMPONENTNOTIFICATIONBUS_ONENTITYSPAWNED_OUTPUT1_NAME">
<source>HANDLER_SPAWNERCOMPONENTNOTIFICATIONBUS_ONENTITYSPAWNED_OUTPUT1_NAME</source>
<comment>Simple Type: EntityID C++ Type: const EntityId&amp;</comment>
<translation type="unfinished">Entity</translation>
<translation type="unfinished">EntityID</translation>
</message>
<message id="HANDLER_SPAWNERCOMPONENTNOTIFICATIONBUS_ONENTITYSPAWNED_OUTPUT1_TOOLTIP">
<source>HANDLER_SPAWNERCOMPONENTNOTIFICATIONBUS_ONENTITYSPAWNED_OUTPUT1_TOOLTIP</source>
@@ -89198,7 +89198,7 @@ The element is removed from its current parent and added as a child of the new p
<message id="HANDLER_ENTITYBUS_ONENTITYACTIVATED_OUTPUT0_NAME">
<source>HANDLER_ENTITYBUS_ONENTITYACTIVATED_OUTPUT0_NAME</source>
<comment>Simple Type: EntityID C++ Type: const EntityId&amp;</comment>
<translation type="unfinished">Entity</translation>
<translation type="unfinished">EntityID</translation>
</message>
<message id="HANDLER_ENTITYBUS_ONENTITYACTIVATED_OUTPUT0_TOOLTIP">
<source>HANDLER_ENTITYBUS_ONENTITYACTIVATED_OUTPUT0_TOOLTIP</source>
@@ -89236,7 +89236,7 @@ The element is removed from its current parent and added as a child of the new p
<message id="HANDLER_ENTITYBUS_ONENTITYDEACTIVATED_OUTPUT0_NAME">
<source>HANDLER_ENTITYBUS_ONENTITYDEACTIVATED_OUTPUT0_NAME</source>
<comment>Simple Type: EntityID C++ Type: const EntityId&amp;</comment>
<translation type="unfinished">Entity</translation>
<translation type="unfinished">EntityID</translation>
</message>
<message id="HANDLER_ENTITYBUS_ONENTITYDEACTIVATED_OUTPUT0_TOOLTIP">
<source>HANDLER_ENTITYBUS_ONENTITYDEACTIVATED_OUTPUT0_TOOLTIP</source>
@@ -145,7 +145,7 @@
<Class name="float" field="ProjectorNearPlane" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}" value="0.0000000" specializationTypeId="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
<Class name="AzFramework::SimpleAssetReference&lt;LmbrCentral::TextureAsset&gt;" field="ProjectorTexture" type="{68E92460-5C0C-4031-9620-6F1A08763243}" version="1" specializationTypeId="{68E92460-5C0C-4031-9620-6F1A08763243}">
<Class name="SimpleAssetReferenceBase" field="BaseClass1" type="{E16CA6C5-5C78-4AD9-8E9B-F8C1FB4D1DB8}" version="1" specializationTypeId="{E16CA6C5-5C78-4AD9-8E9B-F8C1FB4D1DB8}">
<Class name="AZStd::string" field="AssetPath" type="{EF8FF807-DDEE-4EB0-B678-4CA3A2C490A4}" value="engineassets/textures/defaults/spot_default.dds" specializationTypeId="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="AssetPath" type="{EF8FF807-DDEE-4EB0-B678-4CA3A2C490A4}" value="" specializationTypeId="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
</Class>
</Class>
<Class name="AzFramework::SimpleAssetReference&lt;LmbrCentral::MaterialAsset&gt;" field="ProjectorMaterial" type="{B7B8ECC7-FF89-4A76-A50E-4C6CA2B6E6B4}" version="1" specializationTypeId="{B7B8ECC7-FF89-4A76-A50E-4C6CA2B6E6B4}">
-3
View File
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:cf441215a769562f88aa20711aee68dadcbf02597d1e2270547055e8e6aec6a3
size 77
@@ -1,178 +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
--
--
--
----------------------------------------------------------------------------------------------------
Script.ReloadScript("scripts/Utils/EntityUtils.lua")
GeomCache =
{
Properties = {
geomcacheFile = "EngineAssets/GeomCaches/defaultGeomCache.cax",
bPlaying = 0,
fStartTime = 0,
bLooping = 0,
objectStandIn = "",
materialStandInMaterial = "",
objectFirstFrameStandIn = "",
materialFirstFrameStandInMaterial = "",
objectLastFrameStandIn = "",
materialLastFrameStandInMaterial = "",
fStandInDistance = 0,
fStreamInDistance = 0,
Physics = {
bPhysicalize = 0,
}
},
Editor={
Icon = "animobject.bmp",
IconOnTop = 1,
},
bPlaying = 0,
currentTime = 0,
precacheTime = 0,
bPrecachedOutputTriggered = false,
}
function GeomCache:OnLoad(table)
self.currentTime = table.currentTime;
end
function GeomCache:OnSave(table)
table.currentTime = self.currentTime;
end
function GeomCache:OnSpawn()
self.currentTime = self.Properties.fStartTime;
self:SetFromProperties();
end
function GeomCache:OnReset()
self.currentTime = self.Properties.fStartTime;
self.bPrecachedOutputTriggered = true;
self:SetFromProperties();
end
function GeomCache:SetFromProperties()
local Properties = self.Properties;
if (Properties.geomcacheFile == "") then
do return end;
end
self:LoadGeomCache(0, Properties.geomcacheFile);
self.bPlaying = Properties.bPlaying;
if (self.bPlaying == 0) then
self.currentTime = Properties.fStartTime;
end
self:SetGeomCachePlaybackTime(self.currentTime);
self:SetGeomCacheParams(Properties.bLooping, Properties.objectStandIn, Properties.materialStandInMaterial, Properties.objectFirstFrameStandIn,
Properties.materialFirstFrameStandInMaterial, Properties.objectLastFrameStandIn, Properties.materialLastFrameStandInMaterial,
Properties.fStandInDistance, Properties.fStreamInDistance);
self:SetGeomCacheStreaming(false, 0);
if (Properties.Physics.bPhysicalize == 1) then
local tempPhysParams = EntityCommon.TempPhysParams;
self:Physicalize(0, PE_ARTICULATED, tempPhysParams);
end
self:Activate(1);
end
function GeomCache:PhysicalizeThis()
local Physics = self.Properties.Physics;
EntityCommon.PhysicalizeRigid(self, 0, Physics, false);
end
function GeomCache:OnUpdate(dt)
if (self.bPlaying == 1) then
self:SetGeomCachePlaybackTime(self.currentTime);
end
if (self:IsGeomCacheStreaming() and not self.bPrecachedOutputTriggered) then
local precachedTime = self:GetGeomCachePrecachedTime();
if (precachedTime >= self.precacheTime) then
self:ActivateOutput("Precached", true);
self.bPrecachedOutputTriggered = true;
end
end
if (self.bPlaying == 1) then
self.currentTime = self.currentTime + dt;
end
end
function GeomCache:OnPropertyChange()
self:SetFromProperties();
end
function GeomCache:Event_Start(sender, val)
self.bPlaying = 1;
end
function GeomCache:Event_Stop(sender, value)
self.bPlaying = 0;
end
function GeomCache:Event_SetTime(sender, value)
self.currentTime = value;
end
function GeomCache:Event_StartStreaming(sender, value)
self.bPrecachedOutputTriggered = false;
self:SetGeomCacheStreaming(true, self.currentTime);
end
function GeomCache:Event_StopStreaming(sender, value)
self:SetGeomCacheStreaming(false, 0);
end
function GeomCache:Event_PrecacheTime(sender, value)
self.precacheTime = value;
end
function GeomCache:Event_Hide(sender, value)
self:Hide(1);
end
function GeomCache:Event_Unhide(sender, value)
self:Hide(0);
end
function GeomCache:Event_StopDrawing(sender, value)
self:SetGeomCacheDrawing(false);
end
function GeomCache:Event_StartDrawing(sender, value)
self:SetGeomCacheDrawing(true);
end
GeomCache.FlowEvents =
{
Inputs =
{
Start = { GeomCache.Event_Start, "any" },
Stop = { GeomCache.Event_Stop, "any" },
SetTime = { GeomCache.Event_SetTime, "float" },
StartStreaming = { GeomCache.Event_StartStreaming, "any" },
StopStreaming = { GeomCache.Event_StopStreaming, "any" },
PrecacheTime = { GeomCache.Event_PrecacheTime, "float" },
Hide = { GeomCache.Event_Hide, "any" },
Unhide = { GeomCache.Event_Unhide, "any" },
StopDrawing = { GeomCache.Event_StopDrawing, "any" },
StartDrawing = { GeomCache.Event_StartDrawing, "any" },
},
Outputs =
{
Precached = "bool",
},
}
+2 -1
View File
@@ -8,11 +8,12 @@
if(NOT PROJECT_NAME)
cmake_minimum_required(VERSION 3.20)
include(cmake/CompilerSettings.cmake)
project(AutomatedTesting
LANGUAGES C CXX
VERSION 1.0.0.0
)
include(EngineFinder.cmake OPTIONAL)
include(cmake/EngineFinder.cmake OPTIONAL)
find_package(o3de REQUIRED)
o3de_initialize()
else()
@@ -13,4 +13,29 @@
<NetworkInput Type="float" Name="FwdBack" Init="0.0f" ExposeToScript="true"/>
<NetworkInput Type="float" Name="LeftRight" Init="0.0f" ExposeToScript="true"/>
<RemoteProcedure Name="AutonomousToAuthority" InvokeFrom="Autonomous" HandleOn="Authority" IsPublic="false" IsReliable="false" GenerateEventBindings="true" Description="" >
<Param Type="float" Name="SomeFloat" />
</RemoteProcedure>
<RemoteProcedure Name="AutonomousToAuthorityNoParams" InvokeFrom="Autonomous" HandleOn="Authority" IsPublic="false" IsReliable="false" GenerateEventBindings="true" Description="" />
<RemoteProcedure Name="AuthorityToAutonomous" InvokeFrom="Authority" HandleOn="Autonomous" IsPublic="false" IsReliable="false" GenerateEventBindings="true" Description="" >
<Param Type="float" Name="SomeFloat" />
</RemoteProcedure>
<RemoteProcedure Name="AuthorityToAutonomousNoParams" InvokeFrom="Authority" HandleOn="Autonomous" IsPublic="false" IsReliable="false" GenerateEventBindings="true" Description="" />
<RemoteProcedure Name="AuthorityToClient" InvokeFrom="Authority" HandleOn="Client" IsPublic="false" IsReliable="false" GenerateEventBindings="true" Description="" >
<Param Type="float" Name="SomeFloat" />
</RemoteProcedure>
<RemoteProcedure Name="AuthorityToClientNoParams" InvokeFrom="Authority" HandleOn="Client" IsPublic="false" IsReliable="false" GenerateEventBindings="true" Description="" />
<RemoteProcedure Name="ServerToAuthority" InvokeFrom="Server" HandleOn="Authority" IsPublic="false" IsReliable="false" GenerateEventBindings="true" Description="" >
<Param Type="float" Name="SomeFloat" />
</RemoteProcedure>
<RemoteProcedure Name="ServerToAuthorityNoParam" InvokeFrom="Server" HandleOn="Authority" IsPublic="false" IsReliable="false" GenerateEventBindings="true" Description="" />
</Component>
@@ -54,6 +54,7 @@ set(ENABLED_GEMS
AWSMetrics
PrefabBuilder
AudioSystem
Terrain
Profiler
Multiplayer
)
@@ -14,6 +14,7 @@ from datetime import datetime
import ly_test_tools.log.log_monitor
from AWS.common import constants
from AWS.common.resource_mappings import AWS_RESOURCE_MAPPINGS_ACCOUNT_ID_KEY
from .aws_metrics_custom_thread import AWSMetricsThread
# fixture imports
@@ -200,6 +201,59 @@ class TestAWSMetricsWindows(object):
for thread in operational_threads:
thread.join()
@pytest.mark.parametrize('level', ['AWS/Metrics'])
def test_realtime_and_batch_analytics_no_global_accountid(self,
level: str,
launcher: pytest.fixture,
asset_processor: pytest.fixture,
workspace: pytest.fixture,
aws_utils: pytest.fixture,
resource_mappings: pytest.fixture,
aws_metrics_utils: pytest.fixture):
"""
Verify that the metrics events are sent to CloudWatch and S3 for analytics.
"""
# Remove top-level account ID from resource mappings
resource_mappings.clear_select_keys([AWS_RESOURCE_MAPPINGS_ACCOUNT_ID_KEY])
# Start Kinesis analytics application on a separate thread to avoid blocking the test.
kinesis_analytics_application_thread = AWSMetricsThread(target=update_kinesis_analytics_application_status,
args=(aws_metrics_utils, resource_mappings, True))
kinesis_analytics_application_thread.start()
log_monitor = setup(launcher, asset_processor)
# Kinesis analytics application needs to be in the running state before we start the game launcher.
kinesis_analytics_application_thread.join()
launcher.args = ['+LoadLevel', level]
launcher.args.extend(['-rhi=null'])
start_time = datetime.utcnow()
with launcher.start(launch_ap=False):
monitor_metrics_submission(log_monitor)
# Verify that real-time analytics metrics are delivered to CloudWatch.
aws_metrics_utils.verify_cloud_watch_delivery(
AWS_METRICS_FEATURE_NAME,
'TotalLogins',
[],
start_time)
logger.info('Real-time metrics are sent to CloudWatch.')
# Run time-consuming operations on separate threads to avoid blocking the test.
operational_threads = list()
operational_threads.append(
AWSMetricsThread(target=query_metrics_from_s3,
args=(aws_metrics_utils, resource_mappings)))
operational_threads.append(
AWSMetricsThread(target=verify_operational_metrics,
args=(aws_metrics_utils, resource_mappings, start_time)))
operational_threads.append(
AWSMetricsThread(target=update_kinesis_analytics_application_status,
args=(aws_metrics_utils, resource_mappings, False)))
for thread in operational_threads:
thread.start()
for thread in operational_threads:
thread.join()
@pytest.mark.parametrize('level', ['AWS/Metrics'])
def test_unauthorized_user_request_rejected(self,
level: str,
@@ -12,6 +12,7 @@ import pytest
import ly_test_tools.log.log_monitor
from AWS.common import constants
from AWS.common.resource_mappings import AWS_RESOURCE_MAPPINGS_ACCOUNT_ID_KEY
# fixture imports
from assetpipeline.ap_fixtures.asset_processor_fixture import asset_processor
@@ -70,6 +71,41 @@ class TestAWSClientAuthWindows(object):
halt_on_unexpected=True,
)
assert result, 'Anonymous credentials fetched successfully.'
@pytest.mark.parametrize('level', ['AWS/ClientAuth'])
def test_anonymous_credentials_no_global_accountid(self,
level: str,
launcher: pytest.fixture,
resource_mappings: pytest.fixture,
workspace: pytest.fixture,
asset_processor: pytest.fixture
):
"""
Test to verify AWS Cognito Identity pool anonymous authorization.
Setup: Updates resource mapping file using existing CloudFormation stacks.
Tests: Getting credentials when no credentials are configured
Verification: Log monitor looks for success credentials log.
"""
# Remove top-level account ID from resource mappings
resource_mappings.clear_select_keys([AWS_RESOURCE_MAPPINGS_ACCOUNT_ID_KEY])
asset_processor.start()
asset_processor.wait_for_idle()
file_to_monitor = os.path.join(launcher.workspace.paths.project_log(), constants.GAME_LOG_NAME)
log_monitor = ly_test_tools.log.log_monitor.LogMonitor(launcher=launcher, log_file_path=file_to_monitor)
launcher.args = ['+LoadLevel', level]
launcher.args.extend(['-rhi=null'])
with launcher.start(launch_ap=False):
result = log_monitor.monitor_log_for_lines(
expected_lines=['(Script) - Success anonymous credentials'],
unexpected_lines=['(Script) - Fail anonymous credentials'],
halt_on_unexpected=True,
)
assert result, 'Anonymous credentials fetched successfully.'
def test_password_signin_credentials(self,
launcher: pytest.fixture,
@@ -18,6 +18,7 @@ import ly_test_tools.environment.process_utils as process_utils
import ly_test_tools.o3de.asset_processor_utils as asset_processor_utils
from AWS.common import constants
from AWS.common.resource_mappings import AWS_RESOURCE_MAPPINGS_ACCOUNT_ID_KEY
# fixture imports
from assetpipeline.ap_fixtures.asset_processor_fixture import asset_processor
@@ -141,3 +142,51 @@ class TestAWSCoreAWSResourceInteraction(object):
'The expected file wasn\'t successfully downloaded.'
# clean up the file directories.
shutil.rmtree(s3_download_dir)
@pytest.mark.parametrize('expected_lines', [
['(Script) - [S3] Head object request is done',
'(Script) - [S3] Head object success: Object example.txt is found.',
'(Script) - [S3] Get object success: Object example.txt is downloaded.',
'(Script) - [Lambda] Completed Invoke',
'(Script) - [Lambda] Invoke success: {"statusCode": 200, "body": {}}',
'(Script) - [DynamoDB] Results finished']])
@pytest.mark.parametrize('unexpected_lines', [
['(Script) - [S3] Head object error: No response body.',
'(Script) - [S3] Get object error: Request validation failed, output file directory doesn\'t exist.',
'(Script) - Request validation failed, output file miss full path.',
'(Script) - ']])
def test_scripting_behavior_no_global_accountid(self,
level: str,
launcher: pytest.fixture,
workspace: pytest.fixture,
asset_processor: pytest.fixture,
resource_mappings: pytest.fixture,
aws_utils: pytest.fixture,
expected_lines: typing.List[str],
unexpected_lines: typing.List[str]):
"""
Setup: Updates resource mapping file using existing CloudFormation stacks.
Tests: Interact with AWS S3, DynamoDB and Lambda services.
Verification: Script canvas nodes can communicate with AWS services successfully.
"""
resource_mappings.clear_select_keys([AWS_RESOURCE_MAPPINGS_ACCOUNT_ID_KEY])
log_monitor, s3_download_dir = setup(launcher, asset_processor)
write_test_data_to_dynamodb_table(resource_mappings, aws_utils)
launcher.args = ['+LoadLevel', level]
launcher.args.extend(['-rhi=null'])
with launcher.start(launch_ap=False):
result = log_monitor.monitor_log_for_lines(
expected_lines=expected_lines,
unexpected_lines=unexpected_lines,
halt_on_unexpected=True
)
assert result, "Expected lines weren't found."
assert os.path.exists(os.path.join(s3_download_dir, 'output.txt')), \
'The expected file wasn\'t successfully downloaded.'
# clean up the file directories.
shutil.rmtree(s3_download_dir)
@@ -102,3 +102,17 @@ class ResourceMappings:
def get_resource_name_id(self, resource_key: str):
return self._resource_mappings[AWS_RESOURCE_MAPPINGS_KEY][resource_key]['Name/ID']
def clear_select_keys(self, resource_keys=None) -> None:
"""
Clears values from select resource mapping keys.
:param resource_keys: list of keys to clear out
"""
with open(self._resource_mapping_file_path) as file_content:
resource_mappings = json.load(file_content)
for key in resource_keys:
resource_mappings[key] = ''
with open(self._resource_mapping_file_path, 'w') as file_content:
json.dump(resource_mappings, file_content, indent=4)
@@ -13,6 +13,8 @@ from ly_test_tools.o3de.editor_test import EditorSharedTest, EditorTestSuite
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
class TestAutomation(EditorTestSuite):
enable_prefab_system = False
@pytest.mark.test_case_id("C36525657")
class AtomEditorComponents_BloomAdded(EditorSharedTest):
from Atom.tests import hydra_AtomEditorComponents_BloomAdded as test_module
@@ -41,6 +43,10 @@ class TestAutomation(EditorTestSuite):
class AtomEditorComponents_DisplayMapperAdded(EditorSharedTest):
from Atom.tests import hydra_AtomEditorComponents_DisplayMapperAdded as test_module
@pytest.mark.test_case_id("C36525661")
class AtomEditorComponents_EntityReferenceAdded(EditorSharedTest):
from Atom.tests import hydra_AtomEditorComponents_EntityReferenceAdded as test_module
@pytest.mark.test_case_id("C32078121")
class AtomEditorComponents_ExposureControlAdded(EditorSharedTest):
from Atom.tests import hydra_AtomEditorComponents_ExposureControlAdded as test_module
@@ -57,10 +63,18 @@ class TestAutomation(EditorTestSuite):
class AtomEditorComponents_HDRColorGradingAdded(EditorSharedTest):
from Atom.tests import hydra_AtomEditorComponents_HDRColorGradingAdded as test_module
@pytest.mark.test_case_id("C32078116")
class AtomEditorComponents_HDRiSkyboxAdded(EditorSharedTest):
from Atom.tests import hydra_AtomEditorComponents_HDRiSkyboxAdded as test_module
@pytest.mark.test_case_id("C32078117")
class AtomEditorComponents_LightAdded(EditorSharedTest):
from Atom.tests import hydra_AtomEditorComponents_LightAdded as test_module
@pytest.mark.test_case_id("C36525662")
class AtomEditorComponents_LookModificationAdded(EditorSharedTest):
from Atom.tests import hydra_AtomEditorComponents_LookModificationAdded as test_module
@pytest.mark.test_case_id("C32078123")
class AtomEditorComponents_MaterialAdded(EditorSharedTest):
from Atom.tests import hydra_AtomEditorComponents_MaterialAdded as test_module
@@ -98,5 +112,9 @@ class TestAutomation(EditorTestSuite):
class AtomEditorComponents_ReflectionProbeAdded(EditorSharedTest):
from Atom.tests import hydra_AtomEditorComponents_ReflectionProbeAdded as test_module
@pytest.mark.test_case_id("C36525666")
class AtomEditorComponents_SSAOAdded(EditorSharedTest):
from Atom.tests import hydra_AtomEditorComponents_SSAOAdded as test_module
class ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges(EditorSharedTest):
from Atom.tests import hydra_ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges as test_module
@@ -104,6 +104,7 @@ class TestAllComponentsIndepthTests(object):
halt_on_unexpected=True,
cfg_args=[level],
null_renderer=False,
enable_prefab_system=False,
)
similarity_threshold = 0.99
@@ -158,6 +159,7 @@ class TestAllComponentsIndepthTests(object):
halt_on_unexpected=True,
cfg_args=[level],
null_renderer=False,
enable_prefab_system=False,
)
similarity_threshold = 0.99
@@ -205,6 +207,7 @@ class TestPerformanceBenchmarkSuite(object):
halt_on_unexpected=True,
cfg_args=[level],
null_renderer=False,
enable_prefab_system=False,
)
aggregator = BenchmarkDataAggregator(workspace, logger, 'periodic')
@@ -242,5 +245,6 @@ class TestMaterialEditor(object):
halt_on_unexpected=False,
null_renderer=False,
cfg_args=[cfg_args],
log_file_name="MaterialEditor.log"
log_file_name="MaterialEditor.log",
enable_prefab_system=False,
)
@@ -23,6 +23,8 @@ class TestAutomation(EditorTestSuite):
# Remove -autotest_mode from global_extra_cmdline_args since we need rendering for these tests.
global_extra_cmdline_args = ["-BatchMode"] # Default is ["-BatchMode", "-autotest_mode"]
enable_prefab_system = False
@pytest.mark.test_case_id("C34603773")
class AtomGPU_BasicLevelSetup_SetsUpLevel(EditorSharedTest):
use_null_renderer = False # Default is True
@@ -85,6 +85,7 @@ class TestAtomEditorComponentsMain(object):
halt_on_unexpected=True,
null_renderer=True,
cfg_args=cfg_args,
enable_prefab_system=False,
)
@@ -155,5 +156,6 @@ class TestMaterialEditorBasicTests(object):
halt_on_unexpected=True,
null_renderer=True,
log_file_name="MaterialEditor.log",
enable_prefab_system=False,
)
@@ -172,8 +172,7 @@ def create_basic_atom_level(level_name):
entity_position=default_position,
components=["HDRi Skybox", "Global Skylight (IBL)"],
parent_id=default_level.id)
global_skylight_asset_path = os.path.join(
"LightingPresets", "greenwich_park_02_4k_iblskyboxcm_iblspecular.exr.streamingimage")
global_skylight_asset_path = os.path.join("LightingPresets", "default_iblskyboxcm.exr.streamingimage")
global_skylight_asset_value = asset.AssetCatalogRequestBus(
bus.Broadcast, "GetAssetIdByPath", global_skylight_asset_path, math.Uuid(), False)
global_skylight.get_set_test(0, "Controller|Configuration|Cubemap Texture", global_skylight_asset_value)
@@ -57,11 +57,13 @@ class AtomComponentProperties:
def camera(property: str = 'name') -> str:
"""
Camera component properties.
- 'Field of view': Sets the value for the camera's FOV (Field of View) in degrees, i.e. 60.0
:param property: From the last element of the property tree path. Default 'name' for component name string.
:return: Full property path OR component name if no property specified.
"""
properties = {
'name': 'Camera',
'Field of view': 'Controller|Configuration|Field of view'
}
return properties[property]
@@ -202,11 +204,13 @@ class AtomComponentProperties:
def grid(property: str = 'name') -> str:
"""
Grid component properties.
- 'Secondary Grid Spacing': The spacing value for the secondary grid, i.e. 1.0
:param property: From the last element of the property tree path. Default 'name' for component name string.
:return: Full property path OR component name if no property specified.
"""
properties = {
'name': 'Grid',
'Secondary Grid Spacing': 'Controller|Configuration|Secondary Grid Spacing',
}
return properties[property]
@@ -231,11 +235,13 @@ class AtomComponentProperties:
def hdri_skybox(property: str = 'name') -> str:
"""
HDRi Skybox component properties.
- 'Cubemap Texture': Asset.id for the cubemap texture to set.
:param property: From the last element of the property tree path. Default 'name' for component name string.
:return: Full property path OR component name if no property specified.
"""
properties = {
'name': 'HDRi Skybox',
'Cubemap Texture': 'Controller|Configuration|Cubemap Texture',
}
return properties[property]
@@ -259,12 +265,16 @@ class AtomComponentProperties:
Look Modification component properties. Requires PostFX Layer component.
- 'requires' a list of component names as strings required by this component.
Use editor_entity_utils EditorEntity.add_components(list) to add this list of requirements.\n
- 'Enable look modification' Toggle active state of the component True/False
- 'Color Grading LUT' Asset.id for the LUT used for affecting level look.
:param property: From the last element of the property tree path. Default 'name' for component name string.
:return: Full property path OR component name if no property specified.
"""
properties = {
'name': 'Look Modification',
'requires': [AtomComponentProperties.postfx_layer()],
'Enable look modification': 'Controller|Configuration|Enable look modification',
'Color Grading LUT': 'Controller|Configuration|Color Grading LUT',
}
return properties[property]
@@ -274,12 +284,14 @@ class AtomComponentProperties:
Material component properties. Requires one of Actor OR Mesh component.
- 'requires' a list of component names as strings required by this component.
Only one of these is required at a time for this component.\n
- 'Material Asset': the material Asset.id of the material.
:param property: From the last element of the property tree path. Default 'name' for component name string.
:return: Full property path OR component name if no property specified.
"""
properties = {
'name': 'Material',
'requires': [AtomComponentProperties.actor(), AtomComponentProperties.mesh()],
'Material Asset': 'Default Material|Material Asset',
}
return properties[property]
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:954d7d0df47c840a24e313893800eb3126d0c0d47c3380926776b51833778db7
oid sha256:aee1fd4d5264e5ef1676b507409ce70af6358cf1ff368d9aeb17f7b2597dfbca
size 6220817
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e81c19128f42ba362a2d5f3ccf159dfbc942d67ceeb1ac8c21f295a6fd9d2ce5
oid sha256:d4787cdafbcc2fe71c1cb3f1da53a249db839a9df539a9e88be43ccd6d8e4d6a
size 6220817
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:5e20801213e065b6ea8c95ede81c23faa9b6dc70a2002dc5bced293e1bed989f
oid sha256:5fac5bf41c9b16b6fbd762868e5cf514376af92d6ef7ebb9e819f024f1a3e1a7
size 6220817
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e250f812e594e5152bf2d6f23caa8b53b78276bfdf344d7a8d355dd96cb995c0
oid sha256:7a23969670499524725535e8be7428b55b6f3e887cc24e2e903f7ea821a6d1a5
size 6220817
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:95be359041f8291c74b335297a4dfe9902a180510f24a181b15e1a5ba4d3b024
oid sha256:2f1f4d8865c56ed7f96f339c39e5feb4e0dbc6c6a8b4a7843b4166381b06b00d
size 6220817
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:07e09d3eb5bf0cee3d9b3752aaad40f3ead1dcc5ddd837a6226fadde55d57274
oid sha256:5d4ee5641e19eef08dd6b93d2f4054a1aae2165325416ed2cbf0b8243f2c0b06
size 6220817
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:118e43e4b915e262726183467cc4b82f244565213fea5b6bfe02be07f0851ab1
oid sha256:55c8f0d1790bb12660b7557630efca297b2a1b59e6c93167a2563da79e0a8255
size 6220817
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:dc2ce3256a6552975962c9e113c52c1a22bf3817d417151f6f60640dd568e0fa
oid sha256:082ff368b621e12b083d96562a0889b11a1d683767a74296cbe6d8732830e9e8
size 6220817
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:287d98890b35427688999760f9d066bcbff1a3bc9001534241dc212b32edabd8
oid sha256:78cc62d89782899747875b41abee57c2efdfacf4c8af6511c88f82d76eaae4ca
size 6220817
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:66e91c92c868167c850078cd91714db47e10a96e23cc30191994486bd79c353f
oid sha256:3d6719326f4dacae278d1723090ce1182193b793f250963af8be4b2c298e8841
size 6220817
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d950d173f5101820c5e18205401ca08ce5feeff2302ac2920b292750d86a8fa4
oid sha256:9e492bb394fb18fb117f8a5b61cd2789922f9d6e88fc83189b5b6d59ffb1c3ef
size 6220817
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:72eddb7126eae0c839b933886e0fb69d78229f72d49ef13199de28df2b7879db
oid sha256:caca85f7728f660daae36afc81d681ba2de2377c516eb3c637599de5c94012aa
size 6220817
@@ -0,0 +1,158 @@
"""
Copyright (c) Contributors to the Open 3D Engine Project.
For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
class Tests:
creation_undo = (
"UNDO Entity creation success",
"UNDO Entity creation failed")
creation_redo = (
"REDO Entity creation success",
"REDO Entity creation failed")
entity_reference_creation = (
"Entity Reference Entity successfully created",
"Entity Reference Entity failed to be created")
entity_reference_component = (
"Entity has an Entity Reference component",
"Entity failed to find Entity Reference component")
enter_game_mode = (
"Entered game mode",
"Failed to enter game mode")
exit_game_mode = (
"Exited game mode",
"Couldn't exit game mode")
is_visible = (
"Entity is visible",
"Entity was not visible")
is_hidden = (
"Entity is hidden",
"Entity was not hidden")
entity_deleted = (
"Entity deleted",
"Entity was not deleted")
deletion_undo = (
"UNDO deletion success",
"UNDO deletion failed")
deletion_redo = (
"REDO deletion success",
"REDO deletion failed")
def AtomEditorComponents_EntityReference_AddedToEntity():
"""
Summary:
Tests the Entity Reference component can be added to an entity and has the expected functionality.
Test setup:
- Wait for Editor idle loop.
- Open the "Base" level.
Expected Behavior:
The component can be added, used in game mode, hidden/shown, deleted, and has accurate required components.
Creation and deletion undo/redo should also work.
Test Steps:
1) Create an Entity Reference entity with no components.
2) Add Entity Reference component to Entity Reference entity.
3) UNDO the entity creation and component addition.
4) REDO the entity creation and component addition.
5) Enter/Exit game mode.
6) Test IsHidden.
7) Test IsVisible.
8) Delete Entity Reference entity.
9) UNDO deletion.
10) REDO deletion.
11) Look for errors.
:return: None
"""
import azlmbr.legacy.general as general
from editor_python_test_tools.editor_entity_utils import EditorEntity
from editor_python_test_tools.utils import Report, Tracer, TestHelper
from Atom.atom_utils.atom_constants import AtomComponentProperties
with Tracer() as error_tracer:
# Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
TestHelper.init_idle()
TestHelper.open_level("", "Base")
# Test steps begin.
# 1. Create an Entity Reference entity with no components.
entity_reference_entity = EditorEntity.create_editor_entity(AtomComponentProperties.entity_reference())
Report.critical_result(Tests.entity_reference_creation, entity_reference_entity.exists())
# 2. Add Entity Reference component to Entity Reference entity.
entity_reference_component = entity_reference_entity.add_component(
AtomComponentProperties.entity_reference())
Report.critical_result(
Tests.entity_reference_component,
entity_reference_entity.has_component(AtomComponentProperties.entity_reference()))
# 3. UNDO the entity creation and component addition.
# -> UNDO component addition.
general.undo()
# -> UNDO naming entity.
general.undo()
# -> UNDO selecting entity.
general.undo()
# -> UNDO entity creation.
general.undo()
general.idle_wait_frames(1)
Report.result(Tests.creation_undo, not entity_reference_entity.exists())
# 4. REDO the entity creation and component addition.
# -> REDO entity creation.
general.redo()
# -> REDO selecting entity.
general.redo()
# -> REDO naming entity.
general.redo()
# -> REDO component addition.
general.redo()
general.idle_wait_frames(1)
Report.result(Tests.creation_redo, entity_reference_entity.exists())
# 5. Enter/Exit game mode.
TestHelper.enter_game_mode(Tests.enter_game_mode)
general.idle_wait_frames(1)
TestHelper.exit_game_mode(Tests.exit_game_mode)
# 6. Test IsHidden.
entity_reference_entity.set_visibility_state(False)
Report.result(Tests.is_hidden, entity_reference_entity.is_hidden() is True)
# 7. Test IsVisible.
entity_reference_entity.set_visibility_state(True)
general.idle_wait_frames(1)
Report.result(Tests.is_visible, entity_reference_entity.is_visible() is True)
# 8. Delete Entity Reference entity.
entity_reference_entity.delete()
Report.result(Tests.entity_deleted, not entity_reference_entity.exists())
# 9. UNDO deletion.
general.undo()
Report.result(Tests.deletion_undo, entity_reference_entity.exists())
# 10. REDO deletion.
general.redo()
Report.result(Tests.deletion_redo, not entity_reference_entity.exists())
# 11. Look for errors and asserts.
TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
for error_info in error_tracer.errors:
Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
for assert_info in error_tracer.asserts:
Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}")
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(AtomEditorComponents_EntityReference_AddedToEntity)
@@ -151,7 +151,7 @@ def AtomEditorComponents_GlobalSkylightIBL_AddedToEntity():
Report.result(Tests.is_visible, global_skylight_entity.is_visible() is True)
# 8. Set the Diffuse Image asset on the Global Skylight (IBL) entity.
diffuse_image_path = os.path.join("LightingPresets", "greenwich_park_02_4k_iblskyboxcm.exr.streamingimage")
diffuse_image_path = os.path.join("LightingPresets", "default_iblskyboxcm.exr.streamingimage")
diffuse_image_asset = Asset.find_asset_by_path(diffuse_image_path, False)
global_skylight_component.set_component_property_value(
AtomComponentProperties.global_skylight('Diffuse Image'), diffuse_image_asset.id)
@@ -161,7 +161,7 @@ def AtomEditorComponents_GlobalSkylightIBL_AddedToEntity():
AtomComponentProperties.global_skylight('Diffuse Image')))
# 9. Set the Specular Image asset on the Global Light (IBL) entity.
specular_image_path = os.path.join("LightingPresets", "greenwich_park_02_4k_iblskyboxcm.exr.streamingimage")
specular_image_path = os.path.join("LightingPresets", "default_iblskyboxcm.exr.streamingimage")
specular_image_asset = Asset.find_asset_by_path(specular_image_path, False)
global_skylight_component.set_component_property_value(
AtomComponentProperties.global_skylight('Specular Image'), specular_image_asset.id)
@@ -0,0 +1,177 @@
"""
Copyright (c) Contributors to the Open 3D Engine Project.
For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
class Tests:
creation_undo = (
"UNDO Entity creation success",
"UNDO Entity creation failed")
creation_redo = (
"REDO Entity creation success",
"REDO Entity creation failed")
hdri_skybox_entity_creation = (
"HDRi Skybox successfully created",
"HDRi Skybox failed to be created")
hdri_skybox_component = (
"Entity has an HDRi Skybox component",
"Entity failed to find HDRi Skybox component")
cubemap_property_set = (
"Cubemap property set on HDRi Skybox component",
"Couldn't set Cubemap property on HDRi Skybox component")
enter_game_mode = (
"Entered game mode",
"Failed to enter game mode")
exit_game_mode = (
"Exited game mode",
"Couldn't exit game mode")
is_visible = (
"Entity is visible",
"Entity was not visible")
is_hidden = (
"Entity is hidden",
"Entity was not hidden")
entity_deleted = (
"Entity deleted",
"Entity was not deleted")
deletion_undo = (
"UNDO deletion success",
"UNDO deletion failed")
deletion_redo = (
"REDO deletion success",
"REDO deletion failed")
def AtomEditorComponents_HDRiSkybox_AddedToEntity():
"""
Summary:
Tests the HDRi Skybox component can be added to an entity and has the expected functionality.
Test setup:
- Wait for Editor idle loop.
- Open the "Base" level.
Expected Behavior:
The component can be added, used in game mode, hidden/shown, deleted, and has accurate required components.
Creation and deletion undo/redo should also work.
Test Steps:
1) Create an HDRi Skybox with no components.
2) Add an HDRi Skybox component to HDRi Skybox.
3) UNDO the entity creation and component addition.
4) REDO the entity creation and component addition.
5) Enter/Exit game mode.
6) Test IsHidden.
7) Test IsVisible.
8) Delete HDRi Skybox.
9) UNDO deletion.
10) REDO deletion.
11) Look for errors.
:return: None
"""
import os
import azlmbr.legacy.general as general
from editor_python_test_tools.asset_utils import Asset
from editor_python_test_tools.editor_entity_utils import EditorEntity
from editor_python_test_tools.utils import Report, Tracer, TestHelper
from Atom.atom_utils.atom_constants import AtomComponentProperties
with Tracer() as error_tracer:
# Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
TestHelper.init_idle()
TestHelper.open_level("", "Base")
# Test steps begin.
# 1. Create an HDRi Skybox with no components.
hdri_skybox_entity = EditorEntity.create_editor_entity(
AtomComponentProperties.hdri_skybox())
Report.critical_result(Tests.hdri_skybox_entity_creation,
hdri_skybox_entity.exists())
# 2. Add an HDRi Skybox component to HDRi Skybox.
hdri_skybox_component = hdri_skybox_entity.add_component(
AtomComponentProperties.hdri_skybox())
Report.critical_result(
Tests.hdri_skybox_component,
hdri_skybox_entity.has_component(AtomComponentProperties.hdri_skybox()))
# 3. UNDO the entity creation and component addition.
# -> UNDO component addition.
general.undo()
# -> UNDO naming entity.
general.undo()
# -> UNDO selecting entity.
general.undo()
# -> UNDO entity creation.
general.undo()
general.idle_wait_frames(1)
Report.result(Tests.creation_undo, not hdri_skybox_entity.exists())
# 4. REDO the entity creation and component addition.
# -> REDO entity creation.
general.redo()
# -> REDO selecting entity.
general.redo()
# -> REDO naming entity.
general.redo()
# -> REDO component addition.
general.redo()
general.idle_wait_frames(1)
Report.result(Tests.creation_redo, hdri_skybox_entity.exists())
# 5. Set Cubemap Texture on HDRi Skybox component.
skybox_cubemap_asset_path = os.path.join("LightingPresets", "default_iblskyboxcm.exr.streamingimage")
skybox_cubemap_material_asset = Asset.find_asset_by_path(skybox_cubemap_asset_path, False)
hdri_skybox_component.set_component_property_value(
AtomComponentProperties.hdri_skybox('Cubemap Texture'), skybox_cubemap_material_asset.id)
get_cubemap_property = hdri_skybox_component.get_component_property_value(
AtomComponentProperties.hdri_skybox('Cubemap Texture'))
Report.result(Tests.cubemap_property_set, get_cubemap_property == skybox_cubemap_material_asset.id)
# 6. Enter/Exit game mode.
TestHelper.enter_game_mode(Tests.enter_game_mode)
general.idle_wait_frames(1)
TestHelper.exit_game_mode(Tests.exit_game_mode)
# 7. Test IsHidden.
hdri_skybox_entity.set_visibility_state(False)
Report.result(Tests.is_hidden, hdri_skybox_entity.is_hidden() is True)
# 8. Test IsVisible.
hdri_skybox_entity.set_visibility_state(True)
general.idle_wait_frames(1)
Report.result(Tests.is_visible, hdri_skybox_entity.is_visible() is True)
# 9. Delete hdri_skybox entity.
hdri_skybox_entity.delete()
Report.result(Tests.entity_deleted, not hdri_skybox_entity.exists())
# 10. UNDO deletion.
general.undo()
Report.result(Tests.deletion_undo, hdri_skybox_entity.exists())
# 11. REDO deletion.
general.redo()
Report.result(Tests.deletion_redo, not hdri_skybox_entity.exists())
# 12. Look for errors or asserts.
TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
for error_info in error_tracer.errors:
Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
for assert_info in error_tracer.asserts:
Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}")
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(AtomEditorComponents_HDRiSkybox_AddedToEntity)
@@ -0,0 +1,211 @@
"""
Copyright (c) Contributors to the Open 3D Engine Project.
For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
class Tests:
creation_undo = (
"UNDO Entity creation success",
"UNDO Entity creation failed")
creation_redo = (
"REDO Entity creation success",
"REDO Entity creation failed")
look_modification_creation = (
"Look Modification Entity successfully created",
"Look Modification Entity failed to be created")
look_modification_component = (
"Entity has a Look Modification component",
"Entity failed to find Look Modification component")
look_modification_disabled = (
"Look Modification component disabled",
"Look Modification component was not disabled")
postfx_layer_component = (
"Entity has a PostFX Layer component",
"Entity did not have an PostFX Layer component")
look_modification_enabled = (
"Look Modification component enabled",
"Look Modification component was not enabled")
enable_look_modification_parameter_enabled = (
"Enable look modification parameter enabled",
"Enable look modification parameter was not enabled")
color_grading_lut_set = (
"Entity has the Color Grading LUT set",
"Entity did not the Color Grading LUT set")
enter_game_mode = (
"Entered game mode",
"Failed to enter game mode")
exit_game_mode = (
"Exited game mode",
"Couldn't exit game mode")
is_visible = (
"Entity is visible",
"Entity was not visible")
is_hidden = (
"Entity is hidden",
"Entity was not hidden")
entity_deleted = (
"Entity deleted",
"Entity was not deleted")
deletion_undo = (
"UNDO deletion success",
"UNDO deletion failed")
deletion_redo = (
"REDO deletion success",
"REDO deletion failed")
def AtomEditorComponents_LookModification_AddedToEntity():
"""
Summary:
Tests the Look Modification component can be added to an entity and has the expected functionality.
Test setup:
- Wait for Editor idle loop.
- Open the "Base" level.
Expected Behavior:
The component can be added, used in game mode, hidden/shown, deleted, and has accurate required components.
Creation and deletion undo/redo should also work.
Test Steps:
1) Create an Look Modification entity with no components.
2) Add Look Modification component to Look Modification entity.
3) UNDO the entity creation and component addition.
4) REDO the entity creation and component addition.
5) Verify Look Modification component not enabled.
6) Add PostFX Layer component since it is required by the Look Modification component.
7) Verify Look Modification component is enabled.
8) Enable the "Enable Look Modification" parameter.
9) Add LUT asset to the Color Grading LUT parameter.
9) Enter/Exit game mode.
10) Test IsHidden.
11) Test IsVisible.
12) Delete Look Modification entity.
13) UNDO deletion.
14) REDO deletion.
15) Look for errors.
:return: None
"""
import os
import azlmbr.legacy.general as general
from editor_python_test_tools.asset_utils import Asset
from editor_python_test_tools.editor_entity_utils import EditorEntity
from editor_python_test_tools.utils import Report, Tracer, TestHelper
from Atom.atom_utils.atom_constants import AtomComponentProperties
with Tracer() as error_tracer:
# Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
TestHelper.init_idle()
TestHelper.open_level("", "Base")
# Test steps begin.
# 1. Create an Look Modification entity with no components.
look_modification_entity = EditorEntity.create_editor_entity(AtomComponentProperties.look_modification())
Report.critical_result(Tests.look_modification_creation, look_modification_entity.exists())
# 2. Add Look Modification component to Look Modification entity.
look_modification_component = look_modification_entity.add_component(
AtomComponentProperties.look_modification())
Report.critical_result(
Tests.look_modification_component,
look_modification_entity.has_component(AtomComponentProperties.look_modification()))
# 3. UNDO the entity creation and component addition.
# -> UNDO component addition.
general.undo()
# -> UNDO naming entity.
general.undo()
# -> UNDO selecting entity.
general.undo()
# -> UNDO entity creation.
general.undo()
general.idle_wait_frames(1)
Report.result(Tests.creation_undo, not look_modification_entity.exists())
# 4. REDO the entity creation and component addition.
# -> REDO entity creation.
general.redo()
# -> REDO selecting entity.
general.redo()
# -> REDO naming entity.
general.redo()
# -> REDO component addition.
general.redo()
general.idle_wait_frames(1)
Report.result(Tests.creation_redo, look_modification_entity.exists())
# 5. Verify Look Modification component not enabled.
Report.result(Tests.look_modification_disabled, not look_modification_component.is_enabled())
# 6. Add PostFX Layer component since it is required by the Look Modification component.
look_modification_entity.add_component(AtomComponentProperties.postfx_layer())
Report.result(
Tests.postfx_layer_component,
look_modification_entity.has_component(AtomComponentProperties.postfx_layer()))
# 7. Verify Look Modification component is enabled.
Report.result(Tests.look_modification_enabled, look_modification_component.is_enabled())
# 8. Enable the "Enable look modification" parameter.
look_modification_component.set_component_property_value(
AtomComponentProperties.look_modification('Enable look modification'), True)
Report.result(Tests.enable_look_modification_parameter_enabled,
look_modification_component.get_component_property_value(
AtomComponentProperties.look_modification('Enable look modification')) is True)
# 9. Set the Color Grading LUT asset on the Look Modification entity.
color_grading_lut_path = os.path.join("ColorGrading", "TestData", "Photoshop", "inv-Log2-48nits",
"test_3dl_32_lut.azasset")
color_grading_lut_asset = Asset.find_asset_by_path(color_grading_lut_path, False)
look_modification_component.set_component_property_value(
AtomComponentProperties.look_modification('Color Grading LUT'), color_grading_lut_asset.id)
Report.result(
Tests.color_grading_lut_set,
color_grading_lut_asset.id == look_modification_component.get_component_property_value(
AtomComponentProperties.look_modification('Color Grading LUT')))
# 10. Enter/Exit game mode.
TestHelper.enter_game_mode(Tests.enter_game_mode)
general.idle_wait_frames(1)
TestHelper.exit_game_mode(Tests.exit_game_mode)
# 11. Test IsHidden.
look_modification_entity.set_visibility_state(False)
Report.result(Tests.is_hidden, look_modification_entity.is_hidden() is True)
# 12. Test IsVisible.
look_modification_entity.set_visibility_state(True)
general.idle_wait_frames(1)
Report.result(Tests.is_visible, look_modification_entity.is_visible() is True)
# 13. Delete Look Modification entity.
look_modification_entity.delete()
Report.result(Tests.entity_deleted, not look_modification_entity.exists())
# 14. UNDO deletion.
general.undo()
Report.result(Tests.deletion_undo, look_modification_entity.exists())
# 15. REDO deletion.
general.redo()
Report.result(Tests.deletion_redo, not look_modification_entity.exists())
# 16. Look for errors and asserts.
TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
for error_info in error_tracer.errors:
Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
for assert_info in error_tracer.asserts:
Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}")
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(AtomEditorComponents_LookModification_AddedToEntity)
@@ -0,0 +1,182 @@
"""
Copyright (c) Contributors to the Open 3D Engine Project.
For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
class Tests:
creation_undo = (
"UNDO Entity creation success",
"UNDO Entity creation failed")
creation_redo = (
"REDO Entity creation success",
"REDO Entity creation failed")
ssao_creation = (
"SSAO Entity successfully created",
"SSAO Entity failed to be created")
ssao_component = (
"Entity has a SSAO component",
"Entity failed to find SSAO component")
ssao_disabled = (
"SSAO component disabled",
"SSAO component was not disabled.")
postfx_layer_component = (
"Entity has a PostFX Layer component",
"Entity did not have an PostFX Layer component")
ssao_enabled = (
"SSAO component enabled",
"SSAO component was not enabled.")
enter_game_mode = (
"Entered game mode",
"Failed to enter game mode")
exit_game_mode = (
"Exited game mode",
"Couldn't exit game mode")
is_visible = (
"Entity is visible",
"Entity was not visible")
is_hidden = (
"Entity is hidden",
"Entity was not hidden")
entity_deleted = (
"Entity deleted",
"Entity was not deleted")
deletion_undo = (
"UNDO deletion success",
"UNDO deletion failed")
deletion_redo = (
"REDO deletion success",
"REDO deletion failed")
def AtomEditorComponents_SSAO_AddedToEntity():
"""
Summary:
Tests the SSAO component can be added to an entity and has the expected functionality.
Screen Space Ambient Occlusion (SSAO) is a PostFX shadow lighting effect.
Test setup:
- Wait for Editor idle loop.
- Open the "Base" level.
Expected Behavior:
The component can be added, used in game mode, hidden/shown, deleted, and has accurate required components.
Creation and deletion undo/redo should also work.
Test Steps:
1) Create a SSAO entity with no components.
2) Add SSAO component to SSAO entity.
3) UNDO the entity creation and component addition.
4) REDO the entity creation and component addition.
5) Verify SSAO component not enabled.
6) Add PostFX Layer component since it is required by the SSAO component.
7) Verify SSAO component is enabled.
8) Enter/Exit game mode.
9) Test IsHidden.
10) Test IsVisible.
11) Delete SSAO entity.
12) UNDO deletion.
13) REDO deletion.
14) Look for errors.
:return: None
"""
import azlmbr.legacy.general as general
from editor_python_test_tools.editor_entity_utils import EditorEntity
from editor_python_test_tools.utils import Report, Tracer, TestHelper
from Atom.atom_utils.atom_constants import AtomComponentProperties
with Tracer() as error_tracer:
# Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
TestHelper.init_idle()
TestHelper.open_level("", "Base")
# Test steps begin.
# 1. Create a SSAO entity with no components.
ssao_entity = EditorEntity.create_editor_entity(AtomComponentProperties.ssao())
Report.critical_result(Tests.ssao_creation, ssao_entity.exists())
# 2. Add SSAO component to SSAO entity.
ssao_component = ssao_entity.add_component(AtomComponentProperties.ssao())
Report.critical_result(
Tests.ssao_component,
ssao_entity.has_component(AtomComponentProperties.ssao()))
ssao_component.get_property_tree()
# 3. UNDO the entity creation and component addition.
# -> UNDO component addition.
general.undo()
# -> UNDO naming entity.
general.undo()
# -> UNDO selecting entity.
general.undo()
# -> UNDO entity creation.
general.undo()
general.idle_wait_frames(1)
Report.result(Tests.creation_undo, not ssao_entity.exists())
# 4. REDO the entity creation and component addition.
# -> REDO entity creation.
general.redo()
# -> REDO selecting entity.
general.redo()
# -> REDO naming entity.
general.redo()
# -> REDO component addition.
general.redo()
general.idle_wait_frames(1)
Report.result(Tests.creation_redo, ssao_entity.exists())
# 5. Verify SSAO component not enabled.
Report.result(Tests.ssao_disabled, not ssao_component.is_enabled())
# 6. Add PostFX Layer component since it is required by the SSAO component.
ssao_entity.add_component(AtomComponentProperties.postfx_layer())
Report.result(
Tests.postfx_layer_component,
ssao_entity.has_component(AtomComponentProperties.postfx_layer()))
# 7. Verify SSAO component is enabled.
Report.result(Tests.ssao_enabled, ssao_component.is_enabled())
# 8. Enter/Exit game mode.
TestHelper.enter_game_mode(Tests.enter_game_mode)
general.idle_wait_frames(1)
TestHelper.exit_game_mode(Tests.exit_game_mode)
# 9. Test IsHidden.
ssao_entity.set_visibility_state(False)
Report.result(Tests.is_hidden, ssao_entity.is_hidden() is True)
# 10. Test IsVisible.
ssao_entity.set_visibility_state(True)
general.idle_wait_frames(1)
Report.result(Tests.is_visible, ssao_entity.is_visible() is True)
# 11. Delete SSAO entity.
ssao_entity.delete()
Report.result(Tests.entity_deleted, not ssao_entity.exists())
# 12. UNDO deletion.
general.undo()
Report.result(Tests.deletion_undo, ssao_entity.exists())
# 13. REDO deletion.
general.redo()
Report.result(Tests.deletion_redo, not ssao_entity.exists())
# 14. Look for errors and asserts.
TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
for error_info in error_tracer.errors:
Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
for assert_info in error_tracer.asserts:
Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}")
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(AtomEditorComponents_SSAO_AddedToEntity)
@@ -6,30 +6,70 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
"""
# fmt: off
class Tests :
camera_component_added = ("Camera component was added", "Camera component wasn't added")
camera_fov_set = ("Camera component FOV property set", "Camera component FOV property wasn't set")
directional_light_component_added = ("Directional Light component added", "Directional Light component wasn't added")
enter_game_mode = ("Entered game mode", "Failed to enter game mode")
exit_game_mode = ("Exited game mode", "Couldn't exit game mode")
global_skylight_component_added = ("Global Skylight (IBL) component added", "Global Skylight (IBL) component wasn't added")
global_skylight_diffuse_image_set = ("Global Skylight Diffuse Image property set", "Global Skylight Diffuse Image property wasn't set")
global_skylight_specular_image_set = ("Global Skylight Specular Image property set", "Global Skylight Specular Image property wasn't set")
ground_plane_material_asset_set = ("Ground Plane Material Asset was set", "Ground Plane Material Asset wasn't set")
ground_plane_material_component_added = ("Ground Plane Material component added", "Ground Plane Material component wasn't added")
ground_plane_mesh_asset_set = ("Ground Plane Mesh Asset property was set", "Ground Plane Mesh Asset property wasn't set")
hdri_skybox_component_added = ("HDRi Skybox component added", "HDRi Skybox component wasn't added")
hdri_skybox_cubemap_texture_set = ("HDRi Skybox Cubemap Texture property set", "HDRi Skybox Cubemap Texture property wasn't set")
mesh_component_added = ("Mesh component added", "Mesh component wasn't added")
no_assert_occurred = ("No asserts detected", "Asserts were detected")
no_error_occurred = ("No errors detected", "Errors were detected")
secondary_grid_spacing = ("Secondary Grid Spacing set", "Secondary Grid Spacing not set")
sphere_material_component_added = ("Sphere Material component added", "Sphere Material component wasn't added")
sphere_material_set = ("Sphere Material Asset was set", "Sphere Material Asset wasn't set")
sphere_mesh_asset_set = ("Sphere Mesh Asset was set", "Sphere Mesh Asset wasn't set")
viewport_set = ("Viewport set to correct size", "Viewport not set to correct size")
# fmt: on
class Tests:
camera_component_added = (
"Camera component was added",
"Camera component wasn't added")
camera_fov_set = (
"Camera component FOV property set",
"Camera component FOV property wasn't set")
directional_light_component_added = (
"Directional Light component added",
"Directional Light component wasn't added")
enter_game_mode = (
"Entered game mode",
"Failed to enter game mode")
exit_game_mode = (
"Exited game mode",
"Couldn't exit game mode")
global_skylight_component_added = (
"Global Skylight (IBL) component added",
"Global Skylight (IBL) component wasn't added")
global_skylight_diffuse_image_set = (
"Global Skylight Diffuse Image property set",
"Global Skylight Diffuse Image property wasn't set")
global_skylight_specular_image_set = (
"Global Skylight Specular Image property set",
"Global Skylight Specular Image property wasn't set")
ground_plane_material_asset_set = (
"Ground Plane Material Asset was set",
"Ground Plane Material Asset wasn't set")
ground_plane_material_component_added = (
"Ground Plane Material component added",
"Ground Plane Material component wasn't added")
ground_plane_mesh_asset_set = (
"Ground Plane Mesh Asset property was set",
"Ground Plane Mesh Asset property wasn't set")
hdri_skybox_component_added = (
"HDRi Skybox component added",
"HDRi Skybox component wasn't added")
hdri_skybox_cubemap_texture_set = (
"HDRi Skybox Cubemap Texture property set",
"HDRi Skybox Cubemap Texture property wasn't set")
mesh_component_added = (
"Mesh component added",
"Mesh component wasn't added")
no_assert_occurred = (
"No asserts detected",
"Asserts were detected")
no_error_occurred = (
"No errors detected",
"Errors were detected")
secondary_grid_spacing = (
"Secondary Grid Spacing set",
"Secondary Grid Spacing not set")
sphere_material_component_added = (
"Sphere Material component added",
"Sphere Material component wasn't added")
sphere_material_set = (
"Sphere Material Asset was set",
"Sphere Material Asset wasn't set")
sphere_mesh_asset_set = (
"Sphere Mesh Asset was set",
"Sphere Mesh Asset wasn't set")
viewport_set = (
"Viewport set to correct size",
"Viewport not set to correct size")
def AtomGPU_BasicLevelSetup_SetsUpLevel():
@@ -77,19 +117,17 @@ def AtomGPU_BasicLevelSetup_SetsUpLevel():
import os
from math import isclose
import azlmbr.asset as asset
import azlmbr.bus as bus
import azlmbr.legacy.general as general
import azlmbr.math as math
import azlmbr.paths
from editor_python_test_tools.asset_utils import Asset
from editor_python_test_tools.editor_entity_utils import EditorEntity
from editor_python_test_tools.utils import Report, Tracer, TestHelper as helper
from editor_python_test_tools.utils import Report, Tracer, TestHelper
from Atom.atom_utils.atom_constants import AtomComponentProperties
from Atom.atom_utils.screenshot_utils import ScreenshotHelper
MATERIAL_COMPONENT_NAME = "Material"
MESH_COMPONENT_NAME = "Mesh"
SCREENSHOT_NAME = "AtomBasicLevelSetup"
SCREEN_WIDTH = 1280
SCREEN_HEIGHT = 720
@@ -98,24 +136,24 @@ def AtomGPU_BasicLevelSetup_SetsUpLevel():
def initial_viewport_setup(screen_width, screen_height):
general.set_viewport_size(screen_width, screen_height)
general.update_viewport()
result = isclose(
a=general.get_viewport_size().x, b=SCREEN_WIDTH, rel_tol=0.1) and isclose(
a=general.get_viewport_size().y, b=SCREEN_HEIGHT, rel_tol=0.1)
return result
TestHelper.wait_for_condition(
function=lambda: isclose(a=general.get_viewport_size().x, b=SCREEN_WIDTH, rel_tol=0.1)
and isclose(a=general.get_viewport_size().y, b=SCREEN_HEIGHT, rel_tol=0.1),
timeout_in_seconds=4.0
)
with Tracer() as error_tracer:
# Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
helper.init_idle()
helper.open_level("", "Base")
TestHelper.init_idle()
TestHelper.open_level("", "Base")
# Test steps begin.
# 1. Close error windows and display helpers then update the viewport size.
helper.close_error_windows()
helper.close_display_helpers()
TestHelper.close_error_windows()
TestHelper.close_display_helpers()
initial_viewport_setup(SCREEN_WIDTH, SCREEN_HEIGHT)
general.update_viewport()
Report.critical_result(Tests.viewport_set, initial_viewport_setup(SCREEN_WIDTH, SCREEN_HEIGHT))
# 2. Create Default Level Entity.
default_level_entity_name = "Default Level"
@@ -123,168 +161,167 @@ def AtomGPU_BasicLevelSetup_SetsUpLevel():
math.Vector3(0.0, 0.0, 0.0), default_level_entity_name)
# 3. Create Grid Entity as a child entity of the Default Level Entity.
grid_name = "Grid"
grid_entity = EditorEntity.create_editor_entity(grid_name, default_level_entity.id)
grid_entity = EditorEntity.create_editor_entity(AtomComponentProperties.grid(), default_level_entity.id)
# 4. Add Grid component to Grid Entity and set Secondary Grid Spacing.
grid_component = grid_entity.add_component(grid_name)
secondary_grid_spacing_property = "Controller|Configuration|Secondary Grid Spacing"
grid_component = grid_entity.add_component(AtomComponentProperties.grid())
secondary_grid_spacing_value = 1.0
grid_component.set_component_property_value(secondary_grid_spacing_property, secondary_grid_spacing_value)
grid_component.set_component_property_value(
AtomComponentProperties.grid('Secondary Grid Spacing'), secondary_grid_spacing_value)
secondary_grid_spacing_set = grid_component.get_component_property_value(
secondary_grid_spacing_property) == secondary_grid_spacing_value
AtomComponentProperties.grid('Secondary Grid Spacing')) == secondary_grid_spacing_value
Report.result(Tests.secondary_grid_spacing, secondary_grid_spacing_set)
# 5. Create Global Skylight (IBL) Entity as a child entity of the Default Level Entity.
global_skylight_name = "Global Skylight (IBL)"
global_skylight_entity = EditorEntity.create_editor_entity(global_skylight_name, default_level_entity.id)
global_skylight_entity = EditorEntity.create_editor_entity(
AtomComponentProperties.global_skylight(), default_level_entity.id)
# 6. Add HDRi Skybox component to the Global Skylight (IBL) Entity.
hdri_skybox_name = "HDRi Skybox"
hdri_skybox_component = global_skylight_entity.add_component(hdri_skybox_name)
Report.result(Tests.hdri_skybox_component_added, global_skylight_entity.has_component(hdri_skybox_name))
hdri_skybox_component = global_skylight_entity.add_component(AtomComponentProperties.hdri_skybox())
Report.result(Tests.hdri_skybox_component_added, global_skylight_entity.has_component(
AtomComponentProperties.hdri_skybox()))
# 7. Add Global Skylight (IBL) component to the Global Skylight (IBL) Entity.
global_skylight_component = global_skylight_entity.add_component(global_skylight_name)
Report.result(Tests.global_skylight_component_added, global_skylight_entity.has_component(global_skylight_name))
global_skylight_component = global_skylight_entity.add_component(AtomComponentProperties.global_skylight())
Report.result(Tests.global_skylight_component_added, global_skylight_entity.has_component(
AtomComponentProperties.global_skylight()))
# 8. Set the Cubemap Texture property of the HDRi Skybox component.
global_skylight_image_asset_path = os.path.join(
"LightingPresets", "greenwich_park_02_4k_iblskyboxcm_iblspecular.exr.streamingimage")
global_skylight_image_asset = asset.AssetCatalogRequestBus(
bus.Broadcast, "GetAssetIdByPath", global_skylight_image_asset_path, math.Uuid(), False)
hdri_skybox_cubemap_texture_property = "Controller|Configuration|Cubemap Texture"
global_skylight_image_asset_path = os.path.join("LightingPresets", "default_iblskyboxcm.exr.streamingimage")
global_skylight_image_asset = Asset.find_asset_by_path(global_skylight_image_asset_path, False)
hdri_skybox_component.set_component_property_value(
hdri_skybox_cubemap_texture_property, global_skylight_image_asset)
AtomComponentProperties.hdri_skybox('Cubemap Texture'), global_skylight_image_asset.id)
Report.result(
Tests.hdri_skybox_cubemap_texture_set,
hdri_skybox_component.get_component_property_value(
hdri_skybox_cubemap_texture_property) == global_skylight_image_asset)
AtomComponentProperties.hdri_skybox('Cubemap Texture')) == global_skylight_image_asset.id)
# 9. Set the Diffuse Image property of the Global Skylight (IBL) component.
# Re-use the same image that was used in the previous test step.
global_skylight_diffuse_image_property = "Controller|Configuration|Diffuse Image"
global_skylight_diffuse_image_asset_path = os.path.join(
"LightingPresets", "default_iblskyboxcm_ibldiffuse.exr.streamingimage")
global_skylight_diffuse_image_asset = Asset.find_asset_by_path(global_skylight_diffuse_image_asset_path, False)
global_skylight_component.set_component_property_value(
global_skylight_diffuse_image_property, global_skylight_image_asset)
AtomComponentProperties.global_skylight('Diffuse Image'), global_skylight_diffuse_image_asset.id)
Report.result(
Tests.global_skylight_diffuse_image_set,
global_skylight_component.get_component_property_value(
global_skylight_diffuse_image_property) == global_skylight_image_asset)
AtomComponentProperties.global_skylight('Diffuse Image')) == global_skylight_diffuse_image_asset.id)
# 10. Set the Specular Image property of the Global Skylight (IBL) component.
# Re-use the same image that was used in the previous test step.
global_skylight_specular_image_property = "Controller|Configuration|Specular Image"
global_skylight_specular_image_asset_path = os.path.join(
"LightingPresets", "default_iblskyboxcm_iblspecular.exr.streamingimage")
global_skylight_specular_image_asset = Asset.find_asset_by_path(
global_skylight_specular_image_asset_path, False)
global_skylight_component.set_component_property_value(
global_skylight_specular_image_property, global_skylight_image_asset)
AtomComponentProperties.global_skylight('Specular Image'), global_skylight_specular_image_asset.id)
global_skylight_specular_image_set = global_skylight_component.get_component_property_value(
global_skylight_specular_image_property)
AtomComponentProperties.global_skylight('Specular Image'))
Report.result(
Tests.global_skylight_specular_image_set, global_skylight_specular_image_set == global_skylight_image_asset)
Tests.global_skylight_specular_image_set,
global_skylight_specular_image_set == global_skylight_specular_image_asset.id)
# 11. Create a Ground Plane Entity with a Material component that is a child entity of the Default Level Entity.
ground_plane_name = "Ground Plane"
ground_plane_entity = EditorEntity.create_editor_entity(ground_plane_name, default_level_entity.id)
ground_plane_material_component = ground_plane_entity.add_component(MATERIAL_COMPONENT_NAME)
ground_plane_material_component = ground_plane_entity.add_component(AtomComponentProperties.material())
Report.result(
Tests.ground_plane_material_component_added, ground_plane_entity.has_component(MATERIAL_COMPONENT_NAME))
Tests.ground_plane_material_component_added,
ground_plane_entity.has_component(AtomComponentProperties.material()))
# 12. Set the Material Asset property of the Material component for the Ground Plane Entity.
ground_plane_entity.set_local_uniform_scale(32.0)
ground_plane_material_asset_path = os.path.join("Materials", "Presets", "PBR", "metal_chrome.azmaterial")
ground_plane_material_asset = asset.AssetCatalogRequestBus(
bus.Broadcast, "GetAssetIdByPath", ground_plane_material_asset_path, math.Uuid(), False)
ground_plane_material_asset_property = "Default Material|Material Asset"
ground_plane_material_asset = Asset.find_asset_by_path(ground_plane_material_asset_path, False)
ground_plane_material_component.set_component_property_value(
ground_plane_material_asset_property, ground_plane_material_asset)
AtomComponentProperties.material('Material Asset'), ground_plane_material_asset.id)
Report.result(
Tests.ground_plane_material_asset_set,
ground_plane_material_component.get_component_property_value(
ground_plane_material_asset_property) == ground_plane_material_asset)
AtomComponentProperties.material('Material Asset')) == ground_plane_material_asset.id)
# 13. Add the Mesh component to the Ground Plane Entity and set the Mesh component Mesh Asset property.
ground_plane_mesh_component = ground_plane_entity.add_component(MESH_COMPONENT_NAME)
Report.result(Tests.mesh_component_added, ground_plane_entity.has_component(MESH_COMPONENT_NAME))
ground_plane_mesh_asset_path = os.path.join("Objects", "plane.azmodel")
ground_plane_mesh_asset = asset.AssetCatalogRequestBus(
bus.Broadcast, "GetAssetIdByPath", ground_plane_mesh_asset_path, math.Uuid(), False)
ground_plane_mesh_asset_property = "Controller|Configuration|Mesh Asset"
ground_plane_mesh_component = ground_plane_entity.add_component(AtomComponentProperties.mesh())
Report.result(Tests.mesh_component_added, ground_plane_entity.has_component(AtomComponentProperties.mesh()))
ground_plane_mesh_asset_path = os.path.join("TestData", "Objects", "plane.azmodel")
ground_plane_mesh_asset = Asset.find_asset_by_path(ground_plane_mesh_asset_path, False)
ground_plane_mesh_component.set_component_property_value(
ground_plane_mesh_asset_property, ground_plane_mesh_asset)
AtomComponentProperties.mesh('Mesh Asset'), ground_plane_mesh_asset.id)
Report.result(
Tests.ground_plane_mesh_asset_set,
ground_plane_mesh_component.get_component_property_value(
ground_plane_mesh_asset_property) == ground_plane_mesh_asset)
AtomComponentProperties.mesh('Mesh Asset')) == ground_plane_mesh_asset.id)
# 14. Create a Directional Light Entity as a child entity of the Default Level Entity.
directional_light_name = "Directional Light"
directional_light_entity = EditorEntity.create_editor_entity_at(
math.Vector3(0.0, 0.0, 10.0), directional_light_name, default_level_entity.id)
math.Vector3(0.0, 0.0, 10.0), AtomComponentProperties.directional_light(), default_level_entity.id)
# 15. Add Directional Light component to Directional Light Entity and set entity rotation.
directional_light_entity.add_component(directional_light_name)
directional_light_entity.add_component(AtomComponentProperties.directional_light())
directional_light_entity_rotation = math.Vector3(DEGREE_RADIAN_FACTOR * -90.0, 0.0, 0.0)
directional_light_entity.set_local_rotation(directional_light_entity_rotation)
Report.result(
Tests.directional_light_component_added, directional_light_entity.has_component(directional_light_name))
Tests.directional_light_component_added, directional_light_entity.has_component(
AtomComponentProperties.directional_light()))
# 16. Create a Sphere Entity as a child entity of the Default Level Entity then add a Material component.
sphere_entity = EditorEntity.create_editor_entity_at(
math.Vector3(0.0, 0.0, 1.0), "Sphere", default_level_entity.id)
sphere_material_component = sphere_entity.add_component(MATERIAL_COMPONENT_NAME)
Report.result(Tests.sphere_material_component_added, sphere_entity.has_component(MATERIAL_COMPONENT_NAME))
sphere_material_component = sphere_entity.add_component(AtomComponentProperties.material())
Report.result(Tests.sphere_material_component_added, sphere_entity.has_component(
AtomComponentProperties.material()))
# 17. Set the Material Asset property of the Material component for the Sphere Entity.
sphere_material_asset_path = os.path.join("Materials", "Presets", "PBR", "metal_brass_polished.azmaterial")
sphere_material_asset = asset.AssetCatalogRequestBus(
bus.Broadcast, "GetAssetIdByPath", sphere_material_asset_path, math.Uuid(), False)
sphere_material_asset_property = "Default Material|Material Asset"
sphere_material_component.set_component_property_value(sphere_material_asset_property, sphere_material_asset)
sphere_material_asset = Asset.find_asset_by_path(sphere_material_asset_path, False)
sphere_material_component.set_component_property_value(
AtomComponentProperties.material('Material Asset'), sphere_material_asset.id)
Report.result(Tests.sphere_material_set, sphere_material_component.get_component_property_value(
sphere_material_asset_property) == sphere_material_asset)
AtomComponentProperties.material('Material Asset')) == sphere_material_asset.id)
# 18. Add Mesh component to Sphere Entity and set the Mesh Asset property for the Mesh component.
sphere_mesh_component = sphere_entity.add_component(MESH_COMPONENT_NAME)
sphere_mesh_component = sphere_entity.add_component(AtomComponentProperties.mesh())
sphere_mesh_asset_path = os.path.join("Models", "sphere.azmodel")
sphere_mesh_asset = asset.AssetCatalogRequestBus(
bus.Broadcast, "GetAssetIdByPath", sphere_mesh_asset_path, math.Uuid(), False)
sphere_mesh_asset_property = "Controller|Configuration|Mesh Asset"
sphere_mesh_component.set_component_property_value(sphere_mesh_asset_property, sphere_mesh_asset)
sphere_mesh_asset = Asset.find_asset_by_path(sphere_mesh_asset_path, False)
sphere_mesh_component.set_component_property_value(
AtomComponentProperties.mesh('Mesh Asset'), sphere_mesh_asset.id)
Report.result(Tests.sphere_mesh_asset_set, sphere_mesh_component.get_component_property_value(
sphere_mesh_asset_property) == sphere_mesh_asset)
AtomComponentProperties.mesh('Mesh Asset')) == sphere_mesh_asset.id)
# 19. Create a Camera Entity as a child entity of the Default Level Entity then add a Camera component.
camera_name = "Camera"
camera_entity = EditorEntity.create_editor_entity_at(
math.Vector3(5.5, -12.0, 9.0), camera_name, default_level_entity.id)
camera_component = camera_entity.add_component(camera_name)
Report.result(Tests.camera_component_added, camera_entity.has_component(camera_name))
math.Vector3(5.5, -12.0, 9.0), AtomComponentProperties.camera(), default_level_entity.id)
camera_component = camera_entity.add_component(AtomComponentProperties.camera())
Report.result(Tests.camera_component_added, camera_entity.has_component(AtomComponentProperties.camera()))
# 20. Set the Camera Entity rotation value and set the Camera component Field of View value.
camera_entity_rotation = math.Vector3(
DEGREE_RADIAN_FACTOR * -27.0, DEGREE_RADIAN_FACTOR * -12.0, DEGREE_RADIAN_FACTOR * 25.0)
camera_entity.set_local_rotation(camera_entity_rotation)
camera_fov_property = "Controller|Configuration|Field of view"
camera_fov_value = 60.0
camera_component.set_component_property_value(camera_fov_property, camera_fov_value)
camera_component.set_component_property_value(AtomComponentProperties.camera('Field of view'), camera_fov_value)
azlmbr.camera.EditorCameraViewRequestBus(azlmbr.bus.Event, "ToggleCameraAsActiveView", camera_entity.id)
Report.result(Tests.camera_fov_set, camera_component.get_component_property_value(
camera_fov_property) == camera_fov_value)
AtomComponentProperties.camera('Field of view')) == camera_fov_value)
# 21. Enter game mode.
helper.enter_game_mode(Tests.enter_game_mode)
helper.wait_for_condition(function=lambda: general.is_in_game_mode(), timeout_in_seconds=4.0)
TestHelper.enter_game_mode(Tests.enter_game_mode)
TestHelper.wait_for_condition(function=lambda: general.is_in_game_mode(), timeout_in_seconds=4.0)
# 22. Take screenshot.
ScreenshotHelper(general.idle_wait_frames).capture_screenshot_blocking(f"{SCREENSHOT_NAME}.ppm")
# 23. Exit game mode.
helper.exit_game_mode(Tests.exit_game_mode)
helper.wait_for_condition(function=lambda: not general.is_in_game_mode(), timeout_in_seconds=4.0)
TestHelper.exit_game_mode(Tests.exit_game_mode)
TestHelper.wait_for_condition(function=lambda: not general.is_in_game_mode(), timeout_in_seconds=4.0)
# 24. Look for errors.
helper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
Report.result(Tests.no_assert_occurred, not error_tracer.has_asserts)
Report.result(Tests.no_error_occurred, not error_tracer.has_errors)
TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
for error_info in error_tracer.errors:
Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
for assert_info in error_tracer.asserts:
Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}")
if __name__ == "__main__":
@@ -106,8 +106,7 @@ def run():
components=["HDRi Skybox", "Global Skylight (IBL)"],
parent_id=default_level.id
)
global_skylight_image_asset_path = os.path.join(
"LightingPresets", "greenwich_park_02_4k_iblskyboxcm_iblspecular.exr.streamingimage")
global_skylight_image_asset_path = os.path.join("LightingPresets", "default_iblskyboxcm.exr.streamingimage")
global_skylight_image_asset = asset.AssetCatalogRequestBus(
bus.Broadcast, "GetAssetIdByPath", global_skylight_image_asset_path, math.Uuid(), False)
global_skylight.get_set_test(0, "Controller|Configuration|Cubemap Texture", global_skylight_image_asset)
@@ -23,28 +23,28 @@ from base import TestAutomationBase
class TestAutomation(TestAutomationBase):
def test_ActorSplitsAfterCollision(self, request, workspace, editor, launcher_platform):
from .tests import Blast_ActorSplitsAfterCollision as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ActorSplitsAfterRadialDamage(self, request, workspace, editor, launcher_platform):
from .tests import Blast_ActorSplitsAfterRadialDamage as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ActorSplitsAfterCapsuleDamage(self, request, workspace, editor, launcher_platform):
from .tests import Blast_ActorSplitsAfterCapsuleDamage as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ActorSplitsAfterImpactSpreadDamage(self, request, workspace, editor, launcher_platform):
from .tests import Blast_ActorSplitsAfterImpactSpreadDamage as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ActorSplitsAfterShearDamage(self, request, workspace, editor, launcher_platform):
from .tests import Blast_ActorSplitsAfterShearDamage as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ActorSplitsAfterTriangleDamage(self, request, workspace, editor, launcher_platform):
from .tests import Blast_ActorSplitsAfterTriangleDamage as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ActorSplitsAfterStressDamage(self, request, workspace, editor, launcher_platform):
from .tests import Blast_ActorSplitsAfterStressDamage as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@@ -56,6 +56,9 @@ add_subdirectory(streaming)
## Smoke ##
add_subdirectory(smoke)
## Terrain ##
add_subdirectory(Terrain)
## AWS ##
add_subdirectory(AWS)
@@ -51,5 +51,6 @@ class TestComponentAssetListAutomation(object):
editor,
"ComponentUpdateListProperty_test_case.py",
expected_lines=expected_lines,
cfg_args=[level]
cfg_args=[level],
enable_prefab_system=False,
)
@@ -28,7 +28,7 @@ Assuming CMake is already setup on your operating system, below are some sample
cd /path/to/od3e/
mkdir windows_vs2019
cd windows_vs2019
cmake .. -G "Visual Studio 16 2019" -A x64 -T host=x64 -DLY_3RDPARTY_PATH="%3RDPARTYPATH%" -DLY_PROJECTS=AutomatedTesting
cmake .. -G "Visual Studio 16 2019" -DLY_PROJECTS=AutomatedTesting
To manually install the project in development mode using your own installed Python interpreter:
cd /path/to/od3e/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools
@@ -132,6 +132,7 @@ class EditorEntity:
def __init__(self, id: azlmbr.entity.EntityId):
self.id: azlmbr.entity.EntityId = id
self.components: List[EditorComponent] = []
# Creation functions
@classmethod
@@ -279,7 +280,7 @@ class EditorEntity:
), f"Failure: Could not add component: '{new_comp.get_component_name()}' to entity: '{self.get_name()}'"
new_comp.id = add_component_outcome.GetValue()[0]
components.append(new_comp)
self.components.append(new_comp)
return components
def get_components_of_type(self, component_names: list) -> List[EditorComponent]:
@@ -57,6 +57,10 @@ def add_level_component(component_name):
level_component_list, entity.EntityType().Level)
level_component_outcome = editor.EditorLevelComponentAPIBus(bus.Broadcast, 'AddComponentsOfType',
[level_component_type_ids_list[0]])
if not level_component_outcome.IsSuccess():
print('Failed to add {} level component'.format(component_name))
return None
level_component = level_component_outcome.GetValue()[0]
return level_component
@@ -29,7 +29,7 @@ def teardown_editor(editor):
def launch_and_validate_results(request, test_directory, editor, editor_script, expected_lines, unexpected_lines=[],
halt_on_unexpected=False, run_python="--runpythontest", auto_test_mode=True, null_renderer=True, cfg_args=[],
timeout=300, log_file_name="Editor.log"):
timeout=300, log_file_name="Editor.log", enable_prefab_system=True):
"""
Runs the Editor with the specified script, and monitors for expected log lines.
:param request: Special fixture providing information of the requesting test function.
@@ -45,17 +45,22 @@ def launch_and_validate_results(request, test_directory, editor, editor_script,
:param cfg_args: Additional arguments for CFG, such as LevelName.
:param timeout: Length of time for test to run. Default is 60.
:param log_file_name: Name of the log file created by the editor. Defaults to 'Editor.log'
:param enable_prefab_system: Flag to determine whether to use new prefab system or use deprecated slice system. Defaults to True.
"""
test_case = os.path.join(test_directory, editor_script)
request.addfinalizer(lambda: teardown_editor(editor))
logger.debug("Running automated test: {}".format(editor_script))
editor.args.extend(["--skipWelcomeScreenDialog", "--regset=/Amazon/Settings/EnableSourceControl=false",
"--regset=/Amazon/Preferences/EnablePrefabSystem=false", run_python, test_case,
run_python, test_case,
f"--pythontestcase={request.node.name}", "--runpythonargs", " ".join(cfg_args)])
if auto_test_mode:
editor.args.extend(["--autotest_mode"])
if null_renderer:
editor.args.extend(["-rhi=Null"])
if enable_prefab_system:
editor.args.extend(["--regset=/Amazon/Preferences/EnablePrefabSystem=true"])
else:
editor.args.extend(["--regset=/Amazon/Preferences/EnablePrefabSystem=false"])
with editor.start():
@@ -23,7 +23,6 @@ from base import TestAutomationBase
class TestAutomation(TestAutomationBase):
def _run_prefab_test(self, request, workspace, editor, test_module, batch_mode=True, autotest_mode=True):
self._run_test(request, workspace, editor, test_module,
extra_cmdline_args=["--regset=/Amazon/Preferences/EnablePrefabSystem=true"],
batch_mode=batch_mode,
autotest_mode=autotest_mode)
@@ -24,7 +24,6 @@ from base import TestAutomationBase
class TestAutomation(TestAutomationBase):
def _run_prefab_test(self, request, workspace, editor, test_module, batch_mode=True, autotest_mode=True):
self._run_test(request, workspace, editor, test_module,
extra_cmdline_args=["--regset=/Amazon/Preferences/EnablePrefabSystem=true"],
batch_mode=batch_mode,
autotest_mode=autotest_mode)
@@ -25,8 +25,8 @@ class TestAutomation(TestAutomationBase):
def test_NvCloth_AddClothSimulationToMesh(self, request, workspace, editor, launcher_platform):
from .tests import NvCloth_AddClothSimulationToMesh as test_module
self._run_test(request, workspace, editor, test_module, use_null_renderer = self.use_null_renderer)
self._run_test(request, workspace, editor, test_module, use_null_renderer = self.use_null_renderer, enable_prefab_system=False)
def test_NvCloth_AddClothSimulationToActor(self, request, workspace, editor, launcher_platform):
from .tests import NvCloth_AddClothSimulationToActor as test_module
self._run_test(request, workspace, editor, test_module, use_null_renderer = self.use_null_renderer)
self._run_test(request, workspace, editor, test_module, use_null_renderer = self.use_null_renderer, enable_prefab_system=False)
@@ -26,158 +26,158 @@ class TestAutomation(TestAutomationBase):
r"AutomatedTesting\Levels\Physics\Material_LibraryCrudOperationsReflectOnRagdollBones")
def test_Material_LibraryCrudOperationsReflectOnRagdollBones(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_LibraryCrudOperationsReflectOnRagdollBones as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Material_RagdollBones(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_RagdollBones as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@fm.file_revert("c15308221_material_componentsinsyncwithlibrary.physmaterial",
r"AutomatedTesting\Levels\Physics\Material_ComponentsInSyncWithLibrary")
def test_Material_ComponentsInSyncWithLibrary(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_ComponentsInSyncWithLibrary as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
# BUG: LY-107723")
def test_ScriptCanvas_SetKinematicTargetTransform(self, request, workspace, editor, launcher_platform):
from .tests.script_canvas import ScriptCanvas_SetKinematicTargetTransform as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
# Failing, PhysXTerrain
@fm.file_revert("c4925579_material_addmodifydeleteonterrain.physmaterial",
r"AutomatedTesting\Levels\Physics\Material_LibraryCrudOperationsReflectOnTerrain")
def test_Material_LibraryCrudOperationsReflectOnTerrain(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_LibraryCrudOperationsReflectOnTerrain as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
# Failing, PhysXTerrain
def test_Terrain_TerrainTexturePainterWorks(self, request, workspace, editor, launcher_platform):
from .tests.terrain import Terrain_TerrainTexturePainterWorks as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
# Failing, PhysXTerrain
def test_Material_CanBeAssignedToTerrain(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_CanBeAssignedToTerrain as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
# Failing, PhysXTerrain
def test_Material_DefaultLibraryConsistentOnAllFeatures(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_DefaultLibraryConsistentOnAllFeatures as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
# Failing, PhysXTerrain
@fm.file_revert("all_ones_1.physmaterial", r"AutomatedTesting\Levels\Physics\Material_DefaultMaterialLibraryChangesWork")
@fm.file_override("default.physxconfiguration", "Material_DefaultMaterialLibraryChangesWork.physxconfiguration", "AutomatedTesting")
def test_Material_DefaultMaterialLibraryChangesWork(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_DefaultMaterialLibraryChangesWork as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Collider_SameCollisionGroupSameLayerCollide(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_SameCollisionGroupSameLayerCollide as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Ragdoll_OldRagdollSerializationNoErrors(self, request, workspace, editor, launcher_platform):
from .tests.ragdoll import Ragdoll_OldRagdollSerializationNoErrors as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@fm.file_override("default.physxconfiguration", "ScriptCanvas_OverlapNode.physxconfiguration")
def test_ScriptCanvas_OverlapNode(self, request, workspace, editor, launcher_platform):
from .tests.script_canvas import ScriptCanvas_OverlapNode as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Material_StaticFriction(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_StaticFriction as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@fm.file_revert("c4888315_material_addmodifydeleteoncollider.physmaterial",
r"AutomatedTesting\Levels\Physics\Material_LibraryCrudOperationsReflectOnCollider")
def test_Material_LibraryCrudOperationsReflectOnCollider(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_LibraryCrudOperationsReflectOnCollider as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@fm.file_revert("c15563573_material_addmodifydeleteoncharactercontroller.physmaterial",
r"AutomatedTesting\Levels\Physics\Material_LibraryCrudOperationsReflectOnCharacterController")
def test_Material_LibraryCrudOperationsReflectOnCharacterController(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_LibraryCrudOperationsReflectOnCharacterController as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@fm.file_revert("c4888315_material_addmodifydeleteoncollider.physmaterial",
r"AutomatedTesting\Levels\Physics\Material_LibraryCrudOperationsReflectOnCollider")
def test_Material_LibraryCrudOperationsReflectOnCollider(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_LibraryCrudOperationsReflectOnCollider as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@fm.file_revert("c15563573_material_addmodifydeleteoncharactercontroller.physmaterial",
r"AutomatedTesting\Levels\Physics\Material_LibraryCrudOperationsReflectOnCharacterController")
def test_Material_LibraryCrudOperationsReflectOnCharacterController(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_LibraryCrudOperationsReflectOnCharacterController as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@fm.file_revert("c4044455_material_librarychangesinstantly.physmaterial",
r"AutomatedTesting\Levels\Physics\C4044455_Material_LibraryChangesInstantly")
def test_Material_LibraryChangesReflectInstantly(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_LibraryChangesReflectInstantly as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@fm.file_revert("Material_LibraryUpdatedAcrossLevels.physmaterial",
r"AutomatedTesting\Levels\Physics\Material_LibraryUpdatedAcrossLevels")
def test_Material_LibraryUpdatedAcrossLevels(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_LibraryUpdatedAcrossLevels as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_RigidBody_LinearDampingAffectsMotion(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_LinearDampingAffectsMotion as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Terrain_CollisionAgainstRigidBody(self, request, workspace, editor, launcher_platform):
from .tests.terrain import Terrain_CollisionAgainstRigidBody as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ShapeCollider_CylinderShapeCollides(self, request, workspace, editor, launcher_platform):
from .tests.collider import ShapeCollider_CylinderShapeCollides as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Physics_WorldBodyBusWorksOnEditorComponents(self, request, workspace, editor, launcher_platform):
from .tests import Physics_WorldBodyBusWorksOnEditorComponents as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Collider_PxMeshErrorIfNoMesh(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_PxMeshErrorIfNoMesh as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ForceRegion_ImpulsesBoxShapedRigidBody(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_ImpulsesBoxShapedRigidBody as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Terrain_SpawnSecondTerrainComponentWarning(self, request, workspace, editor, launcher_platform):
from .tests.terrain import Terrain_SpawnSecondTerrainComponentWarning as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Terrain_AddPhysTerrainComponent(self, request, workspace, editor, launcher_platform):
from .tests.terrain import Terrain_AddPhysTerrainComponent as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Terrain_CanAddMultipleTerrainComponents(self, request, workspace, editor, launcher_platform):
from .tests.terrain import Terrain_CanAddMultipleTerrainComponents as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Terrain_MultipleTerrainComponentsWarning(self, request, workspace, editor, launcher_platform):
from .tests.terrain import Terrain_MultipleTerrainComponentsWarning as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Terrain_MultipleTerrainComponentsWarning(self, request, workspace, editor, launcher_platform):
from .tests.terrain import Terrain_MultipleTerrainComponentsWarning as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ForceRegion_HighValuesDirectionAxesWorkWithNoError(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_HighValuesDirectionAxesWorkWithNoError as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Terrain_MultipleResolutionsValid(self, request, workspace, editor, launcher_platform):
from .tests.terrain import Terrain_MultipleResolutionsValid as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ForceRegion_SmallMagnitudeDeviationOnLargeForces(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_SmallMagnitudeDeviationOnLargeForces as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@@ -30,33 +30,33 @@ class TestAutomation(TestAutomationBase):
def test_RigidBody_EnablingGravityWorksUsingNotificationsPoC(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_EnablingGravityWorksUsingNotificationsPoC as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_LocalSpaceForceOnRigidBodies(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_LocalSpaceForceOnRigidBodies as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
@fm.file_override('physxsystemconfiguration.setreg','Material_DynamicFriction.setreg_override',
'AutomatedTesting/Registry', search_subdirs=True)
def test_Material_DynamicFriction(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_DynamicFriction as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_Collider_SameCollisionGroupDiffLayersCollide(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_SameCollisionGroupDiffLayersCollide as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_CharacterController_SwitchLevels(self, request, workspace, editor, launcher_platform):
from .tests.character_controller import CharacterController_SwitchLevels as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Ragdoll_AddPhysxRagdollComponentWorks(self, request, workspace, editor, launcher_platform):
from .tests.ragdoll import Ragdoll_AddPhysxRagdollComponentWorks as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ScriptCanvas_MultipleRaycastNode(self, request, workspace, editor, launcher_platform):
@@ -64,31 +64,43 @@ class TestAutomation(TestAutomationBase):
# Fixme: This test previously relied on unexpected lines log reading with is now not supported.
# Now the log reading must be done inside the test, preferably with the Tracer() utility
# unexpected_lines = ["Assert"] + test_module.Lines.unexpected
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
@fm.file_override('physxsystemconfiguration.setreg','Collider_DiffCollisionGroupDiffCollidingLayersNotCollide.setreg_override',
'AutomatedTesting/Registry', search_subdirs=True)
def test_Collider_DiffCollisionGroupDiffCollidingLayersNotCollide(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_DiffCollisionGroupDiffCollidingLayersNotCollide as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_Joints_HingeLeadFollowerCollide(self, request, workspace, editor, launcher_platform):
from .tests.joints import Joints_HingeLeadFollowerCollide as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_Collider_PxMeshConvexMeshCollides(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_PxMeshConvexMeshCollides as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ShapeCollider_CylinderShapeCollides(self, request, workspace, editor, launcher_platform):
from .tests.shape_collider import ShapeCollider_CylinderShapeCollides as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_C15425929_Undo_Redo(self, request, workspace, editor, launcher_platform):
from .tests import Physics_UndoRedoWorksOnEntityWithPhysComponents as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.GROUP_tick
@pytest.mark.xfail(reason="Test still under development.")
def test_Tick_InterpolatedRigidBodyMotionIsSmooth(self, request, workspace, editor, launcher_platform):
from .tests.tick import Tick_InterpolatedRigidBodyMotionIsSmooth as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.GROUP_tick
@pytest.mark.xfail(reason="Test still under development.")
def test_Tick_CharacterGameplayComponentMotionIsSmooth(self, request, workspace, editor, launcher_platform):
from .tests.tick import Tick_CharacterGameplayComponentMotionIsSmooth as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@@ -59,9 +59,6 @@ class EditorSingleTest_WithFileOverrides(EditorSingleTest):
@pytest.mark.parametrize("project", ["AutomatedTesting"])
class TestAutomationWithPrefabSystemEnabled(EditorTestSuite):
global_extra_cmdline_args = ['-BatchMode', '-autotest_mode',
'extra_cmdline_args=["--regset=/Amazon/Preferences/EnablePrefabSystem=true"]']
@staticmethod
def get_number_parallel_editors():
return 16
@@ -81,6 +78,8 @@ class TestAutomationWithPrefabSystemEnabled(EditorTestSuite):
@pytest.mark.parametrize("project", ["AutomatedTesting"])
class TestAutomation(EditorTestSuite):
enable_prefab_system = False
@staticmethod
def get_number_parallel_editors():
return 16
@@ -31,223 +31,223 @@ class TestAutomation(TestAutomationBase):
@revert_physics_config
def test_Terrain_NoPhysTerrainComponentNoCollision(self, request, workspace, editor, launcher_platform):
from .tests.terrain import Terrain_NoPhysTerrainComponentNoCollision as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_RigidBody_InitialLinearVelocity(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_InitialLinearVelocity as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_RigidBody_StartGravityEnabledWorks(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_StartGravityEnabledWorks as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_RigidBody_KinematicModeWorks(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_KinematicModeWorks as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_LinearDampingForceOnRigidBodies(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_LinearDampingForceOnRigidBodies as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_SimpleDragForceOnRigidBodies(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_SimpleDragForceOnRigidBodies as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_CapsuleShapedForce(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_CapsuleShapedForce as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_ImpulsesCapsuleShapedRigidBody(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_ImpulsesCapsuleShapedRigidBody as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_RigidBody_MomentOfInertiaManualSetting(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_MomentOfInertiaManualSetting as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_RigidBody_COM_ManualSettingWorks(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_COM_ManualSettingWorks as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_RigidBody_AddRigidBodyComponent(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_AddRigidBodyComponent as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_SplineForceOnRigidBodies(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_SplineForceOnRigidBodies as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
@fm.file_override('physxsystemconfiguration.setreg','Material_RestitutionCombine.setreg_override',
'AutomatedTesting/Registry', search_subdirs=True)
def test_Material_RestitutionCombine(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_RestitutionCombine as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
@fm.file_override('physxsystemconfiguration.setreg','Material_FrictionCombine.setreg_override',
'AutomatedTesting/Registry', search_subdirs=True)
def test_Material_FrictionCombine(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_FrictionCombine as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_Collider_ColliderPositionOffset(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_ColliderPositionOffset as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_RigidBody_AngularDampingAffectsRotation(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_AngularDampingAffectsRotation as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_Physics_VerifyColliderRigidBodyMeshAndTerrainWorkTogether(self, request, workspace, editor, launcher_platform):
from .tests import Physics_VerifyColliderRigidBodyMeshAndTerrainWorkTogether as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_MultipleForcesInSameComponentCombineForces(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_MultipleForcesInSameComponentCombineForces as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_ImpulsesPxMeshShapedRigidBody(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_ImpulsesPxMeshShapedRigidBody as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ScriptCanvas_TriggerEvents(self, request, workspace, editor, launcher_platform):
from .tests.script_canvas import ScriptCanvas_TriggerEvents as test_module
# FIXME: expected_lines = test_module.LogLines.expected_lines
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_ZeroPointForceDoesNothing(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_ZeroPointForceDoesNothing as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_ZeroWorldSpaceForceDoesNothing(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_ZeroWorldSpaceForceDoesNothing as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_ZeroLinearDampingDoesNothing(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_ZeroLinearDampingDoesNothing as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_MovingForceRegionChangesNetForce(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_MovingForceRegionChangesNetForce as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ScriptCanvas_CollisionEvents(self, request, workspace, editor, launcher_platform):
from .tests.script_canvas import ScriptCanvas_CollisionEvents as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_DirectionHasNoAffectOnTotalForce(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_DirectionHasNoAffectOnTotalForce as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_RigidBody_StartAsleepWorks(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_StartAsleepWorks as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_SliceFileInstantiates(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_SliceFileInstantiates as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_ZeroLocalSpaceForceDoesNothing(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_ZeroLocalSpaceForceDoesNothing as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_ZeroSimpleDragForceDoesNothing(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_ZeroSimpleDragForceDoesNothing as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_RigidBody_COM_ComputingWorks(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_COM_ComputingWorks as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_RigidBody_MassDifferentValuesWorks(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_MassDifferentValuesWorks as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
@fm.file_override('physxsystemconfiguration.setreg','Material_RestitutionCombinePriorityOrder.setreg_override',
'AutomatedTesting/Registry', search_subdirs=True)
def test_Material_RestitutionCombinePriorityOrder(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_RestitutionCombinePriorityOrder as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_SplineRegionWithModifiedTransform(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_SplineRegionWithModifiedTransform as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ScriptCanvas_ShapeCast(self, request, workspace, editor, launcher_platform):
from .tests.script_canvas import ScriptCanvas_ShapeCast as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_RigidBody_InitialAngularVelocity(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_InitialAngularVelocity as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_ZeroSplineForceDoesNothing(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_ZeroSplineForceDoesNothing as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_Physics_DynamicSliceWithPhysNotSpawnsStaticSlice(self, request, workspace, editor, launcher_platform):
from .tests import Physics_DynamicSliceWithPhysNotSpawnsStaticSlice as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_PositionOffset(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_PositionOffset as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
@fm.file_override('physxsystemconfiguration.setreg','Material_FrictionCombinePriorityOrder.setreg_override',
'AutomatedTesting/Registry', search_subdirs=True)
def test_Material_FrictionCombinePriorityOrder(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_FrictionCombinePriorityOrder as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.xfail(
reason="Something with the CryRenderer disabling is causing this test to fail now.")
@revert_physics_config
def test_Ragdoll_LevelSwitchDoesNotCrash(self, request, workspace, editor, launcher_platform):
from .tests.ragdoll import Ragdoll_LevelSwitchDoesNotCrash as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_MultipleComponentsCombineForces(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_MultipleComponentsCombineForces as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
# Marking the test as an expected failure due to sporadic failure on Automated Review: LYN-2580
# The test still runs, but a failure of the test doesn't result in the test run failing
@@ -258,102 +258,102 @@ class TestAutomation(TestAutomationBase):
'AutomatedTesting/Registry', search_subdirs=True)
def test_Material_PerFaceMaterialGetsCorrectMaterial(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_PerFaceMaterialGetsCorrectMaterial as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.xfail(
reason="This test will sometimes fail as the ball will continue to roll before the timeout is reached.")
@revert_physics_config
def test_RigidBody_SleepWhenBelowKineticThreshold(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_SleepWhenBelowKineticThreshold as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_RigidBody_COM_NotIncludesTriggerShapes(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_COM_NotIncludesTriggerShapes as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_Material_NoEffectIfNoColliderShape(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_NoEffectIfNoColliderShape as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_Collider_TriggerPassThrough(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_TriggerPassThrough as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_RigidBody_SetGravityWorks(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_SetGravityWorks as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
@fm.file_override('physxsystemconfiguration.setreg','Material_CharacterController.setreg_override',
'AutomatedTesting/Registry', search_subdirs=True)
def test_Material_CharacterController(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_CharacterController as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_Material_EmptyLibraryUsesDefault(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_EmptyLibraryUsesDefault as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_NoQuiverOnHighLinearDampingForce(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_NoQuiverOnHighLinearDampingForce as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_RigidBody_ComputeInertiaWorks(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_ComputeInertiaWorks as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ScriptCanvas_PostPhysicsUpdate(self, request, workspace, editor, launcher_platform):
from .tests.script_canvas import ScriptCanvas_PostPhysicsUpdate as test_module
# Fixme: unexpected_lines = ["Assert"] + test_module.Lines.unexpected
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
@fm.file_override('physxsystemconfiguration.setreg','Collider_NoneCollisionGroupSameLayerNotCollide.setreg_override',
'AutomatedTesting/Registry', search_subdirs=True)
def test_Collider_NoneCollisionGroupSameLayerNotCollide(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_NoneCollisionGroupSameLayerNotCollide as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
@fm.file_override('physxsystemconfiguration.setreg','Collider_SameCollisionGroupSameCustomLayerCollide.setreg_override',
'AutomatedTesting/Registry', search_subdirs=True)
def test_Collider_SameCollisionGroupSameCustomLayerCollide(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_SameCollisionGroupSameCustomLayerCollide as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
@fm.file_override('physxdefaultsceneconfiguration.setreg','ScriptCanvas_PostUpdateEvent.setreg_override',
'AutomatedTesting/Registry', search_subdirs=True)
def test_ScriptCanvas_PostUpdateEvent(self, request, workspace, editor, launcher_platform):
from .tests.script_canvas import ScriptCanvas_PostUpdateEvent as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
@fm.file_override('physxsystemconfiguration.setreg','Material_Restitution.setreg_override',
'AutomatedTesting/Registry', search_subdirs=True)
def test_Material_Restitution(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_Restitution as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
@fm.file_override('physxdefaultsceneconfiguration.setreg', 'ScriptCanvas_PreUpdateEvent.setreg_override',
'AutomatedTesting/Registry', search_subdirs=True)
def test_ScriptCanvas_PreUpdateEvent(self, request, workspace, editor, launcher_platform):
from .tests.script_canvas import ScriptCanvas_PreUpdateEvent as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_PxMeshShapedForce(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_PxMeshShapedForce as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
# Marking the Test as expected to fail using the xfail decorator due to sporadic failure on Automated Review: SPEC-3146
# The test still runs, but a failure of the test doesn't result in the test run failing
@@ -361,176 +361,173 @@ class TestAutomation(TestAutomationBase):
@revert_physics_config
def test_RigidBody_MaxAngularVelocityWorks(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_MaxAngularVelocityWorks as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_Joints_HingeSoftLimitsConstrained(self, request, workspace, editor, launcher_platform):
from .tests.joints import Joints_HingeSoftLimitsConstrained as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_Joints_BallSoftLimitsConstrained(self, request, workspace, editor, launcher_platform):
from .tests.joints import Joints_BallSoftLimitsConstrained as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_Joints_BallLeadFollowerCollide(self, request, workspace, editor, launcher_platform):
from .tests.joints import Joints_BallLeadFollowerCollide as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
@fm.file_override('physxsystemconfiguration.setreg','Collider_AddingNewGroupWorks.setreg_override',
'AutomatedTesting/Registry', search_subdirs=True)
def test_Collider_AddingNewGroupWorks(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_AddingNewGroupWorks as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ShapeCollider_InactiveWhenNoShapeComponent(self, request, workspace, editor, launcher_platform):
from .tests.shape_collider import ShapeCollider_InactiveWhenNoShapeComponent as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_Collider_CheckDefaultShapeSettingIsPxMesh(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_CheckDefaultShapeSettingIsPxMesh as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ShapeCollider_LargeNumberOfShapeCollidersWontCrashEditor(self, request, workspace, editor, launcher_platform):
from .tests.shape_collider import ShapeCollider_LargeNumberOfShapeCollidersWontCrashEditor as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_Collider_SphereShapeEditing(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_SphereShapeEditing as test_module
self._run_test(request, workspace, editor, test_module,
extra_cmdline_args=["--regset=/Amazon/Preferences/EnablePrefabSystem=true"])
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_Collider_BoxShapeEditing(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_BoxShapeEditing as test_module
self._run_test(request, workspace, editor, test_module,
extra_cmdline_args=["--regset=/Amazon/Preferences/EnablePrefabSystem=true"])
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_Collider_CapsuleShapeEditing(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_CapsuleShapeEditing as test_module
self._run_test(request, workspace, editor, test_module,
extra_cmdline_args=["--regset=/Amazon/Preferences/EnablePrefabSystem=true"])
self._run_test(request, workspace, editor, test_module)
def test_ForceRegion_WithNonTriggerColliderWarning(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_WithNonTriggerColliderWarning as test_module
# Fixme: expected_lines = ["[Warning] (PhysX Force Region) - Please ensure collider component marked as trigger exists in entity"]
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ForceRegion_WorldSpaceForceOnRigidBodies(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_WorldSpaceForceOnRigidBodies as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ForceRegion_PointForceOnRigidBodies(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_PointForceOnRigidBodies as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ForceRegion_SphereShapedForce(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_SphereShapedForce as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ForceRegion_RotationalOffset(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_RotationalOffset as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Material_LibraryClearingAssignsDefault(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_LibraryClearingAssignsDefault as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Collider_AddColliderComponent(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_AddColliderComponent as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.xfail(
reason="This will fail due to this issue ATOM-15487.")
def test_Collider_PxMeshAutoAssignedWhenModifyingRenderMeshComponent(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_PxMeshAutoAssignedWhenModifyingRenderMeshComponent as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Collider_PxMeshAutoAssignedWhenAddingRenderMeshComponent(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_PxMeshAutoAssignedWhenAddingRenderMeshComponent as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Collider_MultipleSurfaceSlots(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_MultipleSurfaceSlots as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Collider_PxMeshNotAutoAssignedWhenNoPhysicsFbx(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_PxMeshNotAutoAssignedWhenNoPhysicsFbx as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_RigidBody_EnablingGravityWorksPoC(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_EnablingGravityWorksPoC as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
@fm.file_override('physxsystemconfiguration.setreg','Collider_CollisionGroupsWorkflow.setreg_override',
'AutomatedTesting/Registry', search_subdirs=True)
def test_Collider_CollisionGroupsWorkflow(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_CollisionGroupsWorkflow as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_Collider_ColliderRotationOffset(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_ColliderRotationOffset as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_ParentChildForcesCombineForces(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_ParentChildForcesCombineForces as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ShapeCollider_CanBeAddedWitNoWarnings(self, request, workspace, editor, launcher_platform):
from .tests.shape_collider import ShapeCollider_CanBeAddedWitNoWarnings as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_Physics_UndoRedoWorksOnEntityWithPhysComponents(self, request, workspace, editor, launcher_platform):
from .tests import Physics_UndoRedoWorksOnEntityWithPhysComponents as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Joints_Fixed2BodiesConstrained(self, request, workspace, editor, launcher_platform):
from .tests.joints import Joints_Fixed2BodiesConstrained as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Joints_Hinge2BodiesConstrained(self, request, workspace, editor, launcher_platform):
from .tests.joints import Joints_Hinge2BodiesConstrained as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Joints_Ball2BodiesConstrained(self, request, workspace, editor, launcher_platform):
from .tests.joints import Joints_Ball2BodiesConstrained as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Joints_FixedBreakable(self, request, workspace, editor, launcher_platform):
from .tests.joints import Joints_FixedBreakable as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Joints_HingeBreakable(self, request, workspace, editor, launcher_platform):
from .tests.joints import Joints_HingeBreakable as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Joints_BallBreakable(self, request, workspace, editor, launcher_platform):
from .tests.joints import Joints_BallBreakable as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Joints_HingeNoLimitsConstrained(self, request, workspace, editor, launcher_platform):
from .tests.joints import Joints_HingeNoLimitsConstrained as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Joints_BallNoLimitsConstrained(self, request, workspace, editor, launcher_platform):
from .tests.joints import Joints_BallNoLimitsConstrained as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Joints_GlobalFrameConstrained(self, request, workspace, editor, launcher_platform):
from .tests.joints import Joints_GlobalFrameConstrained as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_Material_DefaultLibraryUpdatedAcrossLevels(self, request, workspace, editor, launcher_platform):
@@ -540,7 +537,7 @@ class TestAutomation(TestAutomationBase):
search_subdirs=True)
def levels_before(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_DefaultLibraryUpdatedAcrossLevels_before as test_module_0
self._run_test(request, workspace, editor, test_module_0)
self._run_test(request, workspace, editor, test_module_0, enable_prefab_system=False)
# File override replaces the previous physxconfiguration file with another where the only difference is the default material library
@fm.file_override("physxsystemconfiguration.setreg",
@@ -549,7 +546,7 @@ class TestAutomation(TestAutomationBase):
search_subdirs=True)
def levels_after(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_DefaultLibraryUpdatedAcrossLevels_after as test_module_1
self._run_test(request, workspace, editor, test_module_1)
self._run_test(request, workspace, editor, test_module_1, enable_prefab_system=False)
levels_before(self, request, workspace, editor, launcher_platform)
levels_after(self, request, workspace, editor, launcher_platform)
@@ -32,7 +32,7 @@ class TestAutomation(TestAutomationBase):
def test_ScriptCanvas_GetCollisionNameReturnsName(self, request, workspace, editor, launcher_platform):
from .tests.script_canvas import ScriptCanvas_GetCollisionNameReturnsName as test_module
# Fixme: expected_lines=["Layer Name: Right"]
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
## Seems to be flaky, need to investigate
def test_ScriptCanvas_GetCollisionNameReturnsNothingWhenHasToggledLayer(self, request, workspace, editor, launcher_platform):
@@ -42,4 +42,4 @@ class TestAutomation(TestAutomationBase):
# Fixme: for group in collision_groups:
# Fixme: unexpected_lines.append(f"GroupName: {group}")
# Fixme: expected_lines=["GroupName: "]
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@@ -30,11 +30,11 @@ class TestUtils(TestAutomationBase):
expected_lines = []
unexpected_lines = ["Assert"]
self._run_test(request, workspace, editor, physmaterial_editor_test_module, expected_lines, unexpected_lines)
self._run_test(request, workspace, editor, physmaterial_editor_test_module, expected_lines, unexpected_lines, enable_prefab_system=False)
def test_UtilTest_Tracer_PicksErrorsAndWarnings(self, request, workspace, launcher_platform, editor):
from .utils import UtilTest_Tracer_PicksErrorsAndWarnings as testcase_module
self._run_test(request, workspace, editor, testcase_module, [], [])
self._run_test(request, workspace, editor, testcase_module, [], [], enable_prefab_system=False)
def test_FileManagement_FindingFiles(self, workspace, launcher_platform):
"""
@@ -263,4 +263,4 @@ class TestUtils(TestAutomationBase):
expected_lines = []
unexpected_lines = ["Assert"]
self._run_test(request, workspace, editor, test_module, expected_lines, unexpected_lines)
self._run_test(request, workspace, editor, test_module, expected_lines, unexpected_lines, enable_prefab_system=False)
@@ -0,0 +1,99 @@
"""
Copyright (c) Contributors to the Open 3D Engine Project.
For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT
Test Case Title : Verify that an entity with a character gameplay component moves smoothly.
"""
# fmt: off
class Tests():
create_entity = ("Created test entity", "Failed to create test entity")
character_controller_added = ("Added PhysX Character Controller component", "Failed to add PhysX Character Controller component")
character_gameplay_added = ("Added PhysX Character Gameplay component", "Failed to add PhysX Character Gameplay component")
enter_game_mode = ("Entered game mode", "Failed to enter game mode")
exit_game_mode = ("Exited game mode", "Failed to exit game mode")
character_motion_smooth = ("Character motion passed smoothness threshold", "Failed to meet smoothness threshold for character motion")
# fmt: on
def Tick_CharacterGameplayComponentMotionIsSmooth():
"""
Summary:
Create entity with PhysX Character Controller and PhysX Character Gameplay components.
Verify that the motion of the character controller under gravity is smooth.
Expected Behavior:
1) The motion of the character controller under gravity is a smooth curve, rather than an erratic/jittery movement.
Test Steps:
1) Load the empty level
2) Create an entity
3) Add a PhysX Character Controller Component and PhysX Character Gameplay component
4) Enter game mode and collect data for the character controller's z co-ordinate and the time values for a series of frames
5) Check if the motion of the character controller was sufficiently smooth
:return: None
"""
# imports
import os
import azlmbr.legacy.general as general
import azlmbr.math as math
from editor_python_test_tools.editor_entity_utils import EditorEntity as Entity
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
from editor_python_test_tools.asset_utils import Asset
import numpy as np
# constants
COEFFICIENT_OF_DETERMINATION_THRESHOLD = 1 - 1e-4 # curves with values below this are not considered sufficiently smooth
helper.init_idle()
# 1) Load the empty level
helper.open_level("", "Base")
# 2) Create an entity
test_entity = Entity.create_editor_entity("test_entity")
Report.result(Tests.create_entity, test_entity.id.IsValid())
azlmbr.components.TransformBus(
azlmbr.bus.Event, "SetWorldTranslation", test_entity.id, math.Vector3(0.0, 0.0, 0.0))
# 3) Add character controller and character gameplay components
character_controller_component = test_entity.add_component("PhysX Character Controller")
Report.result(Tests.character_controller_added, test_entity.has_component("PhysX Character Controller"))
character_gameplay_component = test_entity.add_component("PhysX Character Gameplay")
Report.result(Tests.character_gameplay_added, test_entity.has_component("PhysX Character Gameplay"))
# 4) Enter game mode and collect data for the rigid body's z co-ordinate and the time values for a series of frames
t = []
z = []
helper.enter_game_mode(Tests.enter_game_mode)
general.idle_wait_frames(1)
game_entity_id = general.find_game_entity("test_entity")
for frame in range(100):
t.append(azlmbr.components.TickRequestBus(azlmbr.bus.Broadcast, "GetTimeAtCurrentTick").GetSeconds())
z.append(azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldZ", game_entity_id))
general.idle_wait_frames(1)
helper.exit_game_mode(Tests.exit_game_mode)
# 5) Test that the z vs t curve is sufficiently smooth (if the interpolation is not working well, the curve will be less smooth)
# normalize the t and z data
t = np.array(t) - np.mean(t)
z = np.array(z) - np.mean(z)
# fit a polynomial to the z vs t curve
fit = np.poly1d(np.polyfit(t, z, 4))
residual = fit(t) - z
# calculate the coefficient of determination (a measure of how closely the polynomial curve fits the data)
# if the coefficient is very close to 1, then the curve fits the data very well, suggesting that the rigid body motion is smooth
# if the coefficient is significantly less than 1, then the z values vary more erratically relative to the smooth curve,
# indicating that the motion of the rigid body is not smooth
coefficient_of_determination = (1 - np.sum(residual * residual) / np.sum(z * z))
Report.result(Tests.character_motion_smooth, bool(coefficient_of_determination > COEFFICIENT_OF_DETERMINATION_THRESHOLD))
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(Tick_CharacterGameplayComponentMotionIsSmooth)
@@ -0,0 +1,98 @@
"""
Copyright (c) Contributors to the Open 3D Engine Project.
For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT
Test Case Title : Verify that a rigid body with "Interpolate motion" option selected moves smoothly.
"""
# fmt: off
class Tests():
create_entity = ("Created test entity", "Failed to create test entity")
rigid_body_added = ("Added PhysX Rigid Body component", "Failed to add PhysX Rigid Body component")
enter_game_mode = ("Entered game mode", "Failed to enter game mode")
exit_game_mode = ("Exited game mode", "Failed to exit game mode")
rigid_body_smooth = ("Rigid body motion passed smoothness threshold", "Failed to meet smoothness threshold for rigid body motion")
# fmt: on
def Tick_InterpolatedRigidBodyMotionIsSmooth():
"""
Summary:
Create entity with PhysX Rigid Body component and turn on the Interpolate motion setting.
Verify that the position of the rigid body varies smoothly with time.
Expected Behavior:
1) The motion of the rigid body under gravity is a smooth curve, rather than an erratic/jittery movement.
Test Steps:
1) Load the empty level
2) Create an entity
3) Add rigid body component
4) Enter game mode and collect data for the rigid body's z co-ordinate and the time values for a series of frames
5) Check if the motion of the rigid body was sufficiently smooth
:return: None
"""
# imports
import os
import azlmbr.legacy.general as general
import azlmbr.math as math
from editor_python_test_tools.editor_entity_utils import EditorEntity as Entity
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
from editor_python_test_tools.asset_utils import Asset
import numpy as np
# constants
COEFFICIENT_OF_DETERMINATION_THRESHOLD = 1 - 1e-4 # curves with values below this are not considered sufficiently smooth
helper.init_idle()
# 1) Load the empty level
helper.open_level("", "Base")
# 2) Create an entity
test_entity = Entity.create_editor_entity("test_entity")
Report.result(Tests.create_entity, test_entity.id.IsValid())
azlmbr.components.TransformBus(
azlmbr.bus.Event, "SetWorldTranslation", test_entity.id, math.Vector3(0.0, 0.0, 0.0))
# 3) Add rigid body component
rigid_body_component = test_entity.add_component("PhysX Rigid Body")
rigid_body_component.set_component_property_value("Configuration|Interpolate motion", True)
azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "SetLinearDamping", test_entity.id, 0.0)
Report.result(Tests.rigid_body_added, test_entity.has_component("PhysX Rigid Body"))
# 4) Enter game mode and collect data for the rigid body's z co-ordinate and the time values for a series of frames
t = []
z = []
helper.enter_game_mode(Tests.enter_game_mode)
general.idle_wait_frames(1)
game_entity_id = general.find_game_entity("test_entity")
for frame in range(100):
t.append(azlmbr.components.TickRequestBus(azlmbr.bus.Broadcast, "GetTimeAtCurrentTick").GetSeconds())
z.append(azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldZ", game_entity_id))
general.idle_wait_frames(1)
helper.exit_game_mode(Tests.exit_game_mode)
# 5) Test that the z vs t curve is sufficiently smooth (if the interpolation is not working well, the curve will be less smooth)
# normalize the t and z data
t = np.array(t) - np.mean(t)
z = np.array(z) - np.mean(z)
# fit a polynomial to the z vs t curve
fit = np.poly1d(np.polyfit(t, z, 4))
residual = fit(t) - z
# calculate the coefficient of determination (a measure of how closely the polynomial curve fits the data)
# if the coefficient is very close to 1, then the curve fits the data very well, suggesting that the rigid body motion is smooth
# if the coefficient is significantly less than 1, then the z values vary more erratically relative to the smooth curve,
# indicating that the motion of the rigid body is not smooth
coefficient_of_determination = (1 - np.sum(residual * residual) / np.sum(z * z))
Report.result(Tests.rigid_body_smooth, bool(coefficient_of_determination > COEFFICIENT_OF_DETERMINATION_THRESHOLD))
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(Tick_InterpolatedRigidBodyMotionIsSmooth)
@@ -218,6 +218,7 @@ class FileManagement:
src_file_path = os.path.join(src_path, src_file)
if os.path.exists(target_file_path):
fs.unlock_file(target_file_path)
os.makedirs(target_path, exist_ok=True)
shutil.copyfile(src_file_path, target_file_path)
@staticmethod
@@ -12,7 +12,6 @@ import pytest
import os
import sys
from ly_test_tools import LAUNCHERS
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../automatedtesting_shared')
from base import TestAutomationBase
@@ -24,42 +23,41 @@ class TestAutomation(TestAutomationBase):
def _run_prefab_test(self, request, workspace, editor, test_module, batch_mode=True, autotest_mode=True):
self._run_test(request, workspace, editor, test_module,
extra_cmdline_args=["--regset=/Amazon/Preferences/EnablePrefabSystem=true"],
batch_mode=batch_mode,
autotest_mode=autotest_mode)
def test_PrefabLevel_OpensLevelWithEntities(self, request, workspace, editor, launcher_platform):
from .tests import PrefabLevel_OpensLevelWithEntities as test_module
def test_OpenLevel_ContainingTwoEntities(self, request, workspace, editor, launcher_platform):
from Prefab.tests.open_level import OpenLevel_ContainingTwoEntities as test_module
self._run_prefab_test(request, workspace, editor, test_module)
def test_PrefabBasicWorkflow_CreatePrefab(self, request, workspace, editor, launcher_platform):
from .tests import PrefabBasicWorkflow_CreatePrefab as test_module
def test_CreatePrefab_WithSingleEntity(self, request, workspace, editor, launcher_platform):
from Prefab.tests.create_prefab import CreatePrefab_WithSingleEntity as test_module
self._run_prefab_test(request, workspace, editor, test_module)
def test_PrefabBasicWorkflow_InstantiatePrefab(self, request, workspace, editor, launcher_platform):
from .tests import PrefabBasicWorkflow_InstantiatePrefab as test_module
def test_InstantiatePrefab_ContainingASingleEntity(self, request, workspace, editor, launcher_platform):
from Prefab.tests.instantiate_prefab import InstantiatePrefab_ContainingASingleEntity as test_module
self._run_prefab_test(request, workspace, editor, test_module)
def test_PrefabBasicWorkflow_CreateAndDeletePrefab(self, request, workspace, editor, launcher_platform):
from .tests import PrefabBasicWorkflow_CreateAndDeletePrefab as test_module
def test_DeletePrefab_ContainingASingleEntity(self, request, workspace, editor, launcher_platform):
from Prefab.tests.delete_prefab import DeletePrefab_ContainingASingleEntity as test_module
self._run_prefab_test(request, workspace, editor, test_module)
def test_PrefabBasicWorkflow_CreateAndReparentPrefab(self, request, workspace, editor, launcher_platform):
from .tests import PrefabBasicWorkflow_CreateAndReparentPrefab as test_module
def test_ReparentPrefab_UnderAnotherPrefab(self, request, workspace, editor, launcher_platform):
from Prefab.tests.reparent_prefab import ReparentPrefab_UnderAnotherPrefab as test_module
self._run_prefab_test(request, workspace, editor, test_module, autotest_mode=False)
def test_PrefabBasicWorkflow_CreateReparentAndDetachPrefab(self, request, workspace, editor, launcher_platform):
from .tests import PrefabBasicWorkflow_CreateReparentAndDetachPrefab as test_module
def test_DetachPrefab_UnderAnotherPrefab(self, request, workspace, editor, launcher_platform):
from Prefab.tests.detach_prefab import DetachPrefab_UnderAnotherPrefab as test_module
self._run_prefab_test(request, workspace, editor, test_module, autotest_mode=False)
def test_PrefabBasicWorkflow_CreateAndDuplicatePrefab(self, request, workspace, editor, launcher_platform):
from .tests import PrefabBasicWorkflow_CreateAndDuplicatePrefab as test_module
def test_DuplicatePrefab_ContainingASingleEntity(self, request, workspace, editor, launcher_platform):
from Prefab.tests.duplicate_prefab import DuplicatePrefab_ContainingASingleEntity as test_module
self._run_prefab_test(request, workspace, editor, test_module)
def test_PrefabComplexWorflow_CreatePrefabOfChildEntity(self, request, workspace, editor, launcher_platform):
from .tests import PrefabComplexWorflow_CreatePrefabOfChildEntity as test_module
def test_CreatePrefab_UnderAnEntity(self, request, workspace, editor, launcher_platform):
from Prefab.tests.create_prefab import CreatePrefab_UnderAnEntity as test_module
self._run_prefab_test(request, workspace, editor, test_module, autotest_mode=False)
def test_PrefabComplexWorflow_CreatePrefabInsidePrefab(self, request, workspace, editor, launcher_platform):
from .tests import PrefabComplexWorflow_CreatePrefabInsidePrefab as test_module
def test_CreatePrefab_UnderAnotherPrefab(self, request, workspace, editor, launcher_platform):
from Prefab.tests.create_prefab import CreatePrefab_UnderAnotherPrefab as test_module
self._run_prefab_test(request, workspace, editor, test_module, autotest_mode=False)
@@ -5,7 +5,7 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
def PrefabComplexWorflow_CreatePrefabOfChildEntity():
def CreatePrefab_UnderAnEntity():
"""
Test description:
- Creates two entities, parent and child. Child entity has Parent entity as its parent.
@@ -18,7 +18,7 @@ def PrefabComplexWorflow_CreatePrefabOfChildEntity():
from editor_python_test_tools.editor_entity_utils import EditorEntity
from editor_python_test_tools.prefab_utils import Prefab
import PrefabTestUtils as prefab_test_utils
import Prefab.tests.PrefabTestUtils as prefab_test_utils
prefab_test_utils.open_base_tests_level()
@@ -49,4 +49,4 @@ def PrefabComplexWorflow_CreatePrefabOfChildEntity():
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(PrefabComplexWorflow_CreatePrefabOfChildEntity)
Report.start_test(CreatePrefab_UnderAnEntity)
@@ -5,7 +5,7 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
def PrefabComplexWorflow_CreatePrefabInsidePrefab():
def CreatePrefab_UnderAnotherPrefab():
"""
Test description:
- Creates an entity with a physx collider
@@ -17,7 +17,7 @@ def PrefabComplexWorflow_CreatePrefabInsidePrefab():
from editor_python_test_tools.editor_entity_utils import EditorEntity
from editor_python_test_tools.prefab_utils import Prefab
import PrefabTestUtils as prefab_test_utils
import Prefab.tests.PrefabTestUtils as prefab_test_utils
prefab_test_utils.open_base_tests_level()
@@ -54,4 +54,4 @@ def PrefabComplexWorflow_CreatePrefabInsidePrefab():
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(PrefabComplexWorflow_CreatePrefabInsidePrefab)
Report.start_test(CreatePrefab_UnderAnotherPrefab)
@@ -5,7 +5,7 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
def PrefabBasicWorkflow_CreatePrefab():
def CreatePrefab_WithSingleEntity():
CAR_PREFAB_FILE_NAME = 'car_prefab'
@@ -13,7 +13,7 @@ def PrefabBasicWorkflow_CreatePrefab():
from editor_python_test_tools.utils import Report
from editor_python_test_tools.prefab_utils import Prefab
import PrefabTestUtils as prefab_test_utils
import Prefab.tests.PrefabTestUtils as prefab_test_utils
prefab_test_utils.open_base_tests_level()
@@ -26,4 +26,4 @@ def PrefabBasicWorkflow_CreatePrefab():
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(PrefabBasicWorkflow_CreatePrefab)
Report.start_test(CreatePrefab_WithSingleEntity)
@@ -5,14 +5,14 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
def PrefabBasicWorkflow_CreateAndDeletePrefab():
def DeletePrefab_ContainingASingleEntity():
CAR_PREFAB_FILE_NAME = 'car_prefab'
from editor_python_test_tools.editor_entity_utils import EditorEntity
from editor_python_test_tools.prefab_utils import Prefab
import PrefabTestUtils as prefab_test_utils
import Prefab.tests.PrefabTestUtils as prefab_test_utils
prefab_test_utils.open_base_tests_level()
@@ -29,4 +29,4 @@ def PrefabBasicWorkflow_CreateAndDeletePrefab():
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(PrefabBasicWorkflow_CreateAndDeletePrefab)
Report.start_test(DeletePrefab_ContainingASingleEntity)
@@ -5,7 +5,7 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
def PrefabBasicWorkflow_CreateReparentAndDetachPrefab():
def DetachPrefab_UnderAnotherPrefab():
CAR_PREFAB_FILE_NAME = 'car_prefab'
WHEEL_PREFAB_FILE_NAME = 'wheel_prefab'
@@ -18,7 +18,7 @@ def PrefabBasicWorkflow_CreateReparentAndDetachPrefab():
from editor_python_test_tools.editor_entity_utils import EditorEntity
from editor_python_test_tools.prefab_utils import Prefab
import PrefabTestUtils as prefab_test_utils
import Prefab.tests.PrefabTestUtils as prefab_test_utils
prefab_test_utils.open_base_tests_level()
@@ -48,4 +48,4 @@ def PrefabBasicWorkflow_CreateReparentAndDetachPrefab():
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(PrefabBasicWorkflow_CreateReparentAndDetachPrefab)
Report.start_test(DetachPrefab_UnderAnotherPrefab)
@@ -5,14 +5,14 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
def PrefabBasicWorkflow_CreateAndDuplicatePrefab():
def DuplicatePrefab_ContainingASingleEntity():
CAR_PREFAB_FILE_NAME = 'car_prefab'
from editor_python_test_tools.editor_entity_utils import EditorEntity
from editor_python_test_tools.prefab_utils import Prefab
import PrefabTestUtils as prefab_test_utils
import Prefab.tests.PrefabTestUtils as prefab_test_utils
prefab_test_utils.open_base_tests_level()
@@ -29,4 +29,4 @@ def PrefabBasicWorkflow_CreateAndDuplicatePrefab():
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(PrefabBasicWorkflow_CreateAndDuplicatePrefab)
Report.start_test(DuplicatePrefab_ContainingASingleEntity)
@@ -5,7 +5,7 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
def PrefabBasicWorkflow_InstantiatePrefab():
def InstantiatePrefab_ContainingASingleEntity():
from azlmbr.math import Vector3
@@ -15,7 +15,7 @@ def PrefabBasicWorkflow_InstantiatePrefab():
from editor_python_test_tools.prefab_utils import Prefab
import PrefabTestUtils as prefab_test_utils
import Prefab.tests.PrefabTestUtils as prefab_test_utils
prefab_test_utils.open_base_tests_level()
@@ -30,4 +30,4 @@ def PrefabBasicWorkflow_InstantiatePrefab():
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(PrefabBasicWorkflow_InstantiatePrefab)
Report.start_test(InstantiatePrefab_ContainingASingleEntity)
@@ -14,7 +14,7 @@ class Tests():
# fmt:on
def PrefabLevel_OpensLevelWithEntities():
def OpenLevel_ContainingTwoEntities():
"""
Opens the level that contains 2 entities, "EmptyEntity" and "EntityWithPxCollider".
This test makes sure that both entities exist after opening the level and that:
@@ -70,4 +70,4 @@ def PrefabLevel_OpensLevelWithEntities():
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(PrefabLevel_OpensLevelWithEntities)
Report.start_test(OpenLevel_ContainingTwoEntities)
@@ -5,7 +5,7 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
def PrefabBasicWorkflow_CreateAndReparentPrefab():
def ReparentPrefab_UnderAnotherPrefab():
CAR_PREFAB_FILE_NAME = 'car_prefab'
WHEEL_PREFAB_FILE_NAME = 'wheel_prefab'
@@ -18,7 +18,7 @@ def PrefabBasicWorkflow_CreateAndReparentPrefab():
from editor_python_test_tools.editor_entity_utils import EditorEntity
from editor_python_test_tools.prefab_utils import Prefab
import PrefabTestUtils as prefab_test_utils
import Prefab.tests.PrefabTestUtils as prefab_test_utils
prefab_test_utils.open_base_tests_level()
@@ -45,4 +45,4 @@ def PrefabBasicWorkflow_CreateAndReparentPrefab():
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(PrefabBasicWorkflow_CreateAndReparentPrefab)
Report.start_test(ReparentPrefab_UnderAnotherPrefab)
@@ -8,42 +8,54 @@ import azlmbr.bus
import azlmbr.asset
import azlmbr.editor
import azlmbr.math
import azlmbr.legacy.general
def raise_and_stop(msg):
print (msg)
print('Starting mock asset tests')
handler = azlmbr.editor.EditorEventBusHandler()
def on_notify_editor_initialized(args):
# These tests are meant to check that the test_asset.mock source asset turned into
# a test_asset.mock_asset product asset via the Python asset builder system
mockAssetType = azlmbr.math.Uuid_CreateString('{9274AD17-3212-4651-9F3B-7DCCB080E467}', 0)
mockAssetPath = 'gem/pythontests/pythonassetbuilder/test_asset.mock_asset'
assetId = azlmbr.asset.AssetCatalogRequestBus(azlmbr.bus.Broadcast, 'GetAssetIdByPath', mockAssetPath, mockAssetType, False)
if (assetId.is_valid() is False):
print(f'Mock AssetId is not valid! Got {assetId.to_string()} instead')
else:
print(f'Mock AssetId is valid!')
assetIdString = assetId.to_string()
if (assetIdString.endswith(':528cca58') is False):
print(f'Mock AssetId {assetIdString} has unexpected sub-id for {mockAssetPath}!')
else:
print(f'Mock AssetId has expected sub-id for {mockAssetPath}!')
print ('Mock asset exists')
# These tests detect if the geom_group.fbx file turns into a number of azmodel product assets
def test_azmodel_product(generatedModelAssetPath):
azModelAssetType = azlmbr.math.Uuid_CreateString('{2C7477B6-69C5-45BE-8163-BCD6A275B6D8}', 0)
assetId = azlmbr.asset.AssetCatalogRequestBus(azlmbr.bus.Broadcast, 'GetAssetIdByPath', generatedModelAssetPath, azModelAssetType, False)
assetIdString = assetId.to_string()
if (assetId.is_valid()):
print(f'AssetId found for asset ({generatedModelAssetPath}) found')
else:
print(f'Asset at path {generatedModelAssetPath} has unexpected asset ID ({assetIdString})!')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_positive_1.azmodel')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_negative_1.azmodel')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_positive_1.azmodel')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_negative_1.azmodel')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_positive_1.azmodel')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_negative_1.azmodel')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center_1.azmodel')
# clear up notification handler
global handler
handler.disconnect()
handler = None
print('Finished mock asset tests')
azlmbr.editor.EditorToolsApplicationRequestBus(azlmbr.bus.Broadcast, 'ExitNoPrompt')
# These tests are meant to check that the test_asset.mock source asset turned into
# a test_asset.mock_asset product asset via the Python asset builder system
mockAssetType = azlmbr.math.Uuid_CreateString('{9274AD17-3212-4651-9F3B-7DCCB080E467}', 0)
mockAssetPath = 'gem/pythontests/pythonassetbuilder/test_asset.mock_asset'
assetId = azlmbr.asset.AssetCatalogRequestBus(azlmbr.bus.Broadcast, 'GetAssetIdByPath', mockAssetPath, mockAssetType, False)
if (assetId.is_valid() is False):
raise_and_stop(f'Mock AssetId is not valid! Got {assetId.to_string()} instead')
assetIdString = assetId.to_string()
if (assetIdString.endswith(':528cca58') is False):
raise_and_stop(f'Mock AssetId {assetIdString} has unexpected sub-id for {mockAssetPath}!')
print ('Mock asset exists')
# These tests detect if the geom_group.fbx file turns into a number of azmodel product assets
def test_azmodel_product(generatedModelAssetPath):
azModelAssetType = azlmbr.math.Uuid_CreateString('{2C7477B6-69C5-45BE-8163-BCD6A275B6D8}', 0)
assetId = azlmbr.asset.AssetCatalogRequestBus(azlmbr.bus.Broadcast, 'GetAssetIdByPath', generatedModelAssetPath, azModelAssetType, False)
assetIdString = assetId.to_string()
if (assetId.is_valid()):
print(f'AssetId found for asset ({generatedModelAssetPath}) found')
else:
raise_and_stop(f'Asset at path {generatedModelAssetPath} has unexpected asset ID ({assetIdString})!')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_positive_1.azmodel')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_negative_1.azmodel')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_positive_1.azmodel')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_negative_1.azmodel')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_positive_1.azmodel')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_negative_1.azmodel')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center_1.azmodel')
azlmbr.editor.EditorToolsApplicationRequestBus(azlmbr.bus.Broadcast, 'ExitNoPrompt')
handler.connect()
handler.add_callback('NotifyEditorInitialized', on_notify_editor_initialized)
@@ -0,0 +1,24 @@
#
# 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
#
#
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
ly_add_pytest(
NAME AutomatedTesting::TerrainTests_Main
TEST_SUITE main
TEST_SERIAL
PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main.py
RUNTIME_DEPENDENCIES
Legacy::Editor
AZ::AssetProcessor
AutomatedTesting.Assets
COMPONENT
Terrain
)
endif()
@@ -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
"""
#fmt: off
class Tests():
create_test_entity = ("Entity created successfully", "Failed to create Entity")
add_axis_aligned_box_shape = ("Axis Aligned Box Shape component added", "Failed to add Axis Aligned Box Shape component")
add_terrain_collider = ("Terrain Physics Heightfield Collider component added", "Failed to add a Terrain Physics Heightfield Collider component")
box_dimensions_changed = ("Aabb dimensions changed successfully", "Failed change Aabb dimensions")
configuration_changed = ("Terrain size changed successfully", "Failed terrain size change")
#fmt: on
def TerrainPhysicsCollider_ChangesSizeWithAxisAlignedBoxShapeChanges():
"""
Summary:
Test aspects of the Terrain Physics Heightfield Collider through the BehaviorContext and the Property Tree.
Test Steps:
Expected Behavior:
The Editor is stable there are no warnings or errors.
Test Steps:
1) Load the base level
2) Create test entity
3) Start the Tracer to catch any errors and warnings
4) Add the Axis Aligned Box Shape and Terrain Physics Heightfield Collider components
5) Change the Axis Aligned Box Shape dimensions
6) Check the Heightfield provider is returning the correct size
7) Verify there are no errors and warnings in the logs
:return: None
"""
from editor_python_test_tools.editor_entity_utils import EditorEntity
from editor_python_test_tools.utils import TestHelper as helper
from editor_python_test_tools.utils import Report, Tracer
import azlmbr.legacy.general as general
import azlmbr.physics as physics
import azlmbr.math as azmath
import azlmbr.bus as bus
import sys
import math
SET_BOX_X_SIZE = 5.0
SET_BOX_Y_SIZE = 6.0
EXPECTED_COLUMN_SIZE = SET_BOX_X_SIZE + 1
EXPECTED_ROW_SIZE = SET_BOX_Y_SIZE + 1
helper.init_idle()
# 1) Load the level
helper.open_level("", "Base")
# 2) Create test entity
test_entity = EditorEntity.create_editor_entity("TestEntity")
Report.result(Tests.create_test_entity, test_entity.id.IsValid())
# 3) Start the Tracer to catch any errors and warnings
with Tracer() as section_tracer:
# 4) Add the Axis Aligned Box Shape and Terrain Physics Heightfield Collider components
aaBoxShape_component = test_entity.add_component("Axis Aligned Box Shape")
Report.result(Tests.add_axis_aligned_box_shape, test_entity.has_component("Axis Aligned Box Shape"))
terrainPhysics_component = test_entity.add_component("Terrain Physics Heightfield Collider")
Report.result(Tests.add_terrain_collider, test_entity.has_component("Terrain Physics Heightfield Collider"))
# 5) Change the Axis Aligned Box Shape dimensions
aaBoxShape_component.set_component_property_value("Axis Aligned Box Shape|Box Configuration|Dimensions", azmath.Vector3(SET_BOX_X_SIZE, SET_BOX_Y_SIZE, 1.0))
add_check = aaBoxShape_component.get_component_property_value("Axis Aligned Box Shape|Box Configuration|Dimensions") == azmath.Vector3(SET_BOX_X_SIZE, SET_BOX_Y_SIZE, 1.0)
Report.result(Tests.box_dimensions_changed, add_check)
# 6) Check the Heightfield provider is returning the correct size
columns = physics.HeightfieldProviderRequestsBus(bus.Broadcast, "GetHeightfieldGridColumns")
rows = physics.HeightfieldProviderRequestsBus(bus.Broadcast, "GetHeightfieldGridRows")
Report.result(Tests.configuration_changed, math.isclose(columns, EXPECTED_COLUMN_SIZE) and math.isclose(rows, EXPECTED_ROW_SIZE))
helper.wait_for_condition(lambda: section_tracer.has_errors or section_tracer.has_asserts, 1.0)
for error_info in section_tracer.errors:
Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
for assert_info in section_tracer.asserts:
Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}")
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(TerrainPhysicsCollider_ChangesSizeWithAxisAlignedBoxShapeChanges)
@@ -0,0 +1,164 @@
"""
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
"""
#fmt: off
class Tests():
create_terrain_spawner_entity = ("Terrain_spawner_entity created successfully", "Failed to create terrain_spawner_entity")
create_height_provider_entity = ("Height_provider_entity created successfully", "Failed to create height_provider_entity")
create_test_ball = ("Ball created successfully", "Failed to create Ball")
box_dimensions_changed = ("Aabb dimensions changed successfully", "Failed change Aabb dimensions")
shape_changed = ("Shape changed successfully", "Failed Shape change")
entity_added = ("Entity added successfully", "Failed Entity add")
frequency_changed = ("Frequency changed successfully", "Failed Frequency change")
shape_set = ("Shape set to Sphere successfully", "Failed to set Sphere shape")
test_collision = ("Ball collided with terrain", "Ball failed to collide with terrain")
no_errors_and_warnings_found = ("No errors and warnings found", "Found errors and warnings")
#fmt: on
def Terrain_SupportsPhysics():
"""
Summary:
Test aspects of the TerrainHeightGradientList through the BehaviorContext and the Property Tree.
Test Steps:
Expected Behavior:
The Editor is stable there are no warnings or errors.
Test Steps:
1) Load the base level
2) Create 2 test entities, one parent at 512.0, 512.0, 50.0 and one child at the default position and add the required components
2a) Create a ball at 600.0, 600.0, 46.0 - This position is not too high over the heightfield so will collide in a reasonable time
3) Start the Tracer to catch any errors and warnings
4) Change the Axis Aligned Box Shape dimensions
5) Set the Vegetation Shape reference to TestEntity1
6) Set the FastNoise gradient frequency to 0.01
7) Set the Gradient List to TestEntity2
8) Set the PhysX Collider to Sphere mode
9) Disable and Enable the Terrain Gradient List so that it is recognised
10) Enter game mode and test if the ball hits the heightfield within 3 seconds
11) Verify there are no errors and warnings in the logs
:return: None
"""
from editor_python_test_tools.editor_entity_utils import EditorEntity
from editor_python_test_tools.utils import TestHelper as helper, Report
from editor_python_test_tools.utils import Report, Tracer
import editor_python_test_tools.hydra_editor_utils as hydra
import azlmbr.math as azmath
import azlmbr.legacy.general as general
import azlmbr.bus as bus
import azlmbr.editor as editor
import math
SET_BOX_X_SIZE = 1024.0
SET_BOX_Y_SIZE = 1024.0
SET_BOX_Z_SIZE = 100.0
helper.init_idle()
# 1) Load the level
helper.open_level("", "Base")
helper.wait_for_condition(lambda: general.get_current_level_name() == "Base", 2.0)
#1a) Load the level components
hydra.add_level_component("Terrain World")
hydra.add_level_component("Terrain World Renderer")
# 2) Create 2 test entities, one parent at 512.0, 512.0, 50.0 and one child at the default position and add the required components
entity1_components_to_add = ["Axis Aligned Box Shape", "Terrain Layer Spawner", "Terrain Height Gradient List", "Terrain Physics Heightfield Collider", "PhysX Heightfield Collider"]
entity2_components_to_add = ["Vegetation Reference Shape", "Gradient Transform Modifier", "FastNoise Gradient"]
ball_components_to_add = ["Sphere Shape", "PhysX Collider", "PhysX Rigid Body"]
terrain_spawner_entity = hydra.Entity("TestEntity1")
terrain_spawner_entity.create_entity(azmath.Vector3(512.0, 512.0, 50.0), entity1_components_to_add)
Report.result(Tests.create_terrain_spawner_entity, terrain_spawner_entity.id.IsValid())
height_provider_entity = hydra.Entity("TestEntity2")
height_provider_entity.create_entity(azmath.Vector3(0.0, 0.0, 0.0), entity2_components_to_add,terrain_spawner_entity.id)
Report.result(Tests.create_height_provider_entity, height_provider_entity.id.IsValid())
# 2a) Create a ball at 600.0, 600.0, 46.0 - This position is not too high over the heightfield so will collide in a reasonable time
ball = hydra.Entity("Ball")
ball.create_entity(azmath.Vector3(600.0, 600.0, 46.0), ball_components_to_add)
Report.result(Tests.create_test_ball, ball.id.IsValid())
# Give everything a chance to finish initializing.
general.idle_wait_frames(1)
# 3) Start the Tracer to catch any errors and warnings
with Tracer() as section_tracer:
# 4) Change the Axis Aligned Box Shape dimensions
box_dimensions = azmath.Vector3(SET_BOX_X_SIZE, SET_BOX_Y_SIZE, SET_BOX_Z_SIZE)
terrain_spawner_entity.get_set_test(0, "Axis Aligned Box Shape|Box Configuration|Dimensions", box_dimensions)
box_shape_dimensions = hydra.get_component_property_value(terrain_spawner_entity.components[0], "Axis Aligned Box Shape|Box Configuration|Dimensions")
Report.result(Tests.box_dimensions_changed, box_dimensions == box_shape_dimensions)
# 5) Set the Vegetaion Shape reference to TestEntity1
height_provider_entity.get_set_test(0, "Configuration|Shape Entity Id", terrain_spawner_entity.id)
entityId = hydra.get_component_property_value(height_provider_entity.components[0], "Configuration|Shape Entity Id")
Report.result(Tests.shape_changed, entityId == terrain_spawner_entity.id)
# 6) Set the FastNoise Gradient frequency to 0.01
Frequency = 0.01
height_provider_entity.get_set_test(2, "Configuration|Frequency", Frequency)
FrequencyVal = hydra.get_component_property_value(height_provider_entity.components[2], "Configuration|Frequency")
Report.result(Tests.frequency_changed, math.isclose(Frequency, FrequencyVal, abs_tol = 0.00001))
# 7) Set the Gradient List to TestEntity2
propertyTree = hydra.get_property_tree(terrain_spawner_entity.components[2])
propertyTree.add_container_item("Configuration|Gradient Entities", 0, height_provider_entity.id)
checkID = propertyTree.get_container_item("Configuration|Gradient Entities", 0)
Report.result(Tests.entity_added, checkID.GetValue() == height_provider_entity.id)
# 8) Set the PhysX Collider to Sphere mode
shape = 0
hydra.get_set_test(ball, 1, "Shape Configuration|Shape", shape)
setShape = hydra.get_component_property_value(ball.components[1], "Shape Configuration|Shape")
Report.result(Tests.shape_set, shape == setShape)
# 9) Disable and Enable the Terrain Gradient List so that it is recognised
editor.EditorComponentAPIBus(bus.Broadcast, 'EnableComponents', [terrain_spawner_entity.components[2]])
general.enter_game_mode()
general.idle_wait_frames(1)
# 10) Enter game mode and test if the ball hits the heightfield within 3 seconds
TIMEOUT = 3.0
class Collider:
id = general.find_game_entity("Ball")
touched_ground = False
terrain_id = general.find_game_entity("TestEntity1")
def on_collision_begin(args):
other_id = args[0]
if other_id.Equal(terrain_id):
Report.info("Touched ground")
Collider.touched_ground = True
handler = azlmbr.physics.CollisionNotificationBusHandler()
handler.connect(Collider.id)
handler.add_callback("OnCollisionBegin", on_collision_begin)
helper.wait_for_condition(lambda: Collider.touched_ground, TIMEOUT)
Report.result(Tests.test_collision, Collider.touched_ground)
general.exit_game_mode()
# 11) Verify there are no errors and warnings in the logs
helper.wait_for_condition(lambda: section_tracer.has_errors or section_tracer.has_asserts, 1.0)
for error_info in section_tracer.errors:
Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
for assert_info in section_tracer.asserts:
Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}")
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(Terrain_SupportsPhysics)
@@ -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
"""
# This suite consists of all test cases that are passing and have been verified.
import pytest
import os
import sys
from ly_test_tools import LAUNCHERS
from ly_test_tools.o3de.editor_test import EditorTestSuite, EditorSharedTest
@pytest.mark.SUITE_main
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
@pytest.mark.parametrize("project", ["AutomatedTesting"])
class TestAutomation(EditorTestSuite):
enable_prefab_system = False
class test_AxisAlignedBoxShape_ConfigurationWorks(EditorSharedTest):
from .EditorScripts import TerrainPhysicsCollider_ChangesSizeWithAxisAlignedBoxShapeChanges as test_module
class test_Terrain_SupportsPhysics(EditorSharedTest):
from .EditorScripts import Terrain_SupportsPhysics as test_module
@@ -0,0 +1,6 @@
"""
Copyright (c) Contributors to the Open 3D Engine Project.
For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
@@ -24,12 +24,12 @@ from base import TestAutomationBase
class TestAutomation(TestAutomationBase):
def test_WhiteBox_AddComponentToEntity(self, request, workspace, editor, launcher_platform):
from .tests import WhiteBox_AddComponentToEntity as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_WhiteBox_SetDefaultShape(self, request, workspace, editor, launcher_platform):
from .tests import WhiteBox_SetDefaultShape as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_WhiteBox_SetInvisible(self, request, workspace, editor, launcher_platform):
from .tests import WhiteBox_SetInvisible as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@@ -158,7 +158,7 @@ def bundler_batch_setup_fixture(request, workspace, asset_processor, timeout) ->
else:
cmd.append(f"--{key}")
if append_defaults:
cmd.append(f"--project-path={workspace.project}")
cmd.append(f"--project-path={workspace.paths.project()}")
return cmd
# ******
@@ -88,214 +88,6 @@ class TestsAssetBundlerBatch_WindowsAndMac(object):
bundler_batch_helper.call_bundles(help="")
bundler_batch_helper.call_bundleSeed(help="")
@pytest.mark.BAT
@pytest.mark.assetpipeline
@pytest.mark.test_case_id("C16877175")
@pytest.mark.skip("'animations/animationeditorfiles/sample1.animgraph' missing, needs investigation")
def test_WindowsAndMac_CreateAssetList_DependenciesCorrect(self, workspace, bundler_batch_helper):
r"""
Tests that an asset list created maps dependencies correctly.
testdependencieslevel\level.pak and lists of known dependencies are used for validation
Test Steps:
1. Create an asset list from the level.pak
2. Create Lists of expected assets in the level.pak
3. Add lists of expected assets to a single list
4. Compare list of expected assets to actual assets
"""
helper = bundler_batch_helper
# Create the asset list file
helper.call_assetLists(
addSeed=r"levels\testdependencieslevel\level.pak",
assetListFile=helper['asset_info_file_request']
)
assert os.path.isfile(helper["asset_info_file_result"])
# Lists of known relative locations of assets
default_level_assets = [
"engineassets/texturemsg/defaultnouvs.dds",
"engineassets/texturemsg/defaultnouvs.dds.1",
"engineassets/texturemsg/defaultnouvs.dds.2",
"engineassets/texturemsg/defaultnouvs.dds.3",
"engineassets/texturemsg/defaultnouvs.dds.4",
"engineassets/texturemsg/defaultnouvs.dds.5",
"engineassets/texturemsg/defaultnouvs.dds.6",
"engineassets/texturemsg/defaultnouvs.dds.7",
"engineassets/texturemsg/defaultnouvs_ddn.dds",
"engineassets/texturemsg/defaultnouvs_ddn.dds.1",
"engineassets/texturemsg/defaultnouvs_ddn.dds.2",
"engineassets/texturemsg/defaultnouvs_ddn.dds.3",
"engineassets/texturemsg/defaultnouvs_ddn.dds.4",
"engineassets/texturemsg/defaultnouvs_ddn.dds.5",
"engineassets/texturemsg/defaultnouvs_spec.dds",
"engineassets/texturemsg/defaultnouvs_spec.dds.1",
"engineassets/texturemsg/defaultnouvs_spec.dds.2",
"engineassets/texturemsg/defaultnouvs_spec.dds.3",
"engineassets/texturemsg/defaultnouvs_spec.dds.4",
"engineassets/texturemsg/defaultnouvs_spec.dds.5",
"engineassets/textures/defaults/16_grey.dds",
"engineassets/textures/cubemap/default_level_cubemap.dds",
"engineassets/textures/cubemap/default_level_cubemap.dds.1",
"engineassets/textures/cubemap/default_level_cubemap.dds.2",
"engineassets/textures/cubemap/default_level_cubemap.dds.3",
"engineassets/textures/cubemap/default_level_cubemap.dds.4",
"engineassets/textures/cubemap/default_level_cubemap_diff.dds",
"engineassets/materials/water/ocean_default.mtl",
"engineassets/textures/defaults/spot_default.dds",
"engineassets/textures/defaults/spot_default.dds.1",
"engineassets/textures/defaults/spot_default.dds.2",
"engineassets/textures/defaults/spot_default.dds.3",
"engineassets/textures/defaults/spot_default.dds.4",
"engineassets/textures/defaults/spot_default.dds.5",
"materials/material_terrain_default.mtl",
"textures/skys/night/half_moon.dds",
"textures/skys/night/half_moon.dds.1",
"textures/skys/night/half_moon.dds.2",
"textures/skys/night/half_moon.dds.3",
"textures/skys/night/half_moon.dds.4",
"textures/skys/night/half_moon.dds.5",
"textures/skys/night/half_moon.dds.6",
"engineassets/materials/sky/sky.mtl",
"levels/testdependencieslevel/level.pak",
"levels/testdependencieslevel/terrain/cover.ctc",
"levels/testdependencieslevel/terraintexture.pak",
]
sequence_material_cube_assets = [
"textures/test_texture_sequence/test_texture_sequence000.dds",
"textures/test_texture_sequence/test_texture_sequence001.dds",
"textures/test_texture_sequence/test_texture_sequence002.dds",
"textures/test_texture_sequence/test_texture_sequence003.dds",
"textures/test_texture_sequence/test_texture_sequence004.dds",
"textures/test_texture_sequence/test_texture_sequence005.dds",
"objects/_primitives/_box_1x1.cgf",
"materials/test_texture_sequence.mtl",
"objects/_primitives/_box_1x1.mtl",
"textures/_primitives/middle_gray_checker.dds",
"textures/_primitives/middle_gray_checker.dds.1",
"textures/_primitives/middle_gray_checker.dds.2",
"textures/_primitives/middle_gray_checker.dds.3",
"textures/_primitives/middle_gray_checker.dds.4",
"textures/_primitives/middle_gray_checker.dds.5",
"textures/_primitives/middle_gray_checker_ddn.dds",
"textures/_primitives/middle_gray_checker_ddn.dds.1",
"textures/_primitives/middle_gray_checker_ddn.dds.2",
"textures/_primitives/middle_gray_checker_ddn.dds.3",
"textures/_primitives/middle_gray_checker_ddn.dds.4",
"textures/_primitives/middle_gray_checker_ddn.dds.5",
"textures/_primitives/middle_gray_checker_spec.dds",
"textures/_primitives/middle_gray_checker_spec.dds.1",
"textures/_primitives/middle_gray_checker_spec.dds.2",
"textures/_primitives/middle_gray_checker_spec.dds.3",
"textures/_primitives/middle_gray_checker_spec.dds.4",
"textures/_primitives/middle_gray_checker_spec.dds.5",
]
character_with_simplified_material_assets = [
"objects/characters/jack/jack.actor",
"objects/characters/jack/jack.mtl",
"objects/characters/jack/textures/jack_diff.dds",
"objects/characters/jack/textures/jack_diff.dds.1",
"objects/characters/jack/textures/jack_diff.dds.2",
"objects/characters/jack/textures/jack_diff.dds.3",
"objects/characters/jack/textures/jack_diff.dds.4",
"objects/characters/jack/textures/jack_diff.dds.5",
"objects/characters/jack/textures/jack_diff.dds.6",
"objects/characters/jack/textures/jack_diff.dds.7",
"objects/characters/jack/textures/jack_spec.dds",
"objects/characters/jack/textures/jack_spec.dds.1",
"objects/characters/jack/textures/jack_spec.dds.2",
"objects/characters/jack/textures/jack_spec.dds.3",
"objects/characters/jack/textures/jack_spec.dds.4",
"objects/characters/jack/textures/jack_spec.dds.5",
"objects/characters/jack/textures/jack_spec.dds.6",
"objects/characters/jack/textures/jack_spec.dds.7",
"objects/default/editorprimitive.mtl",
"engineassets/textures/grey.dds",
"animations/animationeditorfiles/sample0.animgraph",
"animations/motions/jack_death_fall_back_zup.motion",
"animations/animationeditorfiles/sample1.animgraph",
"animations/animationeditorfiles/sample0.motionset",
"animations/motions/rin_jump.motion",
"animations/animationeditorfiles/sample1.motionset",
"animations/motions/rin_idle.motion",
"animations/motions/jack_idle_aim_zup.motion",
]
spawner_assets = [
"slices/sphere.dynamicslice",
"objects/default/primitive_sphere.cgf",
"test1.luac",
"test2.luac",
]
ui_canvas_assets = [
"fonts/vera.ttf",
"fonts/vera.font",
"scriptcanvas/mainmenu.scriptcanvas_compiled",
"fonts/vera.fontfamily",
"ui/canvas/start.uicanvas",
"fonts/vera-italic.font",
"ui/textureatlas/sample.texatlasidx",
"fonts/vera-bold-italic.ttf",
"fonts/vera-bold.font",
"ui/textures/prefab/button_normal.dds",
"ui/textures/prefab/button_normal.sprite",
"fonts/vera-italic.ttf",
"ui/textureatlas/sample.dds",
"fonts/vera-bold-italic.font",
"fonts/vera-bold.ttf",
"ui/textures/prefab/button_disabled.dds",
"ui/textures/prefab/button_disabled.sprite",
]
wwise_and_atl_assets = [
"libs/gameaudio/wwise/levels/testdependencieslevel/test_dependencies_level.xml",
"sounds/wwise/test_bank3.bnk",
"sounds/wwise/test_bank4.bnk",
"sounds/wwise/test_bank5.bnk",
"sounds/wwise/test_bank1.bnk",
"sounds/wwise/init.bnk",
"sounds/wwise/499820003.wem",
"sounds/wwise/196049145.wem",
]
particle_library_assets = [
"libs/particles/milestone2particles.xml",
"textures/milestone2/particles/fx_launchermuzzlering_01.dds",
"textures/milestone2/particles/fx_launchermuzzlering_01.dds.1",
"textures/milestone2/particles/fx_launchermuzzlering_01.dds.2",
"textures/milestone2/particles/fx_launchermuzzlering_01.dds.3",
"textures/milestone2/particles/fx_launchermuzzlering_01.dds.4",
"textures/milestone2/particles/fx_launchermuzzlering_01.dds.5",
"textures/milestone2/particles/fx_sparkstreak_01.dds",
"textures/milestone2/particles/fx_launchermuzzlefront_01.dds",
"textures/milestone2/particles/fx_launchermuzzlefront_01.dds.1",
"textures/milestone2/particles/fx_launchermuzzlefront_01.dds.2",
"textures/milestone2/particles/fx_launchermuzzlefront_01.dds.3",
"textures/milestone2/particles/fx_launchermuzzlefront_01.dds.4",
"textures/milestone2/particles/fx_launchermuzzlefront_01.dds.5",
]
lens_flares_library_assets = ["libs/flares/flares.xml", "textures/lights/flare01.dds"]
expected_assets_list = default_level_assets
expected_assets_list.extend(sequence_material_cube_assets)
expected_assets_list.extend(character_with_simplified_material_assets)
expected_assets_list.extend(spawner_assets)
expected_assets_list.extend(ui_canvas_assets)
expected_assets_list.extend(wwise_and_atl_assets)
expected_assets_list.extend(particle_library_assets)
expected_assets_list.extend(lens_flares_library_assets) # All expected assets
# Get actual calculated dependencies from the asset list created
actual_assets_list = []
for rel_path in helper.get_asset_relative_paths(helper["asset_info_file_result"]):
actual_assets_list.append(rel_path)
assert sorted(actual_assets_list) == sorted(expected_assets_list)
@pytest.mark.BAT
@pytest.mark.assetpipeline
@@ -310,9 +102,9 @@ class TestsAssetBundlerBatch_WindowsAndMac(object):
3. Read and store contents of asset list into memory
4. Attempt to create a new asset list in without using --allowOverwrites
5. Verify that Asset Bundler returns false
6. Verify that file contents of the orignally created asset list did not change from what was stored in memory
6. Verify that file contents of the originally created asset list did not change from what was stored in memory
7. Attempt to create a new asset list without debug while allowing overwrites
8. Verify that file contents of the orignally created asset list changed from what was stored in memory
8. Verify that file contents of the originally created asset list changed from what was stored in memory
"""
helper = bundler_batch_helper
seed_list = os.path.join(workspace.paths.engine_root(), "Assets", "Engine", "SeedAssetList.seed") # Engine seed list
@@ -919,7 +711,7 @@ class TestsAssetBundlerBatch_WindowsAndMac(object):
# Extra arguments for pattern comparison
cmd.extend([f"--filePatternType={pattern_type}", f"--filePattern={pattern}"])
if workspace.project:
cmd.append(f'--project-path={project_name}')
cmd.append(f'--project-path={workspace.paths.project()}')
return cmd
# End generate_compare_command()
@@ -960,7 +752,7 @@ class TestsAssetBundlerBatch_WindowsAndMac(object):
output_mac_asset_list = helper.platform_file_name(last_output_arg, platform)
# Build execution command
cmd = generate_compare_command(platform_arg, workspace.project)
cmd = generate_compare_command(platform_arg, workspace.paths.project())
# Execute command
subprocess.check_call(cmd)
@@ -995,7 +787,7 @@ class TestsAssetBundlerBatch_WindowsAndMac(object):
f"--comparisonRulesFile={rule_file}",
f"--comparisonType={args[1]}",
r"--addComparison",
f"--project-path={workspace.project}",
f"--project-path={workspace.paths.project()}",
]
if args[1] == "4":
# If pattern comparison, append a few extra arguments
@@ -1117,7 +909,7 @@ class TestsAssetBundlerBatch_WindowsAndMac(object):
"--addDefaultSeedListFiles",
"--platform=pc",
"--print",
f"--project-path={workspace.project}"
f"--project-path={workspace.paths.project()}"
],
universal_newlines=True,
)
@@ -1189,7 +981,7 @@ class TestsAssetBundlerBatch_WindowsAndMac(object):
# Make sure file gets deleted on teardown
request.addfinalizer(lambda: fs.delete([bundle_result_path], True, False))
bundles_folder = os.path.join(workspace.paths.engine_root(), workspace.project, "Bundles")
bundles_folder = os.path.join(workspace.paths.project(), "Bundles")
level_pak = r"levels\testdependencieslevel\level.pak"
bundle_request_path = os.path.join(bundles_folder, "bundle.pak")
bundle_result_path = os.path.join(bundles_folder,
@@ -1243,23 +1035,64 @@ class TestsAssetBundlerBatch_WindowsAndMac(object):
2. Verify file was created
3. Verify that only the expected assets are present in the created asset list
"""
expected_assets = [
expected_assets = sorted([
"ui/canvases/lyshineexamples/animation/multiplesequences.uicanvas",
"ui/textures/prefab/button_normal.sprite"
]
"ui/textures/prefab/button_disabled.tif.streamingimage",
"ui/textures/prefab/tooltip_sliced.tif.streamingimage",
"ui/textures/prefab/button_normal.tif.streamingimage"
])
# Printing these lists out can save a step in debugging if this test fails on Jenkins.
logger.info(f"expected_assets: {expected_assets}")
skip_assets = sorted([
"ui/scripts/lyshineexamples/animation/multiplesequences.luac",
"ui/scripts/lyshineexamples/unloadthiscanvasbutton.luac",
"fonts/vera.fontfamily",
"fonts/vera-italic.font",
"fonts/vera.font",
"fonts/vera-bold.font",
"fonts/vera-bold-italic.font",
"fonts/vera-italic.ttf",
"fonts/vera.ttf",
"fonts/vera-bold.ttf",
"fonts/vera-bold-italic.ttf"
])
logger.info(f"skip_assets: {skip_assets}")
expected_and_skip_assets = sorted(expected_assets + skip_assets)
# Printing both together to make it quick to compare the results in the logs for a test failure on Jenkins
logger.info(f"expected_and_skip_assets: {expected_and_skip_assets}")
# First, generate an asset info file without skipping, to get a list that can be used as a baseline to verify
# the files were actually skipped, and not just missing.
bundler_batch_helper.call_assetLists(
assetListFile=bundler_batch_helper['asset_info_file_request'],
addSeed="ui/canvases/lyshineexamples/animation/multiplesequences.uicanvas"
)
assert os.path.isfile(bundler_batch_helper["asset_info_file_result"])
assets_in_no_skip_list = []
for rel_path in bundler_batch_helper.get_asset_relative_paths(bundler_batch_helper["asset_info_file_result"]):
assets_in_no_skip_list.append(rel_path)
assets_in_no_skip_list = sorted(assets_in_no_skip_list)
logger.info(f"assets_in_no_skip_list: {assets_in_no_skip_list}")
assert assets_in_no_skip_list == expected_and_skip_assets
# Now generate an asset info file using the skip command, and verify the skip files are not in the list.
bundler_batch_helper.call_assetLists(
assetListFile=bundler_batch_helper['asset_info_file_request'],
addSeed="ui/canvases/lyshineexamples/animation/multiplesequences.uicanvas",
skip="ui/textures/prefab/button_disabled.sprite,ui/scripts/lyshineexamples/animation/multiplesequences.luac,"
"ui/textures/prefab/tooltip_sliced.sprite,ui/scripts/lyshineexamples/unloadthiscanvasbutton.luac,fonts/vera.fontfamily,fonts/vera-italic.font,"
"fonts/vera.font,fonts/vera-bold.font,fonts/vera-bold-italic.font,fonts/vera-italic.ttf,fonts/vera.ttf,fonts/vera-bold.ttf,fonts/vera-bold-italic.ttf"
allowOverwrites="",
skip=','.join(skip_assets)
)
assert os.path.isfile(bundler_batch_helper["asset_info_file_result"])
assets_in_list = []
for rel_path in bundler_batch_helper.get_asset_relative_paths(bundler_batch_helper["asset_info_file_result"]):
assets_in_list.append(rel_path)
assets_in_list = sorted(assets_in_list)
logger.info(f"assets_in_list: {assets_in_list}")
assert assets_in_list == expected_assets
assert sorted(assets_in_list) == sorted(expected_assets)
@pytest.mark.BAT
@pytest.mark.assetpipeline
@@ -52,7 +52,7 @@ class TestAutomationBase:
cls._kill_ly_processes()
def _run_test(self, request, workspace, editor, testcase_module, extra_cmdline_args=[], batch_mode=True,
autotest_mode=True, use_null_renderer=True):
autotest_mode=True, use_null_renderer=True, enable_prefab_system=True):
test_starttime = time.time()
self.logger = logging.getLogger(__name__)
errors = []
@@ -97,6 +97,11 @@ class TestAutomationBase:
pycmd += ["-BatchMode"]
if autotest_mode:
pycmd += ["-autotest_mode"]
if enable_prefab_system:
pycmd += ["--regset=/Amazon/Preferences/EnablePrefabSystem=true"]
else:
pycmd += ["--regset=/Amazon/Preferences/EnablePrefabSystem=false"]
pycmd += extra_cmdline_args
editor.args.extend(pycmd) # args are added to the WinLauncher start command
editor.start(backupFiles = False, launch_ap = False)
@@ -165,7 +170,7 @@ class TestAutomationBase:
for line in f.readlines():
error_str += f"|{log_basename}| {line}"
except Exception as ex:
error_str += "-- No log available --"
error_str += f"-- No log available ({ex})--"
pytest.fail(error_str)
@@ -62,7 +62,7 @@ def AssetBrowser_SearchFiltering():
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
def verify_files_appeared(model, allowed_asset_extentions, parent_index=QtCore.QModelIndex()):
def verify_files_appeared(model, allowed_asset_extensions, parent_index=QtCore.QModelIndex()):
indexes = [parent_index]
while len(indexes) > 0:
parent_index = indexes.pop(0)
@@ -71,7 +71,7 @@ def AssetBrowser_SearchFiltering():
cur_data = cur_index.data(Qt.DisplayRole)
if (
"." in cur_data
and (cur_data.lower().split(".")[-1] not in allowed_asset_extentions)
and (cur_data.lower().split(".")[-1] not in allowed_asset_extensions)
and not cur_data[-1] == ")"
):
Report.info(f"Incorrect file found: {cur_data}")
@@ -94,16 +94,21 @@ def AssetBrowser_SearchFiltering():
Report.info("Asset Browser is already open")
editor_window = pyside_utils.get_editor_main_window()
app = QtWidgets.QApplication.instance()
# 3) Type the name of an asset in the search bar and make sure only one asset is filtered in Asset browser
# 3) Type the name of an asset in the search bar and make sure it is filtered to and selectable
asset_browser = editor_window.findChild(QtWidgets.QDockWidget, "Asset Browser")
search_bar = asset_browser.findChild(QtWidgets.QLineEdit, "textSearch")
search_bar.setText("cedar.fbx")
asset_browser_tree = asset_browser.findChild(QtWidgets.QTreeView, "m_assetBrowserTreeViewWidget")
model_index = pyside_utils.find_child_by_pattern(asset_browser_tree, "cedar.fbx")
pyside_utils.item_view_index_mouse_click(asset_browser_tree, model_index)
asset_browser_table = asset_browser.findChild(QtWidgets.QTreeView, "m_assetBrowserTableViewWidget")
found = await pyside_utils.wait_for_condition(lambda: pyside_utils.find_child_by_pattern(asset_browser_table, "cedar.fbx"), 5.0)
if found:
model_index = pyside_utils.find_child_by_pattern(asset_browser_table, "cedar.fbx")
else:
Report.result(Tests.asset_filtered, found)
pyside_utils.item_view_index_mouse_click(asset_browser_table, model_index)
is_filtered = await pyside_utils.wait_for_condition(
lambda: asset_browser_tree.indexBelow(asset_browser_tree.currentIndex()) == QtCore.QModelIndex(), 5.0)
lambda: asset_browser_table.currentIndex() == model_index, 5.0)
Report.result(Tests.asset_filtered, is_filtered)
# 4) Click the "X" in the search bar.
@@ -84,8 +84,8 @@ def AssetBrowser_TreeNavigation():
# 3) Collapse all files initially
main_window = editor_window.findChild(QtWidgets.QMainWindow)
asset_browser = pyside_utils.find_child_by_hierarchy(main_window, ..., "Asset Browser")
tree = pyside_utils.find_child_by_hierarchy(asset_browser, ..., "m_assetBrowserTreeViewWidget")
asset_browser = pyside_utils.find_child_by_pattern(main_window, text="Asset Browser", type=QtWidgets.QDockWidget)
tree = pyside_utils.find_child_by_pattern(asset_browser, "m_assetBrowserTreeViewWidget")
scroll_area = tree.findChild(QtWidgets.QWidget, "qt_scrollarea_vcontainer")
scroll_bar = scroll_area.findChild(QtWidgets.QScrollBar)
tree.collapseAll()
@@ -140,13 +140,13 @@ def Docking_BasicDockedTools():
# 2.5,6) Send a console command.
console_line_edit = console.findChild(QtWidgets.QLineEdit, "lineEdit")
console_line_edit.setText("t_Scale 2")
console_line_edit.setText("t_simulationTickScale 2")
QtTest.QTest.keyClick(console_line_edit, QtCore.Qt.Key_Enter)
general.get_cvar("t_Scale")
Report.result(Tests.docked_console_works, general.get_cvar("t_Scale") == "2")
general.get_cvar("t_simulationTickScale")
Report.result(Tests.docked_console_works, general.get_cvar("t_simulationTickScale") == "2")
# Reset the altered cvar
console_line_edit.setText("t_Scale 1")
console_line_edit.setText("t_simulationTickScale 1")
QtTest.QTest.keyClick(console_line_edit, QtCore.Qt.Key_Enter)
run_test()
@@ -0,0 +1,147 @@
"""
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:
entities_sorted = (
"Entities sorted in the expected order",
"Entities sorted in an incorrect order",
)
def EntityOutliner_EntityOrdering():
"""
Summary:
Verify that manual entity ordering in the entity outliner works and is stable.
Expected Behavior:
Several entities are created, some are manually ordered, and their order
is maintained, even when new entities are added.
Test Steps:
1) Open the empty Prefab Base level
2) Add 5 entities to the outliner
3) Move "Entity1" to the top of the order
4) Move "Entity4" to the bottom of the order
5) Add another new entity, ensure the rest of the order is unchanged
"""
import editor_python_test_tools.pyside_utils as pyside_utils
import azlmbr.legacy.general as general
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
from PySide2 import QtCore, QtWidgets, QtGui, QtTest
# Grab the Editor, Entity Outliner, and Outliner Model
editor_window = pyside_utils.get_editor_main_window()
entity_outliner = pyside_utils.find_child_by_hierarchy(
editor_window, ..., "EntityOutlinerWidgetUI", ..., "m_objectTree"
)
entity_outliner_model = entity_outliner.model()
# Get the outliner index for the root prefab container entity
def get_root_prefab_container_index():
return entity_outliner_model.index(0, 0)
# Get the outliner index for the top level entity of a given name
def index_for_name(name):
root_index = get_root_prefab_container_index()
for row in range(entity_outliner_model.rowCount(root_index)):
row_index = entity_outliner_model.index(row, 0, root_index)
if row_index.data() == name:
return row_index
return None
# Validate that the outliner top level entity order matches the expected order
def verify_entities_sorted(expected_order):
actual_order = []
root_index = get_root_prefab_container_index()
for row in range(entity_outliner_model.rowCount(root_index)):
row_index = entity_outliner_model.index(row, 0, root_index)
actual_order.append(row_index.data())
sorted_correctly = actual_order == expected_order
Report.result(Tests.entities_sorted, sorted_correctly)
if not sorted_correctly:
print(f"Expected entity order: {expected_order}")
print(f"Actual entity order: {actual_order}")
# Creates an entity from the outliner context menu
def create_entity():
pyside_utils.trigger_context_menu_entry(
entity_outliner, "Create entity", index=get_root_prefab_container_index()
)
# Wait a tick after entity creation to let events process
general.idle_wait(0.0)
# Moves an entity (wrapped by move_entity_before and move_entity_after)
def _move_entity(source_name, target_name, move_after=False):
source_index = index_for_name(source_name)
target_index = index_for_name(target_name)
target_row = target_index.row()
if move_after:
target_row += 1
# Generate MIME data and directly inject it into the model instead of
# generating mouse click operations, as it's more reliable and we're
# testing the underlying drag & drop logic as opposed to Qt's mouse
# handling here
mime_data = entity_outliner_model.mimeData([source_index])
entity_outliner_model.dropMimeData(
mime_data, QtCore.Qt.MoveAction, target_row, 0, target_index.parent()
)
# Wait after move to let events (i.e. prefab propagation) process
general.idle_wait(1.0)
# Move an entity before another entity in the order by dragging the source above the target
move_entity_before = lambda source_name, target_name: _move_entity(
source_name, target_name, move_after=False
)
# Move an entity after another entity in the order by dragging the source beloew the target
move_entity_after = lambda source_name, target_name: _move_entity(
source_name, target_name, move_after=True
)
expected_order = []
# 1) Open the empty Prefab Base level
helper.init_idle()
helper.open_level("Prefab", "Base")
# 2) Add 5 entities to the outliner
ENTITIES_TO_ADD = 5
for i in range(ENTITIES_TO_ADD):
create_entity()
# Our new entity should be given a name with a number automatically
new_entity = f"Entity{i+1}"
# The new entity should be added to the bottom of its parent entity
expected_order = expected_order + [new_entity]
verify_entities_sorted(expected_order)
# 3) Move "Entity5" to the top of the order
move_entity_before("Entity5", "Entity1")
expected_order = ["Entity5", "Entity1", "Entity2", "Entity3", "Entity4"]
verify_entities_sorted(expected_order)
# 4) Move "Entity2" to the bottom of the order
move_entity_after("Entity2", "Entity4")
expected_order = ["Entity5", "Entity1", "Entity3", "Entity4", "Entity2"]
verify_entities_sorted(expected_order)
# 5) Add another new entity, ensure the rest of the order is unchanged
create_entity()
expected_order = ["Entity5", "Entity1", "Entity3", "Entity4", "Entity2", "Entity6"]
verify_entities_sorted(expected_order)
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(EntityOutliner_EntityOrdering)
@@ -33,11 +33,22 @@ class TestAutomation(TestAutomationBase):
def test_BasicEditorWorkflows_LevelEntityComponentCRUD(self, request, workspace, editor, launcher_platform,
remove_test_level):
from .EditorScripts import BasicEditorWorkflows_LevelEntityComponentCRUD as test_module
self._run_test(request, workspace, editor, test_module, batch_mode=False, autotest_mode=False)
self._run_test(request, workspace, editor, test_module, batch_mode=False, autotest_mode=False, enable_prefab_system=False)
@pytest.mark.REQUIRES_gpu
def test_BasicEditorWorkflows_GPU_LevelEntityComponentCRUD(self, request, workspace, editor, launcher_platform,
remove_test_level):
from .EditorScripts import BasicEditorWorkflows_LevelEntityComponentCRUD as test_module
self._run_test(request, workspace, editor, test_module, batch_mode=False, autotest_mode=False,
use_null_renderer=False)
use_null_renderer=False, enable_prefab_system=False)
def test_EntityOutlienr_EntityOrdering(self, request, workspace, editor, launcher_platform):
from .EditorScripts import EntityOutliner_EntityOrdering as test_module
self._run_test(
request,
workspace,
editor,
test_module,
batch_mode=False,
autotest_mode=True,
)
@@ -21,6 +21,8 @@ class TestAutomationNoAutoTestMode(EditorTestSuite):
# Disable -autotest_mode and -BatchMode. Tests cannot run in -BatchMode due to UI interactions, and these tests
# interact with modal dialogs
global_extra_cmdline_args = []
enable_prefab_system = False
class test_BasicEditorWorkflows_LevelEntityComponentCRUD(EditorSingleTest):
# Custom teardown to remove slice asset created during test
@@ -43,7 +45,6 @@ class TestAutomationNoAutoTestMode(EditorTestSuite):
class test_InputBindings_Add_Remove_Input_Events(EditorSharedTest):
from .EditorScripts import InputBindings_Add_Remove_Input_Events as test_module
@pytest.mark.skip(reason="Crashes Editor: ATOM-15493")
class test_AssetPicker_UI_UX(EditorSharedTest):
from .EditorScripts import AssetPicker_UI_UX as test_module
@@ -57,10 +58,11 @@ class TestAutomationAutoTestMode(EditorTestSuite):
# Enable only -autotest_mode for these tests. Tests cannot run in -BatchMode due to UI interactions
global_extra_cmdline_args = ["-autotest_mode"]
enable_prefab_system = False
class test_AssetBrowser_TreeNavigation(EditorSharedTest):
from .EditorScripts import AssetBrowser_TreeNavigation as test_module
@pytest.mark.skip(reason="Crashes Editor: ATOM-15493")
class test_AssetBrowser_SearchFiltering(EditorSharedTest):
from .EditorScripts import AssetBrowser_SearchFiltering as test_module
@@ -74,6 +76,5 @@ class TestAutomationAutoTestMode(EditorTestSuite):
class test_Menus_FileMenuOptions_Work(EditorSharedTest):
from .EditorScripts import Menus_FileMenuOptions as test_module
class test_BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD(EditorSharedTest):
from .EditorScripts import BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD as test_module
@@ -32,31 +32,29 @@ class TestAutomation(TestAutomationBase):
def test_AssetBrowser_TreeNavigation(self, request, workspace, editor, launcher_platform):
from .EditorScripts import AssetBrowser_TreeNavigation as test_module
self._run_test(request, workspace, editor, test_module, batch_mode=False)
self._run_test(request, workspace, editor, test_module, batch_mode=False, enable_prefab_system=False)
@pytest.mark.skip(reason="Crashes Editor: ATOM-15493")
def test_AssetBrowser_SearchFiltering(self, request, workspace, editor, launcher_platform):
from .EditorScripts import AssetBrowser_SearchFiltering as test_module
self._run_test(request, workspace, editor, test_module, batch_mode=False)
self._run_test(request, workspace, editor, test_module, batch_mode=False, enable_prefab_system=False)
@pytest.mark.skip(reason="Crashes Editor: ATOM-15493")
def test_AssetPicker_UI_UX(self, request, workspace, editor, launcher_platform):
from .EditorScripts import AssetPicker_UI_UX as test_module
self._run_test(request, workspace, editor, test_module, autotest_mode=False, batch_mode=False)
self._run_test(request, workspace, editor, test_module, autotest_mode=False, batch_mode=False, enable_prefab_system=False)
def test_ComponentCRUD_Add_Delete_Components(self, request, workspace, editor, launcher_platform):
from .EditorScripts import ComponentCRUD_Add_Delete_Components as test_module
self._run_test(request, workspace, editor, test_module, batch_mode=False)
self._run_test(request, workspace, editor, test_module, batch_mode=False, enable_prefab_system=False)
def test_InputBindings_Add_Remove_Input_Events(self, request, workspace, editor, launcher_platform):
from .EditorScripts import InputBindings_Add_Remove_Input_Events as test_module
self._run_test(request, workspace, editor, test_module, batch_mode=False, autotest_mode=False)
self._run_test(request, workspace, editor, test_module, batch_mode=False, autotest_mode=False, enable_prefab_system=False)
def test_Menus_ViewMenuOptions_Work(self, request, workspace, editor, launcher_platform):
from .EditorScripts import Menus_ViewMenuOptions as test_module
self._run_test(request, workspace, editor, test_module, batch_mode=False)
self._run_test(request, workspace, editor, test_module, batch_mode=False, enable_prefab_system=False)
@pytest.mark.skip(reason="Times out due to dialogs failing to dismiss: LYN-4208")
def test_Menus_FileMenuOptions_Work(self, request, workspace, editor, launcher_platform):
from .EditorScripts import Menus_FileMenuOptions as test_module
self._run_test(request, workspace, editor, test_module, batch_mode=False)
self._run_test(request, workspace, editor, test_module, batch_mode=False, enable_prefab_system=False)
@@ -20,8 +20,8 @@ class TestAutomation(TestAutomationBase):
def test_Menus_EditMenuOptions_Work(self, request, workspace, editor, launcher_platform):
from .EditorScripts import Menus_EditMenuOptions as test_module
self._run_test(request, workspace, editor, test_module, batch_mode=False)
self._run_test(request, workspace, editor, test_module, batch_mode=False, enable_prefab_system=False)
def test_Docking_BasicDockedTools(self, request, workspace, editor, launcher_platform):
from .EditorScripts import Docking_BasicDockedTools as test_module
self._run_test(request, workspace, editor, test_module, batch_mode=False)
self._run_test(request, workspace, editor, test_module, batch_mode=False, enable_prefab_system=False)
@@ -19,6 +19,8 @@ class TestAutomationAutoTestMode(EditorTestSuite):
# Enable only -autotest_mode for these tests. Tests cannot run in -BatchMode due to UI interactions
global_extra_cmdline_args = ["-autotest_mode"]
enable_prefab_system = False
class test_Docking_BasicDockedTools(EditorSharedTest):
from .EditorScripts import Docking_BasicDockedTools as test_module
@@ -24,7 +24,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
LargeWorlds
)
ly_add_pytest(
NAME AutomatedTesting::DynamicVegetationTests_Periodic
TEST_SERIAL
@@ -39,6 +38,20 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
LargeWorlds
)
ly_add_pytest(
NAME AutomatedTesting::DynamicVegetationTests_Periodic_Optimized
TEST_SERIAL
TEST_SUITE periodic
PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg/TestSuite_Periodic_Optimized.py
RUNTIME_DEPENDENCIES
AZ::AssetProcessor
Legacy::Editor
AutomatedTesting.Assets
AutomatedTesting.GameLauncher
COMPONENT
LargeWorlds
)
ly_add_pytest(
NAME AutomatedTesting::DynamicVegetationTests_Main_Optimized
TEST_SERIAL
@@ -0,0 +1,85 @@
"""
Copyright (c) Contributors to the Open 3D Engine Project.
For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
def DynVegUtils_TempPrefabCreationWorks():
"""
Summary:
An existing level is opened. Each Prefab setup to be spawned by Dynamic Vegetation tests is created in memory and
validated against existing test slice components/mesh assignments.
Expected Behavior:
Temporary prefabs contain the expected components/assets.
Test Steps:
1) Open an existing level
2) Create each of the necessary temporary Mesh prefabs, and validate the component/mesh setups
3) Create the necessary temporary PhysX Collider, and validate the component setup
4) Report errors/asserts
:return: None
"""
import os
import azlmbr.asset as asset
import azlmbr.bus as bus
import azlmbr.math as math
from Prefab.tests import PrefabTestUtils as prefab_test_utils
from largeworlds.large_worlds_utils import editor_dynveg_test_helper as dynveg
from editor_python_test_tools.utils import Report, Tracer
from editor_python_test_tools.utils import TestHelper as helper
from editor_python_test_tools.prefab_utils import PrefabInstance
with Tracer() as error_tracer:
# Create dictionary for prefab filenames and paths to create using helper function
mesh_prefabs = {
"PinkFlower": os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel"),
"PurpleFlower": os.path.join("assets", "objects", "foliage", "grass_flower_purple.azmodel"),
"1m_Cube": os.path.join("objects", "_primitives", "_box_1x1.azmodel"),
"CedarTree": os.path.join("assets", "objects", "foliage", "cedar.azmodel"),
"Bush": os.path.join("assets", "objects", "foliage", "bush_privet_01.azmodel"),
}
# 1) Open an existing simple level
prefab_test_utils.open_base_tests_level()
# 2) Create each of the Mesh asset prefabs and validate that the prefab created successfully
for prefab_filename, asset_path in mesh_prefabs.items():
mesh_prefab_created = (
f"Temporary mesh prefab: {prefab_filename} created successfully",
f"Failed to create temporary mesh prefab: {prefab_filename}"
)
prefab = dynveg.create_temp_mesh_prefab(asset_path, prefab_filename)
Report.result(mesh_prefab_created, helper.wait_for_condition(lambda:
PrefabInstance.is_valid(prefab[1]), 3.0))
# 3) Create temp PhysX Collider prefab and validate that the prefab created successfully
physx_prefab_filename = "CedarTree_Collision"
physx_collider_prefab_created = (
f"Temporary mesh prefab: {physx_prefab_filename} created successfully",
f"Failed to create temporary mesh prefab: {physx_prefab_filename}"
)
test_physx_mesh_asset_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", os.path.join(
"assets", "objects", "foliage", "cedar.pxmesh"), math.Uuid(), False)
dynveg.create_temp_physx_mesh_collider(test_physx_mesh_asset_id, physx_prefab_filename)
Report.result(physx_collider_prefab_created, helper.wait_for_condition(lambda:
PrefabInstance.is_valid(prefab[1]), 3.0))
# 4) Report errors/asserts
helper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
for error_info in error_tracer.errors:
Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
for assert_info in error_tracer.asserts:
Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}")
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(DynVegUtils_TempPrefabCreationWorks)
@@ -20,8 +20,8 @@ class TestAutomation(TestAutomationBase):
def test_DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks(self, request, workspace, editor, launcher_platform):
from .EditorScripts import DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_EmptyInstanceSpawner_EmptySpawnerWorks(self, request, workspace, editor, launcher_platform):
from .EditorScripts import EmptyInstanceSpawner_EmptySpawnerWorks as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@@ -18,6 +18,8 @@ from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, E
@pytest.mark.parametrize("project", ["AutomatedTesting"])
class TestAutomation(EditorTestSuite):
enable_prefab_system = False
class test_DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks(EditorParallelTest):
from .EditorScripts import DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks as test_module
@@ -52,158 +52,158 @@ class TestAutomation(TestAutomationBase):
def test_AltitudeFilter_ComponentAndOverrides_InstancesPlantAtSpecifiedAltitude(self, request, workspace, editor, launcher_platform):
from .EditorScripts import AltitudeFilter_ComponentAndOverrides_InstancesPlantAtSpecifiedAltitude as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_AltitudeFilter_ShapeSample_InstancesPlantAtSpecifiedAltitude(self, request, workspace, editor, launcher_platform):
from .EditorScripts import AltitudeFilter_ShapeSample_InstancesPlantAtSpecifiedAltitude as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_AltitudeFilter_FilterStageToggle(self, request, workspace, editor, launcher_platform):
from .EditorScripts import AltitudeFilter_FilterStageToggle as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_SpawnerSlices_SliceCreationAndVisibilityToggleWorks(self, request, workspace, editor, remove_test_slice, launcher_platform):
from .EditorScripts import SpawnerSlices_SliceCreationAndVisibilityToggleWorks as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea(self, request, workspace, editor, launcher_platform):
from .EditorScripts import AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_AssetWeightSelector_InstancesExpressBasedOnWeight(self, request, workspace, editor, launcher_platform):
from .EditorScripts import AssetWeightSelector_InstancesExpressBasedOnWeight as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/4155")
def test_DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius(self, request, workspace, editor, launcher_platform):
from .EditorScripts import DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/4155")
def test_DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius(self, request, workspace, editor, launcher_platform):
from .EditorScripts import DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_SurfaceDataRefreshes_RemainsStable(self, request, workspace, editor, launcher_platform):
from .EditorScripts import SurfaceDataRefreshes_RemainsStable as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_VegetationInstances_DespawnWhenOutOfRange(self, request, workspace, editor, launcher_platform):
from .EditorScripts import VegetationInstances_DespawnWhenOutOfRange as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_InstanceSpawnerPriority_LayerAndSubPriority_HigherValuesPlantOverLower(self, request, workspace, editor, launcher_platform):
from .EditorScripts import InstanceSpawnerPriority_LayerAndSubPriority as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LayerBlocker_InstancesBlockedInConfiguredArea(self, request, workspace, editor, launcher_platform):
from .EditorScripts import LayerBlocker_InstancesBlockedInConfiguredArea as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LayerSpawner_InheritBehaviorFlag(self, request, workspace, editor, launcher_platform):
from .EditorScripts import LayerSpawner_InheritBehaviorFlag as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LayerSpawner_InstancesPlantInAllSupportedShapes(self, request, workspace, editor, launcher_platform):
from .EditorScripts import LayerSpawner_InstancesPlantInAllSupportedShapes as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LayerSpawner_FilterStageToggle(self, request, workspace, editor, launcher_platform):
from .EditorScripts import LayerSpawner_FilterStageToggle as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/2038")
def test_LayerSpawner_InstancesRefreshUsingCorrectViewportCamera(self, request, workspace, editor, launcher_platform):
from .EditorScripts import LayerSpawner_InstancesRefreshUsingCorrectViewportCamera as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_MeshBlocker_InstancesBlockedByMesh(self, request, workspace, editor, launcher_platform):
from .EditorScripts import MeshBlocker_InstancesBlockedByMesh as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_MeshBlocker_InstancesBlockedByMeshHeightTuning(self, request, workspace, editor, launcher_platform):
from .EditorScripts import MeshBlocker_InstancesBlockedByMeshHeightTuning as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_MeshSurfaceTagEmitter_DependentOnMeshComponent(self, request, workspace, editor, launcher_platform):
from .EditorScripts import MeshSurfaceTagEmitter_DependentOnMeshComponent as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_MeshSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully(self, request, workspace, editor, launcher_platform):
from .EditorScripts import MeshSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_PhysXColliderSurfaceTagEmitter_E2E_Editor(self, request, workspace, editor, launcher_platform):
from .EditorScripts import PhysXColliderSurfaceTagEmitter_E2E_Editor as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_PositionModifier_ComponentAndOverrides_InstancesPlantAtSpecifiedOffsets(self, request, workspace, editor, launcher_platform):
from .EditorScripts import PositionModifier_ComponentAndOverrides_InstancesPlantAtSpecifiedOffsets as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_PositionModifier_AutoSnapToSurfaceWorks(self, request, workspace, editor, launcher_platform):
from .EditorScripts import PositionModifier_AutoSnapToSurfaceWorks as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_RotationModifier_InstancesRotateWithinRange(self, request, workspace, editor, launcher_platform):
from .EditorScripts import RotationModifier_InstancesRotateWithinRange as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_RotationModifierOverrides_InstancesRotateWithinRange(self, request, workspace, editor, launcher_platform):
from .EditorScripts import RotationModifierOverrides_InstancesRotateWithinRange as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ScaleModifier_InstancesProperlyScale(self, request, workspace, editor, launcher_platform):
from .EditorScripts import ScaleModifier_InstancesProperlyScale as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ScaleModifierOverrides_InstancesProperlyScale(self, request, workspace, editor, launcher_platform):
from .EditorScripts import ScaleModifierOverrides_InstancesProperlyScale as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ShapeIntersectionFilter_InstancesPlantInAssignedShape(self, request, workspace, editor, launcher_platform):
from .EditorScripts import ShapeIntersectionFilter_InstancesPlantInAssignedShape as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ShapeIntersectionFilter_FilterStageToggle(self, request, workspace, editor, launcher_platform):
from .EditorScripts import ShapeIntersectionFilter_FilterStageToggle as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_SlopeAlignmentModifier_InstanceSurfaceAlignment(self, request, workspace, editor, launcher_platform):
from .EditorScripts import SlopeAlignmentModifier_InstanceSurfaceAlignment as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_SlopeAlignmentModifierOverrides_InstanceSurfaceAlignment(self, request, workspace, editor, launcher_platform):
from .EditorScripts import SlopeAlignmentModifierOverrides_InstanceSurfaceAlignment as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_SurfaceMaskFilter_BasicSurfaceTagCreation(self, request, workspace, editor, launcher_platform):
from .EditorScripts import SurfaceMaskFilter_BasicSurfaceTagCreation as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_SurfaceMaskFilter_ExclusiveSurfaceTags_Function(self, request, workspace, editor, launcher_platform):
from .EditorScripts import SurfaceMaskFilter_ExclusionList as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_SurfaceMaskFilter_InclusiveSurfaceTags_Function(self, request, workspace, editor, launcher_platform):
from .EditorScripts import SurfaceMaskFilter_InclusionList as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_SurfaceMaskFilterOverrides_MultipleDescriptorOverridesPlantAsExpected(self, request, workspace, editor, launcher_platform):
from .EditorScripts import SurfaceMaskFilterOverrides_MultipleDescriptorOverridesPlantAsExpected as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_SystemSettings_SectorPointDensity(self, request, workspace, editor, launcher_platform):
from .EditorScripts import SystemSettings_SectorPointDensity as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_SystemSettings_SectorSize(self, request, workspace, editor, launcher_platform):
from .EditorScripts import SystemSettings_SectorSize as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlopes(self, request, workspace, editor, launcher_platform):
from .EditorScripts import SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlope as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.SUITE_periodic
@@ -219,7 +219,7 @@ class TestAutomationE2E(TestAutomationBase):
file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
from .EditorScripts import DynamicSliceInstanceSpawner_Embedded_E2E as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.parametrize("launcher_platform", ['windows'])
def test_DynamicSliceInstanceSpawner_Embedded_E2E_Launcher(self, workspace, launcher, level,
@@ -240,7 +240,7 @@ class TestAutomationE2E(TestAutomationBase):
file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
from .EditorScripts import DynamicSliceInstanceSpawner_External_E2E as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.parametrize("launcher_platform", ['windows'])
def test_DynamicSliceInstanceSpawner_External_E2E_Launcher(self, workspace, launcher, level,
@@ -261,7 +261,7 @@ class TestAutomationE2E(TestAutomationBase):
file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
from .EditorScripts import LayerBlender_E2E_Editor as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.parametrize("launcher_platform", ['windows'])
@pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/4170")
@@ -0,0 +1,23 @@
"""
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_main
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
@pytest.mark.parametrize("project", ["AutomatedTesting"])
class TestAutomation(EditorTestSuite):
global_extra_cmdline_args = ["-BatchMode", "-autotest_mode"]
class test_DynVegUtils_TempPrefabCreationWorks(EditorSharedTest):
from .EditorScripts import DynVegUtils_TempPrefabCreationWorks as test_module
@@ -20,52 +20,52 @@ class TestAutomation(TestAutomationBase):
def test_GradientGenerators_Incompatibilities(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientGenerators_Incompatibilities as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_GradientModifiers_Incompatibilities(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientModifiers_Incompatibilities as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_GradientPreviewSettings_DefaultPinnedEntityIsSelf(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientPreviewSettings_DefaultPinnedEntityIsSelf as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_GradientPreviewSettings_ClearingPinnedEntitySetsPreviewToOrigin(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientPreviewSettings_ClearingPinnedEntitySetsPreviewToOrigin as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_GradientSampling_GradientReferencesAddRemoveSuccessfully(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientSampling_GradientReferencesAddRemoveSuccessfully as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_GradientSurfaceTagEmitter_ComponentDependencies(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientSurfaceTagEmitter_ComponentDependencies as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_GradientSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_GradientTransform_RequiresShape(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientTransform_RequiresShape as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_GradientTransform_FrequencyZoomCanBeSetBeyondSliderRange(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientTransform_FrequencyZoomCanBeSetBeyondSliderRange as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_GradientTransform_ComponentIncompatibleWithSpawners(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientTransform_ComponentIncompatibleWithSpawners as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_GradientTransform_ComponentIncompatibleWithExpectedGradients(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientTransform_ComponentIncompatibleWithExpectedGradients as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ImageGradient_RequiresShape(self, request, workspace, editor, launcher_platform):
from .EditorScripts import ImageGradient_RequiresShape as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ImageGradient_ProcessedImageAssignedSuccessfully(self, request, workspace, editor, launcher_platform):
from .EditorScripts import ImageGradient_ProcessedImageAssignedSuccessfully as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@@ -15,6 +15,8 @@ from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, E
@pytest.mark.parametrize("project", ["AutomatedTesting"])
class TestAutomation(EditorTestSuite):
enable_prefab_system = False
class test_GradientGenerators_Incompatibilities(EditorSharedTest):
from .EditorScripts import GradientGenerators_Incompatibilities as test_module
@@ -22,8 +22,8 @@ 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)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
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)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@@ -18,6 +18,8 @@ from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, E
@pytest.mark.parametrize("project", ["AutomatedTesting"])
class TestAutomation(EditorTestSuite):
enable_prefab_system = False
class test_LandscapeCanvas_SlotConnections_UpdateComponentReferences(EditorSharedTest):
from .EditorScripts import SlotConnections_UpdateComponentReferences as test_module
@@ -33,89 +33,89 @@ 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)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_AreaNodes_EntityCreatedOnNodeAdd(self, request, workspace, editor, launcher_platform):
from .EditorScripts import AreaNodes_EntityCreatedOnNodeAdd as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_AreaNodes_EntityRemovedOnNodeDelete(self, request, workspace, editor, launcher_platform):
from .EditorScripts import AreaNodes_EntityRemovedOnNodeDelete as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_LayerExtenderNodes_ComponentEntitySync(self, request, workspace, editor, launcher_platform):
from .EditorScripts import LayerExtenderNodes_ComponentEntitySync as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_Edit_DisabledNodeDuplication(self, request, workspace, editor, launcher_platform):
from .EditorScripts import Edit_DisabledNodeDuplication as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_Edit_UndoNodeDelete_SliceEntity(self, request, workspace, editor, launcher_platform):
from .EditorScripts import Edit_UndoNodeDelete_SliceEntity as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_NewGraph_CreatedSuccessfully(self, request, workspace, editor, launcher_platform):
from .EditorScripts import NewGraph_CreatedSuccessfully as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_Component_AddedRemoved(self, request, workspace, editor, launcher_platform):
from .EditorScripts import Component_AddedRemoved as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_GraphClosed_OnLevelChange(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GraphClosed_OnLevelChange as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/2201")
def test_LandscapeCanvas_GraphClosed_OnEntityDelete(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GraphClosed_OnEntityDelete as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_GraphClosed_TabbedGraphClosesIndependently(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GraphClosed_TabbedGraph as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_Slice_CreateInstantiate(self, request, workspace, editor, remove_test_slice, launcher_platform):
from .EditorScripts import Slice_CreateInstantiate as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_GradientModifierNodes_EntityCreatedOnNodeAdd(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientModifierNodes_EntityCreatedOnNodeAdd as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_GradientModifierNodes_EntityRemovedOnNodeDelete(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientModifierNodes_EntityRemovedOnNodeDelete as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_GradientNodes_DependentComponentsAdded(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientNodes_DependentComponentsAdded as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_GradientNodes_EntityCreatedOnNodeAdd(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientNodes_EntityCreatedOnNodeAdd as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_GradientNodes_EntityRemovedOnNodeDelete(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientNodes_EntityRemovedOnNodeDelete as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_GraphUpdates_UpdateComponents(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GraphUpdates_UpdateComponents as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_ComponentUpdates_UpdateGraph(self, request, workspace, editor, launcher_platform):
from .EditorScripts import ComponentUpdates_UpdateGraph as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_LayerBlender_NodeConstruction(self, request, workspace, editor, launcher_platform):
from .EditorScripts import LayerBlender_NodeConstruction as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_ShapeNodes_EntityCreatedOnNodeAdd(self, request, workspace, editor, launcher_platform):
from .EditorScripts import ShapeNodes_EntityCreatedOnNodeAdd as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_ShapeNodes_EntityRemovedOnNodeDelete(self, request, workspace, editor, launcher_platform):
from .EditorScripts import ShapeNodes_EntityRemovedOnNodeDelete as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@@ -19,6 +19,45 @@ import azlmbr.paths
sys.path.append(os.path.join(azlmbr.paths.projectroot, 'Gem', 'PythonTests'))
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.editor_entity_utils import EditorEntity
from editor_python_test_tools.prefab_utils import Prefab
def create_temp_mesh_prefab(mesh_asset_path, prefab_filename):
# Create initial entity
root = EditorEntity.create_editor_entity(name=prefab_filename)
assert root.exists(), "Failed to create entity"
# Add mesh component
mesh_component = root.add_component("Mesh")
assert root.has_component("Mesh") and mesh_component.is_enabled(), "Failed to add/activate Mesh component"
# Assign the specified mesh asset
mesh_asset = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", mesh_asset_path, math.Uuid(), False)
mesh_component.set_component_property_value("Controller|Configuration|Mesh Asset", mesh_asset)
assert mesh_component.get_component_property_value("Controller|Configuration|Mesh Asset") == mesh_asset, \
"Failed to set Mesh asset"
# Create and return the temporary/in-memory prefab
temp_prefab = Prefab.create_prefab([root], prefab_filename)
return temp_prefab
def create_temp_physx_mesh_collider(physx_mesh_id, prefab_filename):
# Create initial entity
root = EditorEntity.create_editor_entity(name=prefab_filename)
assert root.exists(), "Failed to create entity"
# Add PhysX Collider component
collider_component = root.add_component("PhysX Collider")
assert root.has_component("PhysX Collider") and collider_component.is_enabled(), \
"Failed to add/activate PhysX Collider component"
# Set the Collider's Shape Configuration field to PhysicsAsset, and assign the specified PhysX Mesh asset
collider_component.set_component_property_value("Shape Configuration|Shape", 7)
assert collider_component.get_component_property_value("Shape Configuration|Shape") == 7, \
"Failed to set Collider Shape to PhysicsAsset"
collider_component.set_component_property_value("Shape Configuration|Asset|PhysX Mesh", physx_mesh_id)
assert collider_component.get_component_property_value("Shape Configuration|Asset|PhysX Mesh") == physx_mesh_id, \
"Failed to assign PhysX Mesh asset"
# Create and return the temporary/in-memory prefab
temp_prefab = Prefab.create_prefab([root], prefab_filename)
return temp_prefab
def create_surface_entity(name, center_point, box_size_x, box_size_y, box_size_z):

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