Sfoglia il codice sorgente

Integrating github/staging through commit ab87ed9

alexpete 4 anni fa
parent
commit
1044dc3da1
100 ha cambiato i file con 2015 aggiunte e 581 eliminazioni
  1. 18 0
      AutomatedTesting/Config/AtomImageBuilder/Test_Linear_to_Auto.preset
  2. 18 0
      AutomatedTesting/Config/AtomImageBuilder/Test_Linear_to_Linear.preset
  3. 18 0
      AutomatedTesting/Config/AtomImageBuilder/Test_Linear_to_sRGB.preset
  4. 18 0
      AutomatedTesting/Config/AtomImageBuilder/Test_sRGB_to_Auto.preset
  5. 18 0
      AutomatedTesting/Config/AtomImageBuilder/Test_sRGB_to_Linear.preset
  6. 18 0
      AutomatedTesting/Config/AtomImageBuilder/Test_sRGB_to_sRGB.preset
  7. 11 0
      AutomatedTesting/Config/shader_global_build_options.json
  8. 2 0
      AutomatedTesting/Gem/Code/CMakeLists.txt
  9. 0 1
      AutomatedTesting/Gem/Code/Platform/Android/runtime_dependencies.cmake
  10. 1 1
      AutomatedTesting/Gem/Code/Platform/Android/tool_dependencies.cmake
  11. 1 1
      AutomatedTesting/Gem/Code/Platform/Linux/runtime_dependencies.cmake
  12. 0 2
      AutomatedTesting/Gem/Code/Platform/Mac/runtime_dependencies.cmake
  13. 4 2
      AutomatedTesting/Gem/Code/Platform/Windows/runtime_dependencies.cmake
  14. 5 0
      AutomatedTesting/Gem/Code/Platform/Windows/tool_dependencies.cmake
  15. 10 0
      AutomatedTesting/Gem/Code/Platform/iOS/runtime_dependencies.cmake
  16. 10 0
      AutomatedTesting/Gem/Code/Platform/iOS/tool_dependencies.cmake
  17. 12 1
      AutomatedTesting/Gem/Code/runtime_dependencies.cmake
  18. 18 2
      AutomatedTesting/Gem/Code/tool_dependencies.cmake
  19. 69 66
      AutomatedTesting/Gem/PythonTests/CMakeLists.txt
  20. 4 8
      AutomatedTesting/Gem/PythonTests/EditorPythonBindings/ComponentAssetCommands_test.py
  21. 3 8
      AutomatedTesting/Gem/PythonTests/EditorPythonBindings/ComponentAssetCommands_test_case.py
  22. 33 17
      AutomatedTesting/Gem/PythonTests/EditorPythonBindings/ComponentUpdateListProperty_test.py
  23. 0 78
      AutomatedTesting/Gem/PythonTests/EditorPythonBindings/ComponentUpdateListProperty_test_case.py
  24. 87 0
      AutomatedTesting/Gem/PythonTests/EditorPythonBindings/EditorScripts/ComponentUpdateListProperty_test_case.py
  25. 0 0
      AutomatedTesting/Gem/PythonTests/EditorPythonBindings/EditorScripts/__init__.py
  26. 4 4
      AutomatedTesting/Gem/PythonTests/EditorPythonBindings/ViewPaneCommands_test.py
  27. 18 17
      AutomatedTesting/Gem/PythonTests/EditorPythonBindings/ViewPaneCommands_test_case.py
  28. 2 2
      AutomatedTesting/Gem/PythonTests/WhiteBox/FileManagement.py
  29. 1 1
      AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/ap_all_platforms_setup_fixture.py
  30. 3 3
      AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/ap_setup_fixture.py
  31. 2 2
      AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/bundler_batch_setup_fixture.py
  32. 2 2
      AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/clear_moveoutput_fixture.py
  33. 4 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt
  34. 4 4
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_bundler_batch_tests.py
  35. 1 1
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_batch_dependency_tests2.py
  36. 154 155
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/assets_with_nested_preload_dependency/TestA.slice
  37. 0 2
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/missing_dependency_tests.py
  38. 5 5
      AutomatedTesting/Gem/PythonTests/assetpipeline/auxiliary_content_tests/auxiliary_content_tests.py
  39. 1 1
      AutomatedTesting/Gem/PythonTests/assetpipeline/wwise_bank_dependency_tests/bank_info_parser_tests.py
  40. 4 5
      AutomatedTesting/Gem/PythonTests/automatedtesting_shared/editor_test_helper.py
  41. 11 0
      AutomatedTesting/Gem/PythonTests/automatedtesting_shared/hydra_editor_utils.py
  42. 1 1
      AutomatedTesting/Gem/PythonTests/automatedtesting_shared/hydra_test_utils.py
  43. 0 0
      AutomatedTesting/Gem/PythonTests/automatedtesting_shared/registry_utils.py
  44. 3 3
      AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetBrowser_SearchFiltering.py
  45. 1 1
      AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetBrowser_TreeNavigation.py
  46. 262 0
      AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetPicker_UI_UX.py
  47. 3 5
      AutomatedTesting/Gem/PythonTests/editor/EditorScripts/ComponentCRUD_Add_Delete_Components.py
  48. 142 0
      AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Docking_BasicDockedTools.py
  49. 120 0
      AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_EditMenuOptions.py
  50. 90 0
      AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_FileMenuOptions.py
  51. 91 0
      AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_ViewMenuOptions.py
  52. 51 0
      AutomatedTesting/Gem/PythonTests/editor/conftest.py
  53. 92 0
      AutomatedTesting/Gem/PythonTests/editor/test_AssetBrowser.py
  54. 76 0
      AutomatedTesting/Gem/PythonTests/editor/test_AssetPicker.py
  55. 3 9
      AutomatedTesting/Gem/PythonTests/editor/test_ComponentCRUD.py
  56. 58 0
      AutomatedTesting/Gem/PythonTests/editor/test_Docking.py
  57. 2 2
      AutomatedTesting/Gem/PythonTests/editor/test_InputBindings.py
  58. 143 0
      AutomatedTesting/Gem/PythonTests/editor/test_Menus.py
  59. 3 3
      AutomatedTesting/Gem/PythonTests/editor/test_SearchFiltering.py
  60. 2 2
      AutomatedTesting/Gem/PythonTests/editor/test_TreeNavigation.py
  61. 26 6
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AltitudeFilter_FilterStageToggle.py
  62. 33 9
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_FilterStageToggle.py
  63. 25 5
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshBlocker_InstancesBlockedByMesh.py
  64. 34 11
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshBlocker_InstancesBlockedByMeshHeightTuning.py
  65. 26 4
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/PositionModifier_AutoSnapToSurfaceWorks.py
  66. 3 3
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SlopeAlignmentModifierOverrides_InstanceSurfaceAlignment.py
  67. 3 3
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SlopeAlignmentModifier_InstanceSurfaceAlignment.py
  68. 5 5
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_AltitudeFilter.py
  69. 7 7
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_AreaComponentSlices.py
  70. 3 3
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_AssetListCombiner.py
  71. 2 2
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_AssetWeightSelector.py
  72. 3 3
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_Debugger.py
  73. 2 2
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_DistanceBetweenFilter.py
  74. 2 2
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_DynVeg_Regressions.py
  75. 8 6
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_DynamicSliceInstanceSpawner.py
  76. 2 2
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_EmptyInstanceSpawner.py
  77. 3 3
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_InstanceSpawnerPriority.py
  78. 4 4
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_LayerBlender.py
  79. 3 3
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_LayerBlocker.py
  80. 7 6
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_LayerSpawner.py
  81. 5 5
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_MeshBlocker.py
  82. 2 2
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_MeshSurfaceTagEmitter.py
  83. 3 3
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_PhysXColliderSurfaceTagEmitter.py
  84. 4 5
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_PositionModifier.py
  85. 4 4
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_RotationModifier.py
  86. 4 4
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_ScaleModifier.py
  87. 3 3
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_ShapeIntersectionFilter.py
  88. 6 4
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_SlopeAlignmentModifier.py
  89. 5 4
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_SlopeFilter.py
  90. 5 5
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_SurfaceMaskFilter.py
  91. 4 4
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_SystemSettings.py
  92. 1 1
      AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/test_GradientIncompatibilities.py
  93. 2 2
      AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/test_GradientPreviewSettings.py
  94. 2 2
      AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/test_GradientSampling.py
  95. 4 4
      AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/test_GradientSurfaceTagEmitter.py
  96. 2 2
      AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/test_GradientTransform.py
  97. 1 1
      AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/test_ImageGradient.py
  98. 6 6
      AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/test_AreaNodes.py
  99. 4 4
      AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/test_EditFunctionality.py
  100. 10 10
      AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/test_GeneralGraphFunctionality.py

+ 18 - 0
AutomatedTesting/Config/AtomImageBuilder/Test_Linear_to_Auto.preset

@@ -0,0 +1,18 @@
+{
+    "Type": "JsonSerialization",
+    "Version": 1,
+    "ClassName": "MultiplatformPresetSettings",
+    "ClassData": {
+        "DefaultPreset": {
+            "UUID": "{9E5BBFB4-BDDA-4759-AB74-D047EE25A35D}",
+            "Name": "Test_Linear_to_Auto",
+            "SourceColor": "Linear",
+            "DestColor": "Auto",
+            "FileMasks": [
+                "_linear-to-auto"
+            ],
+            "PixelFormat": "R8G8B8X8",
+            "DiscardAlpha": true
+        }
+    }
+}

+ 18 - 0
AutomatedTesting/Config/AtomImageBuilder/Test_Linear_to_Linear.preset

@@ -0,0 +1,18 @@
+{
+    "Type": "JsonSerialization",
+    "Version": 1,
+    "ClassName": "MultiplatformPresetSettings",
+    "ClassData": {
+        "DefaultPreset": {
+            "UUID": "{31199710-5B61-4A30-99F0-18DF724EC308}",
+            "Name": "Test_Linear_to_Linear",
+            "SourceColor": "Linear",
+            "DestColor": "Linear",
+            "FileMasks": [
+                "_linear-to-linear"
+            ],
+            "PixelFormat": "R8G8B8X8",
+            "DiscardAlpha": true
+        }
+    }
+}

+ 18 - 0
AutomatedTesting/Config/AtomImageBuilder/Test_Linear_to_sRGB.preset

@@ -0,0 +1,18 @@
+{
+    "Type": "JsonSerialization",
+    "Version": 1,
+    "ClassName": "MultiplatformPresetSettings",
+    "ClassData": {
+        "DefaultPreset": {
+            "UUID": "{F0E6BE7F-376E-4F1B-9244-70E01C1CABD6}",
+            "Name": "Test_Linear_to_sRGB",
+            "SourceColor": "Linear",
+            "DestColor": "sRGB",
+            "FileMasks": [
+                "_linear-to-srgb"
+            ],
+            "PixelFormat": "R8G8B8X8",
+            "DiscardAlpha": true
+        }
+    }
+}

+ 18 - 0
AutomatedTesting/Config/AtomImageBuilder/Test_sRGB_to_Auto.preset

@@ -0,0 +1,18 @@
+{
+    "Type": "JsonSerialization",
+    "Version": 1,
+    "ClassName": "MultiplatformPresetSettings",
+    "ClassData": {
+        "DefaultPreset": {
+            "UUID": "{EE397A40-4430-437F-B0EF-9EC8B6E35176}",
+            "Name": "Test_sRGB_to_Auto",
+            "SourceColor": "sRGB",
+            "DestColor": "Auto",
+            "FileMasks": [
+                "_srgb-to-auto"
+            ],
+            "PixelFormat": "R8G8B8X8",
+            "DiscardAlpha": true
+        }
+    }
+}

+ 18 - 0
AutomatedTesting/Config/AtomImageBuilder/Test_sRGB_to_Linear.preset

@@ -0,0 +1,18 @@
+{
+    "Type": "JsonSerialization",
+    "Version": 1,
+    "ClassName": "MultiplatformPresetSettings",
+    "ClassData": {
+        "DefaultPreset": {
+            "UUID": "{2865D7A5-B75D-4D9C-9591-47BD2FF93377}",
+            "Name": "Test_sRGB_to_Linear",
+            "SourceColor": "sRGB",
+            "DestColor": "Linear",
+            "FileMasks": [
+                "_srgb-to-linear"
+            ],
+            "PixelFormat": "R8G8B8X8",
+            "DiscardAlpha": true
+        }
+    }
+}

+ 18 - 0
AutomatedTesting/Config/AtomImageBuilder/Test_sRGB_to_sRGB.preset

@@ -0,0 +1,18 @@
+{
+    "Type": "JsonSerialization",
+    "Version": 1,
+    "ClassName": "MultiplatformPresetSettings",
+    "ClassData": {
+        "DefaultPreset": {
+            "UUID": "{9FBA54D5-EF6F-4728-AF92-B0176B8308C5}",
+            "Name": "Test_sRGB_to_sRGB",
+            "SourceColor": "sRGB",
+            "DestColor": "sRGB",
+            "FileMasks": [
+                "_srgb-to-srgb"
+            ],
+            "PixelFormat": "R8G8B8X8",
+            "DiscardAlpha": true
+        }
+    }
+}

+ 11 - 0
AutomatedTesting/Config/shader_global_build_options.json

@@ -0,0 +1,11 @@
+{
+    "Type": "JsonSerialization",
+    "Version": 1,
+    "ClassName": "GlobalBuildOptions",
+    "ClassData": {
+        "ShaderCompilerArguments" : {
+            "DefaultMatrixOrder" : "Row",
+            "AzslcAdditionalFreeArguments" : "--strip-unused-srgs"
+        }
+    }
+}

+ 2 - 0
AutomatedTesting/Gem/Code/CMakeLists.txt

@@ -25,6 +25,7 @@ ly_add_target(
     BUILD_DEPENDENCIES
         PRIVATE
             AZ::AzCore
+            Gem::Atom_AtomBridge.Static
 )
 
 ################################################################################
@@ -37,6 +38,7 @@ ly_add_project_dependencies(
         AutomatedTesting.GameLauncher
     DEPENDENCIES_FILES
         runtime_dependencies.cmake
+        ${pal_dir}/runtime_dependencies.cmake
 )
 
 if(PAL_TRAIT_BUILD_HOST_TOOLS)

+ 0 - 1
Gems/RenderToTexture/Code/Platform/Android/platform_android.cmake → AutomatedTesting/Gem/Code/Platform/Android/runtime_dependencies.cmake

@@ -8,4 +8,3 @@
 # remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 #
-

+ 1 - 1
Gems/RenderToTexture/Code/Platform/Windows/platform_windows.cmake → AutomatedTesting/Gem/Code/Platform/Android/tool_dependencies.cmake

@@ -7,4 +7,4 @@
 # or, if provided, by the license below or the license accompanying this file. Do not
 # remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#
+#

+ 1 - 1
Gems/RenderToTexture/Code/Platform/Linux/platform_linux.cmake → AutomatedTesting/Gem/Code/Platform/Linux/runtime_dependencies.cmake

@@ -7,4 +7,4 @@
 # or, if provided, by the license below or the license accompanying this file. Do not
 # remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#
+#

+ 0 - 2
Gems/GameLift/CMakeLists.txt → AutomatedTesting/Gem/Code/Platform/Mac/runtime_dependencies.cmake

@@ -8,5 +8,3 @@
 # remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 #
-
-add_subdirectory(Code)

+ 4 - 2
Code/Tools/AssetProcessor/Platform/Linux/PAL_linux.cmake → AutomatedTesting/Gem/Code/Platform/Windows/runtime_dependencies.cmake

@@ -9,5 +9,7 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 #
 
-set (PAL_TRAIT_BUILD_ASSETPROCESSOR_APPLICATION_TYPE APPLICATION)
-
+set(GEM_DEPENDENCIES
+    Gem::Atom_RHI_Vulkan.Private
+    Gem::Atom_RHI_DX12.Private
+)

+ 5 - 0
AutomatedTesting/Gem/Code/Platform/Windows/tool_dependencies.cmake

@@ -11,4 +11,9 @@
 
 set(GEM_DEPENDENCIES
     Gem::QtForPython.Editor
+    Gem::Atom_RHI_Vulkan.Private
+    Gem::Atom_RHI_Vulkan.Builders
+    Gem::Atom_RHI_DX12.Private
+    Gem::Atom_RHI_DX12.Builders
+    Gem::Atom_RHI_Metal.Builders
 )

+ 10 - 0
AutomatedTesting/Gem/Code/Platform/iOS/runtime_dependencies.cmake

@@ -0,0 +1,10 @@
+#
+# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+# its licensors.
+#
+# For complete copyright and license terms please see the LICENSE at the root of this
+# distribution (the "License"). All use of this software is governed by the License,
+# or, if provided, by the license below or the license accompanying this file. Do not
+# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#

+ 10 - 0
AutomatedTesting/Gem/Code/Platform/iOS/tool_dependencies.cmake

@@ -0,0 +1,10 @@
+#
+# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+# its licensors.
+#
+# For complete copyright and license terms please see the LICENSE at the root of this
+# distribution (the "License"). All use of this software is governed by the License,
+# or, if provided, by the license below or the license accompanying this file. Do not
+# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#

+ 12 - 1
AutomatedTesting/Gem/Code/runtime_dependencies.cmake

@@ -21,7 +21,6 @@ set(GEM_DEPENDENCIES
     Gem::Gestures
     Gem::CertificateManager
     Gem::DebugDraw
-    Gem::GameLift
     Gem::AudioSystem
     Gem::InAppPurchases
     Gem::AutomatedTesting
@@ -43,4 +42,16 @@ set(GEM_DEPENDENCIES
     Gem::SurfaceData
     Gem::GradientSignal
     Gem::Vegetation
+
+    Gem::Atom_RHI.Private
+    Gem::Atom_RPI.Private
+    Gem::Atom_Feature_Common
+    Gem::Atom_Bootstrap
+    Gem::Atom_Component_DebugCamera
+    Gem::AtomImGuiTools
+    Gem::AtomLyIntegration_CommonFeatures
+    Gem::EMotionFX_Atom
+    Gem::ImguiAtom
+    Gem::Atom_AtomBridge
+    Gem::AtomFont
 )

+ 18 - 2
AutomatedTesting/Gem/Code/tool_dependencies.cmake

@@ -21,7 +21,6 @@ set(GEM_DEPENDENCIES
     Gem::Gestures
     Gem::CertificateManager
     Gem::DebugDraw.Editor
-    Gem::GameLift
     Gem::SceneProcessing.Editor
     Gem::GraphCanvas.Editor
     Gem::InAppPurchases
@@ -30,7 +29,6 @@ set(GEM_DEPENDENCIES
     Gem::PythonAssetBuilder.Editor
     Gem::Metastream
     Gem::AudioSystem.Editor
-    Gem::ImageProcessing.Editor
     Gem::Camera.Editor
     Gem::EMotionFX.Editor
     Gem::PhysX.Editor
@@ -52,4 +50,22 @@ set(GEM_DEPENDENCIES
     Gem::Vegetation.Editor
     Gem::GraphModel.Editor
     Gem::LandscapeCanvas.Editor
+    Gem::Atom_RHI.Private
+    Gem::EMotionFX.Editor
+    Gem::Atom_RPI.Builders
+    Gem::Atom_RPI.Editor
+    Gem::Atom_Feature_Common.Builders
+    Gem::Atom_Feature_Common.Editor
+    Gem::ImGui.Editor
+    Gem::Atom_Bootstrap
+    Gem::Atom_Asset_Shader.Builders
+    Gem::Atom_Component_DebugCamera
+    Gem::AtomImGuiTools
+    Gem::AtomLyIntegration_CommonFeatures.Editor
+    Gem::EMotionFX_Atom.Editor
+    Gem::ImageProcessingAtom.Editor
+    Gem::Atom_AtomBridge.Editor
+    Gem::ImguiAtom
+    Gem::AtomFont
+    Gem::AtomToolsFramework.Editor
 )

+ 69 - 66
AutomatedTesting/Gem/PythonTests/CMakeLists.txt

@@ -18,36 +18,37 @@ ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${P
 add_subdirectory(assetpipeline)
 
 ## Physics ##
-if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
-    ly_add_pytest(
-        NAME AutomatedTesting::PhysicsTests
-        TEST_SUITE sandbox
-        TEST_SERIAL
-        PATH ${CMAKE_CURRENT_LIST_DIR}/physics/TestSuite_Active.py
-        TIMEOUT 3600
-        RUNTIME_DEPENDENCIES
-            Legacy::Editor
-            Legacy::CryRenderNULL
-            AZ::AssetProcessor
-            AutomatedTesting.Assets
-        COMPONENT
-            Physics
-    )
-    ly_add_pytest(
-        NAME AutomatedTesting::PhysicsTests_Sandbox
-        TEST_SUITE sandbox
-        TEST_SERIAL
-        PATH ${CMAKE_CURRENT_LIST_DIR}/physics/TestSuite_Sandbox.py
-        TIMEOUT 3600
-        RUNTIME_DEPENDENCIES
-            Legacy::Editor
-            Legacy::CryRenderNULL
-            AZ::AssetProcessor
-            AutomatedTesting.Assets
-        COMPONENT
-            Physics
-    )
-endif()
+# DISABLED - see LYN-2536
+#if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
+#    ly_add_pytest(
+#        NAME AutomatedTesting::PhysicsTests
+#        TEST_SUITE main
+#        TEST_SERIAL
+#        PATH ${CMAKE_CURRENT_LIST_DIR}/physics/TestSuite_Active.py
+#        TIMEOUT 3600
+#        RUNTIME_DEPENDENCIES
+#            Legacy::Editor
+#            Legacy::CryRenderNULL
+#            AZ::AssetProcessor
+#            AutomatedTesting.Assets
+#        COMPONENT
+#            Physics
+#    )
+#    ly_add_pytest(
+#        NAME AutomatedTesting::PhysicsTests_Sandbox
+#        TEST_SUITE sandbox
+#        TEST_SERIAL
+#        PATH ${CMAKE_CURRENT_LIST_DIR}/physics/TestSuite_Sandbox.py
+#        TIMEOUT 3600
+#        RUNTIME_DEPENDENCIES
+#            Legacy::Editor
+#            Legacy::CryRenderNULL
+#            AZ::AssetProcessor
+#            AutomatedTesting.Assets
+#        COMPONENT
+#            Physics
+#    )
+#endif()
 
 ## ScriptCanvas ##
 if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
@@ -80,22 +81,23 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
 endif()
 
 ## White Box ##
-if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
-    ly_add_pytest(
-        NAME AutomatedTesting::WhiteBoxTests
-        TEST_SUITE main
-        TEST_SERIAL
-        PATH ${CMAKE_CURRENT_LIST_DIR}/WhiteBox/TestSuite_Active.py
-        TIMEOUT 3600
-        RUNTIME_DEPENDENCIES
-            Legacy::Editor
-            Legacy::CryRenderNULL
-            AZ::AssetProcessor
-            AutomatedTesting.Assets
-        COMPONENT
-            WhiteBox
-    )
-endif()
+# DISABLED - See LYN-2663
+#if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
+#    ly_add_pytest(
+#        NAME AutomatedTesting::WhiteBoxTests
+#        TEST_SUITE main
+#        TEST_SERIAL
+#        PATH ${CMAKE_CURRENT_LIST_DIR}/WhiteBox/TestSuite_Active.py
+#        TIMEOUT 3600
+#        RUNTIME_DEPENDENCIES
+#            Legacy::Editor
+#            Legacy::CryRenderNULL
+#            AZ::AssetProcessor
+#            AutomatedTesting.Assets
+#        COMPONENT
+#            WhiteBox
+#    )
+#endif()
 
 ## NvCloth ##
 # [TODO LYN-1928] Enable when AutomatedTesting runs with Atom
@@ -157,51 +159,51 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
 
 ## DynVeg ##
     ly_add_pytest(
-        NAME DynamicVegetationTests_Main_NoGPU
+        NAME DynamicVegetationTests_Main_GPU
+        TEST_REQUIRES gpu
         TEST_SERIAL
         TEST_SUITE main
         PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/dyn_veg
-        PYTEST_MARKS "not REQUIRES_gpu"
+        PYTEST_MARKS "not SUITE_sandbox and not SUITE_periodic and not SUITE_benchmark"
         TIMEOUT 36000
         RUNTIME_DEPENDENCIES
             AZ::AssetProcessor
             Legacy::Editor
             AutomatedTesting.GameLauncher
             AutomatedTesting.Assets
-            Legacy::CryRenderNULL
         COMPONENT
             LargeWorlds
     )
 
     ly_add_pytest(
-        NAME DynamicVegetationTests_Sandbox_NoGPU
+        NAME DynamicVegetationTests_Sandbox_GPU
+        TEST_REQUIRES gpu
         TEST_SERIAL
         TEST_SUITE sandbox
         PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/dyn_veg
-        PYTEST_MARKS "not REQUIRES_gpu"
+        PYTEST_MARKS "SUITE_sandbox"
         TIMEOUT 36000
         RUNTIME_DEPENDENCIES
             AZ::AssetProcessor
             Legacy::Editor
             AutomatedTesting.GameLauncher
             AutomatedTesting.Assets
-            Legacy::CryRenderNULL
         COMPONENT
             LargeWorlds
     )
 
     ly_add_pytest(
-        NAME DynamicVegetationTests_Periodic_NoGPU
+        NAME DynamicVegetationTests_Periodic_GPU
+        TEST_REQUIRES gpu
         TEST_SERIAL
         TEST_SUITE periodic
         PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/dyn_veg
-        PYTEST_MARKS "not REQUIRES_gpu"
+        PYTEST_MARKS "SUITE_periodic"
         TIMEOUT 3600
         RUNTIME_DEPENDENCIES
             AZ::AssetProcessor
             Legacy::Editor
             AutomatedTesting.Assets
-            Legacy::CryRenderNULL
         COMPONENT
             LargeWorlds
     )
@@ -209,38 +211,40 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
 ## LandscapeCanvas ##
     ly_add_pytest(
         NAME LandscapeCanvasTests_Main
+        TEST_REQUIRES gpu
         TEST_SERIAL
         TEST_SUITE main
         PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/landscape_canvas
+        PYTEST_MARKS "not SUITE_sandbox and not SUITE_periodic and not SUITE_benchmark"
         TIMEOUT 3600
         RUNTIME_DEPENDENCIES
            AZ::AssetProcessor
            Legacy::Editor
            AutomatedTesting.Assets
-           Legacy::CryRenderNULL
         COMPONENT
             LargeWorlds
     )
 
-## GradientSignal ##
-
     ly_add_pytest(
-        NAME GradientSignalTests_Main
+        NAME LandscapeCanvasTests_Periodic
+        TEST_REQUIRES gpu
         TEST_SERIAL
-        TEST_SUITE main
-        PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/gradient_signal
+        TEST_SUITE periodic
+        PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/landscape_canvas
+        PYTEST_MARKS "SUITE_periodic"
         TIMEOUT 3600
         RUNTIME_DEPENDENCIES
-            AZ::AssetProcessor
-            Legacy::Editor
-            AutomatedTesting.Assets
-            Legacy::CryRenderNULL
+           AZ::AssetProcessor
+           Legacy::Editor
+           AutomatedTesting.Assets
         COMPONENT
             LargeWorlds
     )
 
+## GradientSignal ##
     ly_add_pytest(
         NAME GradientSignalTests_Periodic
+        TEST_REQUIRES gpu
         TEST_SERIAL
         TEST_SUITE periodic
         PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/gradient_signal
@@ -249,7 +253,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
             AZ::AssetProcessor
             Legacy::Editor
             AutomatedTesting.Assets
-            Legacy::CryRenderNULL
         COMPONENT
             LargeWorlds
     )

+ 4 - 8
AutomatedTesting/Gem/PythonTests/EditorPythonBindings/ComponentAssetCommands_test.py

@@ -35,14 +35,10 @@ class TestGradientRequiresShape(object):
             "New entity with no parent created: SUCCESS",
             "Mesh component added to entity: SUCCESS",
             "Entity has a Mesh component: SUCCESS",
-            "GetSetCompare Test MeshComponentRenderNode|Mesh asset: SUCCESS",
-            "GetSetCompare Clear MeshComponentRenderNode|Mesh asset: SUCCESS",
-            "PTE Test MeshComponentRenderNode|Mesh asset: SUCCESS",
-            "PTE Clear MeshComponentRenderNode|Mesh asset: SUCCESS",
-            "GetSetCompare Test MeshComponentRenderNode|Material override: SUCCESS",
-            "GetSetCompare Clear MeshComponentRenderNode|Material override: SUCCESS",
-            "PTE Test MeshComponentRenderNode|Material override: SUCCESS",
-            "PTE Clear MeshComponentRenderNode|Material override: SUCCESS",
+            "GetSetCompare Test Controller|Configuration|Mesh Asset: SUCCESS",
+            "GetSetCompare Clear Controller|Configuration|Mesh Asset: SUCCESS",
+            "PTE Test Controller|Configuration|Mesh Asset: SUCCESS",
+            "PTE Clear Controller|Configuration|Mesh Asset: SUCCESS",
             ]
         
         test_case_file = os.path.join(os.path.dirname(__file__), 'ComponentAssetCommands_test_case.py')

+ 3 - 8
AutomatedTesting/Gem/PythonTests/EditorPythonBindings/ComponentAssetCommands_test_case.py

@@ -129,13 +129,8 @@ if(pteObj.IsSuccess()):
     pte = pteObj.GetValue()
 
 # Tests for the Asset<> case
-cubeId = asset.AssetCatalogRequestBus(bus.Broadcast, 'GetAssetIdByPath', 'objects/default/primitive_cube.cgf', math.Uuid(), False)
-GetSetCompareTest(component, "MeshComponentRenderNode|Mesh asset", cubeId)
-PteTest(pte, "MeshComponentRenderNode|Mesh asset", cubeId)
-
-# Tests for the SimpleAssetReference case
-materialId = asset.AssetCatalogRequestBus(bus.Broadcast, 'GetAssetIdByPath', 'engineassets/texturemsg/defaultsolids.mtl', math.Uuid(), False)
-GetSetCompareTest(component, "MeshComponentRenderNode|Material override", materialId)
-PteTest(pte, "MeshComponentRenderNode|Material override", materialId)
+testAssetId = asset.AssetCatalogRequestBus(bus.Broadcast, 'GetAssetIdByPath', 'assets/objects/foliage/cedar.azmodel', math.Uuid(), False)
+GetSetCompareTest(component, "Controller|Configuration|Mesh Asset", testAssetId)
+PteTest(pte, "Controller|Configuration|Mesh Asset", testAssetId)
 
 editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'ExitNoPrompt')

+ 33 - 17
AutomatedTesting/Gem/PythonTests/EditorPythonBindings/ComponentUpdateListProperty_test.py

@@ -9,27 +9,38 @@ remove or modify any license notices. This file is distributed on an "AS IS" BAS
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 """
 
-#
-# This is a pytest module to test the in-Editor Python API from PythonEditorFuncs
-#
+import os
 import pytest
-pytest.importorskip('ly_test_tools')
+import logging
 
-import sys
-import os
-sys.path.append(os.path.dirname(__file__))
-from hydra_utils import launch_test_case
+# Bail on the test if ly_test_tools doesn't exist.
+pytest.importorskip("ly_test_tools")
+import ly_test_tools.environment.file_system as file_system
+import automatedtesting_shared.hydra_test_utils as hydra
+
+logger = logging.getLogger(__name__)
+test_directory = os.path.join(os.path.dirname(__file__), "EditorScripts")
 
 
 @pytest.mark.SUITE_sandbox
[email protected]('launcher_platform', ['windows_editor'])
[email protected]('project', ['AutomatedTesting'])
[email protected]('level', ['Simple'])
-class TestComponentAssetAutomation(object):
[email protected]("project", ["AutomatedTesting"])
[email protected]("level", ["tmp_level"])
[email protected]("automatic_process_killer")
[email protected]("launcher_platform", ['windows_editor'])
+class TestComponentAssetListAutomation(object):
+    @pytest.fixture(autouse=True)
+    def setup_teardown(self, request, workspace, project, level):
+        # Cleanup our temp level
+        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+
+        def teardown():
+            # Cleanup our temp level
+            file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+
+        request.addfinalizer(teardown)
 
-    def test_ComponentAsset(self, request, editor, level, launcher_platform):
+    def test_ComponentAssetList(self, request, editor, level, launcher_platform):
 
-        unexpected_lines=[]
         expected_lines = [
             'Set EditorDescriptorListComponent Embedded Assets as List',
             'Set EditorDescriptorListComponent Embedded Assets 0 Descriptor Mesh Asset ID',
@@ -37,7 +48,12 @@ class TestComponentAssetAutomation(object):
             'Set EditorDescriptorListComponent Embedded Assets 2 Descriptor Mesh Asset ID',
             'Set EditorDescriptorListComponent Embedded Assets 3 Descriptor Mesh Asset ID'
             ]
-        
-        test_case_file = os.path.join(os.path.dirname(__file__), 'ComponentUpdateListProperty_test_case.py')
-        launch_test_case(editor, test_case_file, expected_lines, unexpected_lines)
 
+        hydra.launch_and_validate_results(
+            request,
+            test_directory,
+            editor,
+            "ComponentUpdateListProperty_test_case.py",
+            expected_lines=expected_lines,
+            cfg_args=[level]
+        )

+ 0 - 78
AutomatedTesting/Gem/PythonTests/EditorPythonBindings/ComponentUpdateListProperty_test_case.py

@@ -1,78 +0,0 @@
-"""
-All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
-its licensors.
-
-For complete copyright and license terms please see the LICENSE at the root of this
-distribution (the "License"). All use of this software is governed by the License,
-or, if provided, by the license below or the license accompanying this file. Do not
-remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-"""
-
-import azlmbr.object as object
-import azlmbr.legacy.general as general
-import azlmbr.editor as editor
-import azlmbr.bus as bus
-import azlmbr.entity as entity
-import azlmbr.math as math
-import azlmbr.asset as asset
-
-
-def add_component_with_uuid(entityId, typeId):
-    componentOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentsOfType', entityId, [typeId])
-    if (componentOutcome.IsSuccess()):
-        return componentOutcome.GetValue()[0]
-
-
-def set_component_property(component, path, value):
-    outcome = editor.EditorComponentAPIBus(bus.Broadcast, 'SetComponentProperty', component, path, value)
-    return outcome.IsSuccess()
-
-
-def get_component_property(component, path):
-    outcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentProperty', component, path)
-    if (outcome.IsSuccess()):
-        return outcome.GetValue()
-    return None
-
-
-try:
-    # Open a level
-    print ('Test started')
-    general.open_level_no_prompt('auto_test')
-
-    newEntityId = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', entity.EntityId())
-
-    editorDescriptorListComponentId = math.Uuid_CreateString('{3AF9BE58-6D2D-44FB-AB4D-CA1182F6C78F}', 0)
-    descListComponent = add_component_with_uuid(newEntityId, editorDescriptorListComponentId)
-    print ('descListComponent added')
-
-    primitiveCubeId = asset.AssetCatalogRequestBus(bus.Broadcast, 'GetAssetIdByPath', 'objects/default/primitive_cube.cgf', math.Uuid(), False)
-    primitiveSphereId = asset.AssetCatalogRequestBus(bus.Broadcast, 'GetAssetIdByPath', 'objects/default/primitive_sphere.cgf', math.Uuid(), False)
-    primitiveCapsuleId = asset.AssetCatalogRequestBus(bus.Broadcast, 'GetAssetIdByPath', 'objects/default/primitive_capsule.cgf', math.Uuid(), False)
-    primitivePlaneId = asset.AssetCatalogRequestBus(bus.Broadcast, 'GetAssetIdByPath', 'objects/default/primitive_plane.cgf', math.Uuid(), False)
-    print ('fetched asset ids')
-
-    # expand the list of veg descriptors to 4 elements
-    descList = get_component_property(descListComponent, 'Configuration|Embedded Assets')
-    print('Got the veg descriptor list')
-    descElem = descList[0]
-    descList.append(descElem)
-    descList.append(descElem)
-    descList.append(descElem)
-
-    set_component_property(descListComponent, 'Configuration|Embedded Assets', descList)
-    print('Set EditorDescriptorListComponent Embedded Assets as List')
-    set_component_property(descListComponent, 'Configuration|Embedded Assets|[0]|Instance|Mesh Asset', primitiveCubeId)
-    print('Set EditorDescriptorListComponent Embedded Assets 0 Descriptor Mesh Asset ID')
-    set_component_property(descListComponent, 'Configuration|Embedded Assets|[1]|Instance|Mesh Asset', primitiveSphereId)
-    print('Set EditorDescriptorListComponent Embedded Assets 1 Descriptor Mesh Asset ID')
-    set_component_property(descListComponent, 'Configuration|Embedded Assets|[2]|Instance|Mesh Asset', primitiveCapsuleId)
-    print('Set EditorDescriptorListComponent Embedded Assets 2 Descriptor Mesh Asset ID')
-    set_component_property(descListComponent, 'Configuration|Embedded Assets|[3]|Instance|Mesh Asset', primitivePlaneId)
-    print('Set EditorDescriptorListComponent Embedded Assets 3 Descriptor Mesh Asset ID')
-except:
-    print ('Test failed.')
-finally:
-    print ('Test done.')
-    general.exit_no_prompt()

+ 87 - 0
AutomatedTesting/Gem/PythonTests/EditorPythonBindings/EditorScripts/ComponentUpdateListProperty_test_case.py

@@ -0,0 +1,87 @@
+"""
+All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+its licensors.
+
+For complete copyright and license terms please see the LICENSE at the root of this
+distribution (the "License"). All use of this software is governed by the License,
+or, if provided, by the license below or the license accompanying this file. Do not
+remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+"""
+
+
+import os
+import sys
+
+import azlmbr.asset as asset
+import azlmbr.bus as bus
+import azlmbr.editor as editor
+import azlmbr.entity as entity
+import azlmbr.math as math
+import azlmbr.paths
+
+sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
+from automatedtesting_shared.editor_test_helper import EditorTestHelper
+
+
+def add_component_with_uuid(entityId, typeId):
+    componentOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentsOfType', entityId, [typeId])
+    if (componentOutcome.IsSuccess()):
+        return componentOutcome.GetValue()[0]
+
+
+def set_component_property(component, path, value):
+    outcome = editor.EditorComponentAPIBus(bus.Broadcast, 'SetComponentProperty', component, path, value)
+    return outcome.IsSuccess()
+
+
+def get_component_property(component, path):
+    outcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentProperty', component, path)
+    if (outcome.IsSuccess()):
+        return outcome.GetValue()
+    return None
+
+class TestComponentUpdateListProperty(EditorTestHelper):
+    def __init__(self):
+        EditorTestHelper.__init__(self, log_prefix="ComponentUpdateListProperty", args=["level"])
+
+    def run_test(self):
+        """
+        Test configuring an asset descriptor list.
+        """
+
+        # Create a new level
+        self.test_success = self.create_level(
+            self.args["level"],
+        )
+
+        newEntityId = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', entity.EntityId())
+
+        editorDescriptorListComponentId = math.Uuid_CreateString('{3AF9BE58-6D2D-44FB-AB4D-CA1182F6C78F}', 0)
+        descListComponent = add_component_with_uuid(newEntityId, editorDescriptorListComponentId)
+
+        primitiveCubeId = asset.AssetCatalogRequestBus(bus.Broadcast, 'GetAssetIdByPath', 'objects/default/primitive_cube.cgf', math.Uuid(), False)
+        primitiveSphereId = asset.AssetCatalogRequestBus(bus.Broadcast, 'GetAssetIdByPath', 'objects/default/primitive_sphere.cgf', math.Uuid(), False)
+        primitiveCapsuleId = asset.AssetCatalogRequestBus(bus.Broadcast, 'GetAssetIdByPath', 'objects/default/primitive_capsule.cgf', math.Uuid(), False)
+        primitivePlaneId = asset.AssetCatalogRequestBus(bus.Broadcast, 'GetAssetIdByPath', 'objects/default/primitive_plane.cgf', math.Uuid(), False)
+
+        # expand the list of veg descriptors to 4 elements
+        descList = get_component_property(descListComponent, 'Configuration|Embedded Assets')
+        descElem = descList[0]
+        descList.append(descElem)
+        descList.append(descElem)
+        descList.append(descElem)
+
+        self.test_success = set_component_property(descListComponent, 'Configuration|Embedded Assets', descList) and self.test_success
+        print('Set EditorDescriptorListComponent Embedded Assets as List')
+        self.test_success = set_component_property(descListComponent, 'Configuration|Embedded Assets|[0]|Instance|Mesh Asset', primitiveCubeId) and self.test_success
+        print('Set EditorDescriptorListComponent Embedded Assets 0 Descriptor Mesh Asset ID')
+        self.test_success = set_component_property(descListComponent, 'Configuration|Embedded Assets|[1]|Instance|Mesh Asset', primitiveSphereId) and self.test_success
+        print('Set EditorDescriptorListComponent Embedded Assets 1 Descriptor Mesh Asset ID')
+        self.test_success = set_component_property(descListComponent, 'Configuration|Embedded Assets|[2]|Instance|Mesh Asset', primitiveCapsuleId) and self.test_success
+        print('Set EditorDescriptorListComponent Embedded Assets 2 Descriptor Mesh Asset ID')
+        self.test_success = set_component_property(descListComponent, 'Configuration|Embedded Assets|[3]|Instance|Mesh Asset', primitivePlaneId) and self.test_success
+        print('Set EditorDescriptorListComponent Embedded Assets 3 Descriptor Mesh Asset ID')
+
+test = TestComponentUpdateListProperty()
+test.run()

+ 0 - 0
Tests/networking/__init__.py → AutomatedTesting/Gem/PythonTests/EditorPythonBindings/EditorScripts/__init__.py


+ 4 - 4
AutomatedTesting/Gem/PythonTests/EditorPythonBindings/ViewPaneCommands_test.py

@@ -36,10 +36,10 @@ class TestViewPaneAutomation(object):
             "get_viewport_expansion_policy works",
             "set_viewport_expansion_policy works",
             "get_view_pane_layout works",
-            "set_view_pane_layout works",
-            "get_viewport_count works",
-            "get_active_viewport works",
-            "set_active_viewport works"
+            "set_view_pane_layout works"
+#            "get_viewport_count works",
+#            "get_active_viewport works",
+#            "set_active_viewport works"
             ]
         
         test_case_file = os.path.join(os.path.dirname(__file__), 'ViewPaneCommands_test_case.py')

+ 18 - 17
AutomatedTesting/Gem/PythonTests/EditorPythonBindings/ViewPaneCommands_test_case.py

@@ -73,31 +73,32 @@ if (set_and_validate_viewport_size(150, 300)):
 
 # Set different view pane layouts and verify it works
 success = True
-general.set_view_pane_layout(0)
+#general.set_view_pane_layout(0)
 general.idle_wait(0.5)
+
 success = success and (general.get_view_pane_layout() == 0)
 success = success and (general.get_viewport_count() == 1)
-general.set_view_pane_layout(1)
-general.idle_wait(0.5)
-success = success and (general.get_view_pane_layout() == 1)
-success = success and (general.get_viewport_count() == 2)
+# general.set_view_pane_layout(1)
+# general.idle_wait(0.5)
+# success = success and (general.get_view_pane_layout() == 1)
+# success = success and (general.get_viewport_count() == 2)
 if success:
     print("get_view_pane_layout works")
     print("set_view_pane_layout works")
     print("get_viewport_count works")
 
-success = True
-general.set_active_viewport(0)
-general.idle_wait(0.5)
-success = success and (general.get_active_viewport() == 0)
-general.set_active_viewport(1)
-general.idle_wait(0.5)
-success = success and (general.get_active_viewport() == 1)
-if success:
-    print("get_active_viewport works")
-    print("set_active_viewport works")
-
-general.set_view_pane_layout(0)
+#success = True
+#general.set_active_viewport(0)
+#general.idle_wait(0.5)
+#success = success and (general.get_active_viewport() == 0)
+#general.set_active_viewport(1)
+#general.idle_wait(0.5)
+#success = success and (general.get_active_viewport() == 1)
+#if success:
+#    print("get_active_viewport works")
+#    print("set_active_viewport works")
+
+#general.set_view_pane_layout(0)
 general.idle_wait(0.5)
 
 editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'ExitNoPrompt')

+ 2 - 2
AutomatedTesting/Gem/PythonTests/WhiteBox/FileManagement.py

@@ -264,7 +264,7 @@ class FileManagement:
                 """
                 root_path = parent_path
                 if root_path is not None:
-                    root_path = os.path.join(workspace.paths.dev(), root_path)
+                    root_path = os.path.join(workspace.paths.engine_root(), root_path)
                 else:
                     # Default to project folder (AutomatedTesting)
                     root_path = workspace.paths.project()
@@ -325,7 +325,7 @@ class FileManagement:
                 """
                 root_path = parent_path
                 if root_path is not None:
-                    root_path = os.path.join(workspace.paths.dev(), root_path)
+                    root_path = os.path.join(workspace.paths.engine_root(), root_path)
                 else:
                     # Default to project folder (AutomatedTesting)
                     root_path = workspace.paths.project()

+ 1 - 1
AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/ap_all_platforms_setup_fixture.py

@@ -23,7 +23,7 @@ from . import ap_setup_fixture as ap_setup_fixture
 @pytest.fixture
 def ap_all_platforms_setup_fixture(request, workspace, ap_setup_fixture) -> Dict[str, str]:
 
-    dev_dir = os.path.join(workspace.paths.dev())
+    dev_dir = os.path.join(workspace.paths.engine_root())
     cache_dir = workspace.paths.cache()
 
     # add some useful locations

+ 3 - 3
AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/ap_setup_fixture.py

@@ -42,8 +42,8 @@ def ap_setup_fixture(request, workspace) -> Dict:
         "ap_batch_log_file": workspace.paths.ap_batch_log(),
         # Path to AP_GUI.log
         "ap_logFile": workspace.paths.ap_gui_log(),
-        # Path to the dev directory
-        "dev_dir": workspace.paths.dev(),
+        # Path to the engine root directory
+        "engine_dir": workspace.paths.engine_root(),
         # Path to the current project directory
         "project_dir": workspace.paths.project(),
         # Path to AP Batch file
@@ -56,7 +56,7 @@ def ap_setup_fixture(request, workspace) -> Dict:
 
     # Changing modtime of UserSettings.xml so it is always processed by AssetProcessorBatch
     # to prevent unexpected processing
-    user_settings_file = os.path.join(workspace.paths.dev(), "UserSettings.xml")
+    user_settings_file = os.path.join(workspace.paths.project(), "user", "UserSettings.xml")
     if os.path.exists(user_settings_file):
         timestamp = time.time()
         os.utime(user_settings_file, (timestamp, timestamp))

+ 2 - 2
AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/bundler_batch_setup_fixture.py

@@ -66,7 +66,7 @@ def bundler_batch_setup_fixture(request, workspace, asset_processor, timeout) ->
             self.bundler_batch = os.path.join(self.bin_dir, "AssetBundlerBatch")
             self.test_dir = tempDir
             self.asset_alias = workspace.paths.platform_cache()
-            self.tools_dir = os.path.join(workspace.paths.dev(), "Tools")
+            self.tools_dir = os.path.join(workspace.paths.engine_root(), "Tools")
             self.seed_list_file_name = "testSeedListFile.seed"
             self.seed_list_file = os.path.join(self.test_dir, self.seed_list_file_name)
             self.asset_info_file_name = "assetFileInfo.assetlist"
@@ -297,7 +297,7 @@ def bundler_batch_setup_fixture(request, workspace, asset_processor, timeout) ->
             Note: the platform's are bit flags, so their values are powers of 2: 1 << position_in_file
             """
             platform_declaration_file = os.path.join(
-                workspace.paths.dev(),
+                workspace.paths.engine_root(),
                 "Code",
                 "Framework",
                 "AzFramework",

+ 2 - 2
AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/clear_moveoutput_fixture.py

@@ -20,9 +20,9 @@ import ly_test_tools.lumberyard.pipeline_utils as pipeline_utils
 
 @pytest.fixture
 def clear_moveoutput_fixture(request, workspace) -> None:
-    pipeline_utils.delete_MoveOutput_folders([workspace.paths.dev(), workspace.paths.project()])
+    pipeline_utils.delete_MoveOutput_folders([workspace.paths.engine_root(), workspace.paths.project()])
 
     def teardown():
-        pipeline_utils.delete_MoveOutput_folders([workspace.paths.dev(), workspace.paths.project()])
+        pipeline_utils.delete_MoveOutput_folders([workspace.paths.engine_root(), workspace.paths.project()])
 
     request.addfinalizer(teardown)

+ 4 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt

@@ -26,6 +26,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
         NAME AssetPipelineTests.Batch_2_Main
         TEST_SUITE main
         PATH  ${CMAKE_CURRENT_LIST_DIR}/asset_processor_batch_tests_2.py
+        PYTEST_MARKS "not SUITE_sandbox" # don't run sandbox tests in this file
         EXCLUDE_TEST_RUN_TARGET_FROM_IDE
         RUNTIME_DEPENDENCIES
             AZ::AssetProcessorBatch
@@ -36,6 +37,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
         NAME AssetPipelineTests.Batch_2_Sandbox
         TEST_SUITE sandbox
         PATH  ${CMAKE_CURRENT_LIST_DIR}/asset_processor_batch_tests_2.py
+        PYTEST_MARKS "SUITE_sandbox" # run only sandbox tests in this file
         EXCLUDE_TEST_RUN_TARGET_FROM_IDE
         RUNTIME_DEPENDENCIES
             AZ::AssetProcessorBatch
@@ -75,6 +77,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
         NAME AssetPipelineTests.Gui_2_Main
         TEST_SUITE main
         PATH  ${CMAKE_CURRENT_LIST_DIR}/asset_processor_gui_tests_2.py
+        PYTEST_MARKS "not SUITE_sandbox" # don't run sandbox tests in this file
         EXCLUDE_TEST_RUN_TARGET_FROM_IDE
         RUNTIME_DEPENDENCIES
             AZ::AssetProcessorBatch
@@ -85,6 +88,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
         NAME AssetPipelineTests.Gui_2_Sandbox
         TEST_SUITE sandbox
         PATH  ${CMAKE_CURRENT_LIST_DIR}/asset_processor_gui_tests_2.py
+        PYTEST_MARKS "SUITE_sandbox" # run only sandbox tests in this file
         EXCLUDE_TEST_RUN_TARGET_FROM_IDE
         RUNTIME_DEPENDENCIES
             AZ::AssetProcessorBatch

+ 4 - 4
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_bundler_batch_tests.py

@@ -302,7 +302,7 @@ class TestsAssetBundlerBatch_WindowsAndMac(object):
         that generating debug information does not affect asset list creation
         """
         helper = bundler_batch_helper
-        seed_list = os.path.join(workspace.paths.dev(), "Engine", "SeedAssetList.seed")  # Engine seed list
+        seed_list = os.path.join(workspace.paths.engine_root(), "Engine", "SeedAssetList.seed")  # Engine seed list
         asset = r"levels\testdependencieslevel\level.pak"
 
         # Create Asset list
@@ -377,7 +377,7 @@ class TestsAssetBundlerBatch_WindowsAndMac(object):
         subcommands.
         """
         helper = bundler_batch_helper
-        seed_list = os.path.join(workspace.paths.dev(), "Engine", "SeedAssetList.seed")  # Engine seed list
+        seed_list = os.path.join(workspace.paths.engine_root(), "Engine", "SeedAssetList.seed")  # Engine seed list
         asset = r"levels\testdependencieslevel\level.pak"
 
         # Useful bundle locations / names (2 for comparing contents)
@@ -465,7 +465,7 @@ class TestsAssetBundlerBatch_WindowsAndMac(object):
             "Please rerun with commandline option: '--bundle_platforms=pc,osx_gl'"
         # fmt:on
 
-        seed_list = os.path.join(workspace.paths.dev(), "Engine", "SeedAssetList.seed")  # Engine seed list
+        seed_list = os.path.join(workspace.paths.engine_root(), "Engine", "SeedAssetList.seed")  # Engine seed list
 
         # Useful bundle / asset list locations
         bundle_dir = os.path.dirname(helper["bundle_file"])
@@ -1109,7 +1109,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.dev(), workspace.project, "Bundles")
+        bundles_folder = os.path.join(workspace.paths.engine_root(), workspace.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,

+ 1 - 1
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_batch_dependency_tests2.py

@@ -69,7 +69,7 @@ class TestsAssetProcessorBatch_DependenycyTests(object):
         asset_processor.add_scan_folder("Gems/LyShineExamples/Assets")
         gem_asset_path = "Gems/CertificateManager/Assets"
         asset_processor.add_scan_folder(gem_asset_path)
-        engine_schema_path = os.path.join(workspace.paths.dev(), "Engine", "Schema")
+        engine_schema_path = os.path.join(workspace.paths.engine_root(), "Engine", "Schema")
         gem_schema_path = os.path.join(asset_processor.temp_asset_root(), gem_asset_path, "Schema")
 
         # EXPECT Assets process successfully

+ 154 - 155
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/assets_with_nested_preload_dependency/TestA.slice

@@ -1,223 +1,222 @@
 <ObjectStream version="3">
-	<Class name="AZ::Entity" version="2" type="{75651658-8663-478D-9090-2432DFCAFA44}">
-		<Class name="EntityId" field="Id" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
-			<Class name="AZ::u64" field="id" value="269594828358" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+	<Class name="AZ::Entity" type="{75651658-8663-478D-9090-2432DFCAFA44}" version="2">
+		<Class field="Id" name="EntityId" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}" version="1">
+			<Class field="id" name="AZ::u64" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}" value="269594828358" />
 		</Class>
-		<Class name="AZStd::string" field="Name" value="Slice" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
-		<Class name="AZStd::vector" field="Components" type="{13D58FF9-1088-5C69-9A1F-C2A144B57B78}">
-			<Class name="SliceComponent" field="element" version="3" type="{AFD304E4-1773-47C8-855A-8B622398934F}">
-				<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
-					<Class name="AZ::u64" field="Id" value="13642727600084297375" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+		<Class field="Name" name="AZStd::string" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}" value="Slice" />
+		<Class field="Components" name="AZStd::vector" type="{13D58FF9-1088-5C69-9A1F-C2A144B57B78}">
+			<Class field="element" name="SliceComponent" type="{AFD304E4-1773-47C8-855A-8B622398934F}" version="3">
+				<Class field="BaseClass1" name="AZ::Component" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+					<Class field="Id" name="AZ::u64" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}" value="13642727600084297375" />
 				</Class>
-				<Class name="AZStd::vector" field="Entities" type="{21786AF0-2606-5B9A-86EB-0892E2820E6C}">
-					<Class name="AZ::Entity" field="element" version="2" type="{75651658-8663-478D-9090-2432DFCAFA44}">
-						<Class name="EntityId" field="Id" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
-							<Class name="AZ::u64" field="id" value="278184762950" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+				<Class field="Entities" name="AZStd::vector" type="{21786AF0-2606-5B9A-86EB-0892E2820E6C}">
+					<Class field="element" name="AZ::Entity" type="{75651658-8663-478D-9090-2432DFCAFA44}" version="2">
+						<Class field="Id" name="EntityId" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}" version="1">
+							<Class field="id" name="AZ::u64" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}" value="278184762950" />
 						</Class>
-						<Class name="AZStd::string" field="Name" value="TestE" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
-						<Class name="AZStd::vector" field="Components" type="{13D58FF9-1088-5C69-9A1F-C2A144B57B78}">
-							<Class name="EditorOnlyEntityComponent" field="element" type="{22A16F1D-6D49-422D-AAE9-91AE45B5D3E7}">
-								<Class name="EditorComponentBase" field="BaseClass1" version="1" type="{D5346BD4-7F20-444E-B370-327ACD03D4A0}">
-									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
-										<Class name="AZ::u64" field="Id" value="16738199190794244171" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+						<Class field="Name" name="AZStd::string" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}" value="TestE" />
+						<Class field="Components" name="AZStd::vector" type="{13D58FF9-1088-5C69-9A1F-C2A144B57B78}">
+							<Class field="element" name="EditorOnlyEntityComponent" type="{22A16F1D-6D49-422D-AAE9-91AE45B5D3E7}">
+								<Class field="BaseClass1" name="EditorComponentBase" type="{D5346BD4-7F20-444E-B370-327ACD03D4A0}" version="1">
+									<Class field="BaseClass1" name="AZ::Component" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class field="Id" name="AZ::u64" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}" value="16738199190794244171" />
 									</Class>
 								</Class>
-								<Class name="bool" field="IsEditorOnly" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+								<Class field="IsEditorOnly" name="bool" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}" value="false" />
 							</Class>
-							<Class name="TransformComponent" field="element" version="9" type="{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0}">
-								<Class name="EditorComponentBase" field="BaseClass1" version="1" type="{D5346BD4-7F20-444E-B370-327ACD03D4A0}">
-									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
-										<Class name="AZ::u64" field="Id" value="16210900323787785224" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
-									</Class>
-								</Class>
-								<Class name="EntityId" field="Parent Entity" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
-									<Class name="AZ::u64" field="id" value="4294967295" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
-								</Class>
-								<Class name="EditorTransform" field="Transform Data" version="2" type="{B02B7063-D238-4F40-A724-405F7A6D68CB}">
-									<Class name="Vector3" field="Translate" value="0.0000000 0.0000000 0.0000000" type="{8379EB7D-01FA-4538-B64B-A6543B4BE73D}"/>
-									<Class name="Vector3" field="Rotate" value="0.0000000 0.0000000 0.0000000" type="{8379EB7D-01FA-4538-B64B-A6543B4BE73D}"/>
-									<Class name="Vector3" field="Scale" value="1.0000000 1.0000000 1.0000000" type="{8379EB7D-01FA-4538-B64B-A6543B4BE73D}"/>
-									<Class name="bool" field="Locked" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
-								</Class>
-								<Class name="Transform" field="Cached World Transform" value="1.0000000 0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 0.0000000" type="{5D9958E9-9F1E-4985-B532-FFFDE75FEDFD}"/>
-								<Class name="EntityId" field="Cached World Transform Parent" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
-									<Class name="AZ::u64" field="id" value="4294967295" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
-								</Class>
-								<Class name="unsigned int" field="Parent Activation Transform Mode" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-								<Class name="bool" field="IsStatic" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
-								<Class name="bool" field="Sync Enabled" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
-								<Class name="unsigned int" field="InterpolatePosition" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-								<Class name="unsigned int" field="InterpolateRotation" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
+							<Class field="element" name="TransformComponent" type="{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0}" version="9">
+								<Class field="BaseClass1" name="EditorComponentBase" type="{D5346BD4-7F20-444E-B370-327ACD03D4A0}" version="1">
+									<Class field="BaseClass1" name="AZ::Component" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class field="Id" name="AZ::u64" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}" value="16210900323787785224" />
+									</Class>
+								</Class>
+								<Class field="Parent Entity" name="EntityId" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}" version="1">
+									<Class field="id" name="AZ::u64" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}" value="4294967295" />
+								</Class>
+								<Class field="Transform Data" name="EditorTransform" type="{B02B7063-D238-4F40-A724-405F7A6D68CB}" version="2">
+									<Class field="Translate" name="Vector3" type="{8379EB7D-01FA-4538-B64B-A6543B4BE73D}" value="0.0000000 0.0000000 0.0000000" />
+									<Class field="Rotate" name="Vector3" type="{8379EB7D-01FA-4538-B64B-A6543B4BE73D}" value="0.0000000 0.0000000 0.0000000" />
+									<Class field="Scale" name="Vector3" type="{8379EB7D-01FA-4538-B64B-A6543B4BE73D}" value="1.0000000 1.0000000 1.0000000" />
+									<Class field="Locked" name="bool" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}" value="false" />
+								</Class>
+								<Class field="Cached World Transform" name="Transform" type="{5D9958E9-9F1E-4985-B532-FFFDE75FEDFD}" value="1.0000000 0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 0.0000000" />
+								<Class field="Cached World Transform Parent" name="EntityId" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}" version="1">
+									<Class field="id" name="AZ::u64" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}" value="4294967295" />
+								</Class>
+								<Class field="Parent Activation Transform Mode" name="unsigned int" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}" value="0" />
+								<Class field="IsStatic" name="bool" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}" value="false" />
+								<Class field="Sync Enabled" name="bool" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}" value="false" />
+								<Class field="InterpolatePosition" name="unsigned int" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}" value="0" />
+								<Class field="InterpolateRotation" name="unsigned int" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}" value="0" />
 							</Class>
-							<Class name="EditorInspectorComponent" field="element" version="2" type="{47DE3DDA-50C5-4F50-B1DB-BA4AE66AB056}">
-								<Class name="EditorComponentBase" field="BaseClass1" version="1" type="{D5346BD4-7F20-444E-B370-327ACD03D4A0}">
-									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
-										<Class name="AZ::u64" field="Id" value="7735546012552452863" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+							<Class field="element" name="EditorInspectorComponent" type="{47DE3DDA-50C5-4F50-B1DB-BA4AE66AB056}" version="2">
+								<Class field="BaseClass1" name="EditorComponentBase" type="{D5346BD4-7F20-444E-B370-327ACD03D4A0}" version="1">
+									<Class field="BaseClass1" name="AZ::Component" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class field="Id" name="AZ::u64" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}" value="7735546012552452863" />
 									</Class>
 								</Class>
-								<Class name="AZStd::vector" field="ComponentOrderEntryArray" type="{B6EFED5B-19B4-5084-9D92-42DECCE83872}">
-									<Class name="ComponentOrderEntry" field="element" version="1" type="{335C5861-5197-4DD5-A766-EF2B551B0D9D}">
-										<Class name="AZ::u64" field="ComponentId" value="16210900323787785224" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
-										<Class name="AZ::u64" field="SortIndex" value="0" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+								<Class field="ComponentOrderEntryArray" name="AZStd::vector" type="{B6EFED5B-19B4-5084-9D92-42DECCE83872}">
+									<Class field="element" name="ComponentOrderEntry" type="{335C5861-5197-4DD5-A766-EF2B551B0D9D}" version="1">
+										<Class field="ComponentId" name="AZ::u64" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}" value="16210900323787785224" />
+										<Class field="SortIndex" name="AZ::u64" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}" value="0" />
 									</Class>
-									<Class name="ComponentOrderEntry" field="element" version="1" type="{335C5861-5197-4DD5-A766-EF2B551B0D9D}">
-										<Class name="AZ::u64" field="ComponentId" value="4070968465717414181" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
-										<Class name="AZ::u64" field="SortIndex" value="1" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+									<Class field="element" name="ComponentOrderEntry" type="{335C5861-5197-4DD5-A766-EF2B551B0D9D}" version="1">
+										<Class field="ComponentId" name="AZ::u64" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}" value="4070968465717414181" />
+										<Class field="SortIndex" name="AZ::u64" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}" value="1" />
 									</Class>
-									<Class name="ComponentOrderEntry" field="element" version="1" type="{335C5861-5197-4DD5-A766-EF2B551B0D9D}">
-										<Class name="AZ::u64" field="ComponentId" value="8906495340202656540" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
-										<Class name="AZ::u64" field="SortIndex" value="2" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+									<Class field="element" name="ComponentOrderEntry" type="{335C5861-5197-4DD5-A766-EF2B551B0D9D}" version="1">
+										<Class field="ComponentId" name="AZ::u64" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}" value="8906495340202656540" />
+										<Class field="SortIndex" name="AZ::u64" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}" value="2" />
 									</Class>
 								</Class>
 							</Class>
-							<Class name="EditorEntitySortComponent" field="element" version="2" type="{6EA1E03D-68B2-466D-97F7-83998C8C27F0}">
-								<Class name="EditorComponentBase" field="BaseClass1" version="1" type="{D5346BD4-7F20-444E-B370-327ACD03D4A0}">
-									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
-										<Class name="AZ::u64" field="Id" value="9760814841523354339" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+							<Class field="element" name="EditorEntitySortComponent" type="{6EA1E03D-68B2-466D-97F7-83998C8C27F0}" version="2">
+								<Class field="BaseClass1" name="EditorComponentBase" type="{D5346BD4-7F20-444E-B370-327ACD03D4A0}" version="1">
+									<Class field="BaseClass1" name="AZ::Component" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class field="Id" name="AZ::u64" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}" value="9760814841523354339" />
 									</Class>
 								</Class>
-								<Class name="AZStd::vector" field="ChildEntityOrderEntryArray" type="{BE163120-C1ED-5F69-A650-DC2528A8FF94}"/>
+								<Class field="ChildEntityOrderEntryArray" name="AZStd::vector" type="{BE163120-C1ED-5F69-A650-DC2528A8FF94}" />
 							</Class>
-							<Class name="SelectionComponent" field="element" type="{73B724FC-43D1-4C75-ACF5-79AA8A3BF89D}">
-								<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
-									<Class name="AZ::u64" field="Id" value="8339376805608654145" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+							<Class field="element" name="SelectionComponent" type="{73B724FC-43D1-4C75-ACF5-79AA8A3BF89D}">
+								<Class field="BaseClass1" name="AZ::Component" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+									<Class field="Id" name="AZ::u64" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}" value="8339376805608654145" />
 								</Class>
 							</Class>
-							<Class name="EditorSpawnerComponent" field="element" version="1" type="{77CDE991-EC1A-B7C1-B112-7456ABAC81A1}">
-								<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
-									<Class name="AZ::u64" field="Id" value="4070968465717414181" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+							<Class field="element" name="EditorSpawnerComponent" type="{77CDE991-EC1A-B7C1-B112-7456ABAC81A1}" version="1">
+								<Class field="BaseClass1" name="AZ::Component" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+									<Class field="Id" name="AZ::u64" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}" value="4070968465717414181" />
 								</Class>
-								<Class name="Asset" field="Slice" value="id={F6621671-E624-53B1-BEB8-EB028B777B4C}:2,type={78802ABF-9595-463A-8D2B-D022F906F9B1},hint={assets_with_nested_preload_dependency/testd.dynamicslice}" version="1" type="{77A19D40-8731-4D3C-9041-1B43047366A4}"/>
-								<Class name="bool" field="SpawnOnActivate" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
-								<Class name="bool" field="DestroyOnDeactivate" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+								<Class field="Slice" name="Asset" type="{77A19D40-8731-4D3C-9041-1B43047366A4}" value="id={F6621671-E624-53B1-BEB8-EB028B777B4C}:2,type={78802ABF-9595-463A-8D2B-D022F906F9B1},hint={assets_with_nested_preload_dependency/testd.dynamicslice}" version="1" />
+								<Class field="SpawnOnActivate" name="bool" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}" value="false" />
+								<Class field="DestroyOnDeactivate" name="bool" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}" value="false" />
 							</Class>
-							<Class name="EditorVisibilityComponent" field="element" type="{88E08E78-5C2F-4943-9F73-C115E6FFAB43}">
-								<Class name="EditorComponentBase" field="BaseClass1" version="1" type="{D5346BD4-7F20-444E-B370-327ACD03D4A0}">
-									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
-										<Class name="AZ::u64" field="Id" value="10678724437556014335" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+							<Class field="element" name="EditorVisibilityComponent" type="{88E08E78-5C2F-4943-9F73-C115E6FFAB43}">
+								<Class field="BaseClass1" name="EditorComponentBase" type="{D5346BD4-7F20-444E-B370-327ACD03D4A0}" version="1">
+									<Class field="BaseClass1" name="AZ::Component" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class field="Id" name="AZ::u64" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}" value="10678724437556014335" />
 									</Class>
 								</Class>
-								<Class name="bool" field="VisibilityFlag" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+								<Class field="VisibilityFlag" name="bool" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}" value="true" />
 							</Class>
-							<Class name="EditorActorComponent" field="element" version="4" type="{A863EE1B-8CFD-4EDD-BA0D-1CEC2879AD44}">
-								<Class name="EditorComponentBase" field="BaseClass1" version="1" type="{D5346BD4-7F20-444E-B370-327ACD03D4A0}">
-									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
-										<Class name="AZ::u64" field="Id" value="8906495340202656540" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+							<Class field="element" name="EditorActorComponent" type="{A863EE1B-8CFD-4EDD-BA0D-1CEC2879AD44}" version="4">
+								<Class field="BaseClass1" name="EditorComponentBase" type="{D5346BD4-7F20-444E-B370-327ACD03D4A0}" version="1">
+									<Class field="BaseClass1" name="AZ::Component" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class field="Id" name="AZ::u64" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}" value="8906495340202656540" />
 									</Class>
 								</Class>
-								<Class name="Asset" field="ActorAsset" value="id={58BE9DA5-1F17-53B9-8CEE-EEB10E63454D}:914f19b7,type={F67CC648-EA51-464C-9F5D-4A9CE41A7F86},hint={objects/characters/jack/jack.actor}" version="1" type="{77A19D40-8731-4D3C-9041-1B43047366A4}"/>
-								<Class name="AZStd::vector" field="MaterialPerLOD" type="{BB800BD1-3E2D-5089-8423-F400597960FF}">
-									<Class name="AzFramework::SimpleAssetReference&lt;LmbrCentral::MaterialAsset&gt;" field="element" version="1" type="{B7B8ECC7-FF89-4A76-A50E-4C6CA2B6E6B4}">
-										<Class name="SimpleAssetReferenceBase" field="BaseClass1" version="1" type="{E16CA6C5-5C78-4AD9-8E9B-F8C1FB4D1DB8}">
-											<Class name="AZStd::string" field="AssetPath" value="objects/characters/jack/jack.mtl" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+								<Class field="ActorAsset" name="Asset" type="{77A19D40-8731-4D3C-9041-1B43047366A4}" value="id={58BE9DA5-1F17-53B9-8CEE-EEB10E63454D}:914f19b7,type={F67CC648-EA51-464C-9F5D-4A9CE41A7F86},hint={objects/characters/jack/jack.actor}" version="1" />
+								<Class field="MaterialPerLOD" name="AZStd::vector" type="{BB800BD1-3E2D-5089-8423-F400597960FF}">
+									<Class field="element" name="AzFramework::SimpleAssetReference&lt;LmbrCentral::MaterialAsset&gt;" type="{B7B8ECC7-FF89-4A76-A50E-4C6CA2B6E6B4}" version="1">
+										<Class field="BaseClass1" name="SimpleAssetReferenceBase" type="{E16CA6C5-5C78-4AD9-8E9B-F8C1FB4D1DB8}" version="1">
+											<Class field="AssetPath" name="AZStd::string" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}" value="objects/characters/jack/jack.mtl" />
 										</Class>
 									</Class>
-									<Class name="AzFramework::SimpleAssetReference&lt;LmbrCentral::MaterialAsset&gt;" field="element" version="1" type="{B7B8ECC7-FF89-4A76-A50E-4C6CA2B6E6B4}">
-										<Class name="SimpleAssetReferenceBase" field="BaseClass1" version="1" type="{E16CA6C5-5C78-4AD9-8E9B-F8C1FB4D1DB8}">
-											<Class name="AZStd::string" field="AssetPath" value="objects/characters/jack/jack.mtl" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+									<Class field="element" name="AzFramework::SimpleAssetReference&lt;LmbrCentral::MaterialAsset&gt;" type="{B7B8ECC7-FF89-4A76-A50E-4C6CA2B6E6B4}" version="1">
+										<Class field="BaseClass1" name="SimpleAssetReferenceBase" type="{E16CA6C5-5C78-4AD9-8E9B-F8C1FB4D1DB8}" version="1">
+											<Class field="AssetPath" name="AZStd::string" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}" value="objects/characters/jack/jack.mtl" />
 										</Class>
 									</Class>
-									<Class name="AzFramework::SimpleAssetReference&lt;LmbrCentral::MaterialAsset&gt;" field="element" version="1" type="{B7B8ECC7-FF89-4A76-A50E-4C6CA2B6E6B4}">
-										<Class name="SimpleAssetReferenceBase" field="BaseClass1" version="1" type="{E16CA6C5-5C78-4AD9-8E9B-F8C1FB4D1DB8}">
-											<Class name="AZStd::string" field="AssetPath" value="objects/characters/jack/jack.mtl" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+									<Class field="element" name="AzFramework::SimpleAssetReference&lt;LmbrCentral::MaterialAsset&gt;" type="{B7B8ECC7-FF89-4A76-A50E-4C6CA2B6E6B4}" version="1">
+										<Class field="BaseClass1" name="SimpleAssetReferenceBase" type="{E16CA6C5-5C78-4AD9-8E9B-F8C1FB4D1DB8}" version="1">
+											<Class field="AssetPath" name="AZStd::string" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}" value="objects/characters/jack/jack.mtl" />
 										</Class>
 									</Class>
-									<Class name="AzFramework::SimpleAssetReference&lt;LmbrCentral::MaterialAsset&gt;" field="element" version="1" type="{B7B8ECC7-FF89-4A76-A50E-4C6CA2B6E6B4}">
-										<Class name="SimpleAssetReferenceBase" field="BaseClass1" version="1" type="{E16CA6C5-5C78-4AD9-8E9B-F8C1FB4D1DB8}">
-											<Class name="AZStd::string" field="AssetPath" value="objects/characters/jack/jack.mtl" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+									<Class field="element" name="AzFramework::SimpleAssetReference&lt;LmbrCentral::MaterialAsset&gt;" type="{B7B8ECC7-FF89-4A76-A50E-4C6CA2B6E6B4}" version="1">
+										<Class field="BaseClass1" name="SimpleAssetReferenceBase" type="{E16CA6C5-5C78-4AD9-8E9B-F8C1FB4D1DB8}" version="1">
+											<Class field="AssetPath" name="AZStd::string" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}" value="objects/characters/jack/jack.mtl" />
 										</Class>
 									</Class>
 								</Class>
-								<Class name="AzFramework::SimpleAssetReference&lt;LmbrCentral::MaterialAsset&gt;" field="MaterialPerActor" version="1" type="{B7B8ECC7-FF89-4A76-A50E-4C6CA2B6E6B4}">
-									<Class name="SimpleAssetReferenceBase" field="BaseClass1" version="1" type="{E16CA6C5-5C78-4AD9-8E9B-F8C1FB4D1DB8}">
-										<Class name="AZStd::string" field="AssetPath" value="objects/characters/jack/jack.mtl" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+								<Class field="MaterialPerActor" name="AzFramework::SimpleAssetReference&lt;LmbrCentral::MaterialAsset&gt;" type="{B7B8ECC7-FF89-4A76-A50E-4C6CA2B6E6B4}" version="1">
+									<Class field="BaseClass1" name="SimpleAssetReferenceBase" type="{E16CA6C5-5C78-4AD9-8E9B-F8C1FB4D1DB8}" version="1">
+										<Class field="AssetPath" name="AZStd::string" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}" value="objects/characters/jack/jack.mtl" />
 									</Class>
 								</Class>
-								<Class name="unsigned int" field="AttachmentType" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-								<Class name="EntityId" field="AttachmentTarget" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
-									<Class name="AZ::u64" field="id" value="4294967295" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+								<Class field="AttachmentType" name="unsigned int" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}" value="0" />
+								<Class field="AttachmentTarget" name="EntityId" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}" version="1">
+									<Class field="id" name="AZ::u64" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}" value="4294967295" />
 								</Class>
-								<Class name="bool" field="RenderSkeleton" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
-								<Class name="bool" field="RenderCharacter" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
-								<Class name="bool" field="RenderBounds" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
-								<Class name="unsigned int" field="SkinningMethod" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-								<Class name="bool" field="UpdateJointTransformsWhenOutOfView" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
-								<Class name="unsigned int" field="LodLevel" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
+								<Class field="RenderSkeleton" name="bool" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}" value="false" />
+								<Class field="RenderCharacter" name="bool" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}" value="true" />
+								<Class field="RenderBounds" name="bool" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}" value="false" />
+								<Class field="SkinningMethod" name="unsigned int" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}" value="0" />
+								<Class field="UpdateJointTransformsWhenOutOfView" name="bool" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}" value="false" />
+								<Class field="LodLevel" name="unsigned int" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}" value="0" />
 							</Class>
-							<Class name="EditorLockComponent" field="element" type="{C3A169C9-7EFB-4D6C-8710-3591680D0936}">
-								<Class name="EditorComponentBase" field="BaseClass1" version="1" type="{D5346BD4-7F20-444E-B370-327ACD03D4A0}">
-									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
-										<Class name="AZ::u64" field="Id" value="2755228366872136502" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+							<Class field="element" name="EditorLockComponent" type="{C3A169C9-7EFB-4D6C-8710-3591680D0936}">
+								<Class field="BaseClass1" name="EditorComponentBase" type="{D5346BD4-7F20-444E-B370-327ACD03D4A0}" version="1">
+									<Class field="BaseClass1" name="AZ::Component" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class field="Id" name="AZ::u64" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}" value="2755228366872136502" />
 									</Class>
 								</Class>
-								<Class name="bool" field="Locked" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+								<Class field="Locked" name="bool" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}" value="false" />
 							</Class>
-							<Class name="EditorPendingCompositionComponent" field="element" type="{D40FCB35-153D-45B3-AF6D-7BA576D8AFBB}">
-								<Class name="EditorComponentBase" field="BaseClass1" version="1" type="{D5346BD4-7F20-444E-B370-327ACD03D4A0}">
-									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
-										<Class name="AZ::u64" field="Id" value="2364131805451940550" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+							<Class field="element" name="EditorPendingCompositionComponent" type="{D40FCB35-153D-45B3-AF6D-7BA576D8AFBB}">
+								<Class field="BaseClass1" name="EditorComponentBase" type="{D5346BD4-7F20-444E-B370-327ACD03D4A0}" version="1">
+									<Class field="BaseClass1" name="AZ::Component" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class field="Id" name="AZ::u64" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}" value="2364131805451940550" />
 									</Class>
 								</Class>
-								<Class name="AZStd::vector" field="PendingComponents" type="{13D58FF9-1088-5C69-9A1F-C2A144B57B78}"/>
+								<Class field="PendingComponents" name="AZStd::vector" type="{13D58FF9-1088-5C69-9A1F-C2A144B57B78}" />
 							</Class>
-							<Class name="EditorEntityIconComponent" field="element" type="{E15D42C2-912D-466F-9547-E7E948CE2D7D}">
-								<Class name="EditorComponentBase" field="BaseClass1" version="1" type="{D5346BD4-7F20-444E-B370-327ACD03D4A0}">
-									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
-										<Class name="AZ::u64" field="Id" value="15019118415351685531" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+							<Class field="element" name="EditorEntityIconComponent" type="{E15D42C2-912D-466F-9547-E7E948CE2D7D}">
+								<Class field="BaseClass1" name="EditorComponentBase" type="{D5346BD4-7F20-444E-B370-327ACD03D4A0}" version="1">
+									<Class field="BaseClass1" name="AZ::Component" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class field="Id" name="AZ::u64" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}" value="15019118415351685531" />
 									</Class>
 								</Class>
-								<Class name="AssetId" field="EntityIconAssetId" version="1" type="{652ED536-3402-439B-AEBE-4A5DBC554085}">
-									<Class name="AZ::Uuid" field="guid" value="{00000000-0000-0000-0000-000000000000}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
-									<Class name="unsigned int" field="subId" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
+								<Class field="EntityIconAssetId" name="AssetId" type="{652ED536-3402-439B-AEBE-4A5DBC554085}" version="1">
+									<Class field="guid" name="AZ::Uuid" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}" value="{00000000-0000-0000-0000-000000000000}" />
+									<Class field="subId" name="unsigned int" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}" value="0" />
 								</Class>
 							</Class>
-							<Class name="EditorDisabledCompositionComponent" field="element" type="{E77AE6AC-897D-4035-8353-637449B6DCFB}">
-								<Class name="EditorComponentBase" field="BaseClass1" version="1" type="{D5346BD4-7F20-444E-B370-327ACD03D4A0}">
-									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
-										<Class name="AZ::u64" field="Id" value="12728572968760191789" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+							<Class field="element" name="EditorDisabledCompositionComponent" type="{E77AE6AC-897D-4035-8353-637449B6DCFB}">
+								<Class field="BaseClass1" name="EditorComponentBase" type="{D5346BD4-7F20-444E-B370-327ACD03D4A0}" version="1">
+									<Class field="BaseClass1" name="AZ::Component" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class field="Id" name="AZ::u64" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}" value="12728572968760191789" />
 									</Class>
 								</Class>
-								<Class name="AZStd::vector" field="DisabledComponents" type="{13D58FF9-1088-5C69-9A1F-C2A144B57B78}"/>
+								<Class field="DisabledComponents" name="AZStd::vector" type="{13D58FF9-1088-5C69-9A1F-C2A144B57B78}" />
 							</Class>
 						</Class>
-						<Class name="bool" field="IsDependencyReady" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
-						<Class name="bool" field="IsRuntimeActive" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+						<Class field="IsDependencyReady" name="bool" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}" value="true" />
+						<Class field="IsRuntimeActive" name="bool" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}" value="true" />
 					</Class>
 				</Class>
-				<Class name="AZStd::list" field="Prefabs" type="{DAD45EB6-5853-5645-B762-3A37F8775E12}"/>
-				<Class name="bool" field="IsDynamic" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
-				<Class name="AZ::Entity" field="MetadataEntity" version="2" type="{75651658-8663-478D-9090-2432DFCAFA44}">
-					<Class name="EntityId" field="Id" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
-						<Class name="AZ::u64" field="id" value="273889795654" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+				<Class field="Prefabs" name="AZStd::list" type="{DAD45EB6-5853-5645-B762-3A37F8775E12}" />
+				<Class field="IsDynamic" name="bool" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}" value="true" />
+				<Class field="MetadataEntity" name="AZ::Entity" type="{75651658-8663-478D-9090-2432DFCAFA44}" version="2">
+					<Class field="Id" name="EntityId" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}" version="1">
+						<Class field="id" name="AZ::u64" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}" value="273889795654" />
 					</Class>
-					<Class name="AZStd::string" field="Name" value="No Asset Association" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
-					<Class name="AZStd::vector" field="Components" type="{13D58FF9-1088-5C69-9A1F-C2A144B57B78}">
-						<Class name="SliceMetadataInfoComponent" field="element" version="2" type="{25EE4D75-8A17-4449-81F4-E561005BAABD}">
-							<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
-								<Class name="AZ::u64" field="Id" value="1605466577178627956" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+					<Class field="Name" name="AZStd::string" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}" value="No Asset Association" />
+					<Class field="Components" name="AZStd::vector" type="{13D58FF9-1088-5C69-9A1F-C2A144B57B78}">
+						<Class field="element" name="SliceMetadataInfoComponent" type="{25EE4D75-8A17-4449-81F4-E561005BAABD}" version="2">
+							<Class field="BaseClass1" name="AZ::Component" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+								<Class field="Id" name="AZ::u64" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}" value="1605466577178627956" />
 							</Class>
-							<Class name="AZStd::set" field="AssociatedIds" type="{78E024C3-0143-53FC-B393-0675227839AF}">
-								<Class name="EntityId" field="element" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
-									<Class name="AZ::u64" field="id" value="278184762950" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+							<Class field="AssociatedIds" name="AZStd::set" type="{78E024C3-0143-53FC-B393-0675227839AF}">
+								<Class field="element" name="EntityId" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}" version="1">
+									<Class field="id" name="AZ::u64" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}" value="278184762950" />
 								</Class>
 							</Class>
-							<Class name="EntityId" field="ParentId" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
-								<Class name="AZ::u64" field="id" value="4294967295" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+							<Class field="ParentId" name="EntityId" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}" version="1">
+								<Class field="id" name="AZ::u64" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}" value="4294967295" />
 							</Class>
-							<Class name="AZStd::unordered_set" field="ChildrenIds" type="{6C8F8E52-AB4A-5C1F-8E56-9AC390290B94}"/>
-							<Class name="bool" field="PersistenceFlag" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+							<Class field="ChildrenIds" name="AZStd::unordered_set" type="{6C8F8E52-AB4A-5C1F-8E56-9AC390290B94}" />
+							<Class field="PersistenceFlag" name="bool" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}" value="false" />
 						</Class>
 					</Class>
-					<Class name="bool" field="IsDependencyReady" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
-					<Class name="bool" field="IsRuntimeActive" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+					<Class field="IsDependencyReady" name="bool" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}" value="false" />
+					<Class field="IsRuntimeActive" name="bool" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}" value="true" />
 				</Class>
-				<Class name="DataFlagsPerEntity" field="DataFlagsForNewEntities" version="1" type="{57FE7B9E-B2AF-4F6F-9F8D-87F671E91C99}">
-					<Class name="AZStd::unordered_map" field="EntityToDataFlags" type="{CAB9E1F5-761E-54B8-916E-E7FB597E5EDE}"/>
+				<Class field="DataFlagsForNewEntities" name="DataFlagsPerEntity" type="{57FE7B9E-B2AF-4F6F-9F8D-87F671E91C99}" version="1">
+					<Class field="EntityToDataFlags" name="AZStd::unordered_map" type="{CAB9E1F5-761E-54B8-916E-E7FB597E5EDE}" />
 				</Class>
 			</Class>
 		</Class>
-		<Class name="bool" field="IsDependencyReady" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
-		<Class name="bool" field="IsRuntimeActive" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+		<Class field="IsDependencyReady" name="bool" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}" value="false" />
+		<Class field="IsRuntimeActive" name="bool" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}" value="true" />
 	</Class>
-</ObjectStream>
-
+</ObjectStream>

+ 0 - 2
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/missing_dependency_tests.py

@@ -71,8 +71,6 @@ class TestsMissingDependencies_WindowsAndMac(object):
         self._asset_processor.add_source_folder_assets(f"{self._workspace.project}\\textures")
         self._asset_processor.add_source_folder_assets(f"{self._workspace.project}\\UI")
         self._asset_processor.add_source_folder_assets(f"{self._workspace.project}\\libs\\particles")
-        asset_processor.copy_assets_to_project(['Game.xml'], os.path.join(self._workspace.paths.dev(), self._workspace.project, 'Config'),
-                                               os.path.join(self._asset_processor.temp_asset_root(), self._workspace.project, 'Config'))
 
     def do_missing_dependency_test(self, source_product, expected_dependencies,
                                    dsp_param,

+ 5 - 5
AutomatedTesting/Gem/PythonTests/assetpipeline/auxiliary_content_tests/auxiliary_content_tests.py

@@ -30,7 +30,7 @@ project_list = ['AutomatedTesting']
 class TestAuxiliaryContent:
     @pytest.fixture(autouse=True)
     def setup_teardown(self, request, workspace, project):
-        path_to_dev = workspace.paths.dev()
+        path_to_dev = workspace.paths.engine_root()
         os.chdir(path_to_dev)
         auxiliaryContentDirName = str.lower(project) + f"_{ASSET_PROCESSOR_PLATFORM_MAP[workspace.asset_processor_platform]}_paks"
         self.auxiliaryContentPath = os.path.join(path_to_dev, auxiliaryContentDirName)
@@ -53,14 +53,14 @@ class TestAuxiliaryContent:
         This test ensure that Auxiliary Content contain level.pak files
         """
 
-        path_to_dev = workspace.paths.dev()
+        path_to_dev = workspace.paths.engine_root()
         bin_path = workspace.paths.build_directory()
 
         auxiliaryContentScriptPath = os.path.join(path_to_dev, 'BuildReleaseAuxiliaryContent.py')
         subprocess.check_call(['python', auxiliaryContentScriptPath,
                                "--buildFolder={0}".format(bin_path),
                                "--platforms=pc",
-                               f"--project={workspace.project}"])
+                               f"--project-path={workspace.project}"])
 
         assert os.path.exists(self.auxiliaryContentPath)
         assert not self.scanForLevelPak(self.auxiliaryContentPath) == 0
@@ -72,7 +72,7 @@ class TestAuxiliaryContent:
         This test ensure that Auxiliary Content contain no level.pak file
         """
 
-        path_to_dev = workspace.paths.dev()
+        path_to_dev = workspace.paths.engine_root()
         bin_path = workspace.paths.build_directory()
 
         auxiliaryContentScriptPath = os.path.join(path_to_dev, 'BuildReleaseAuxiliaryContent.py')
@@ -80,7 +80,7 @@ class TestAuxiliaryContent:
                                "--buildFolder={0}".format(bin_path),
                                "--platforms=pc",
                                "--skiplevelPaks",
-                               f"--project={workspace.project}"])
+                               f"--project-path={workspace.project}"])
         assert os.path.exists(self.auxiliaryContentPath)
 
         assert self.scanForLevelPak(self.auxiliaryContentPath) == 0

+ 1 - 1
AutomatedTesting/Gem/PythonTests/assetpipeline/wwise_bank_dependency_tests/bank_info_parser_tests.py

@@ -67,7 +67,7 @@ def success_case_test(test_folder, expected_dependencies_dict, bank_info, expect
 
 def get_bank_info(workspace):
     sys.path.append(
-        os.path.join(workspace.paths.dev(), 'Gems', 'AudioEngineWwise', 'Tools'))
+        os.path.join(workspace.paths.engine_root(), 'Gems', 'AudioEngineWwise', 'Tools'))
 
     from WwiseAuthoringScripts import bank_info_parser as bank_info_module
     return bank_info_module

+ 4 - 5
AutomatedTesting/Gem/PythonTests/automatedtesting_shared/editor_test_helper.py

@@ -119,7 +119,6 @@ class EditorTestHelper:
         general.set_viewport_expansion_policy("AutoExpand")
         general.set_view_pane_layout(self.viewport_layout)
         general.update_viewport()
-        general.idle_wait(1.0)
 
         self.log("test finished")
 
@@ -162,10 +161,10 @@ class EditorTestHelper:
     def create_level(
         self,
         level_name: str,
-        heightmap_resolution: int,
-        heightmap_meters_per_pixel: int,
-        terrain_texture_resolution: int,
-        use_terrain: bool,
+        heightmap_resolution: int = 1024,
+        heightmap_meters_per_pixel: int = 1,
+        terrain_texture_resolution: int = 4096,
+        use_terrain: bool = False,
         bypass_viewport_resize: bool = False,
     ) -> bool:
         self.log(f"Creating level {level_name}")

+ 11 - 0
AutomatedTesting/Gem/PythonTests/automatedtesting_shared/hydra_editor_utils.py

@@ -88,6 +88,13 @@ def add_component(componentName, entityId):
     return componentOutcome.GetValue()[0]
 
 
+def add_component_of_type(componentTypeId, entityId):
+    typeIdsList = [componentTypeId]
+    componentOutcome = editor.EditorComponentAPIBus(
+        azlmbr.bus.Broadcast, 'AddComponentsOfType', entityId, typeIdsList)
+    return componentOutcome.GetValue()[0]
+
+
 def remove_component(component_name, entity_id):
     """
     Removes the specified component from the specified entity.
@@ -213,6 +220,10 @@ class Entity:
         new_component = add_component(component, self.id)
         self.components.append(new_component)
 
+    def add_component_of_type(self, componentTypeId):
+        new_component = add_component_of_type(componentTypeId, self.id)
+        self.components.append(new_component)
+
     def remove_component(self, component):
         removed_component = remove_component(component, self.id)
         if removed_component is not None:

+ 1 - 1
AutomatedTesting/Gem/PythonTests/automatedtesting_shared/hydra_test_utils.py

@@ -32,7 +32,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=[],
+                                halt_on_unexpected=False, run_python="--runpythontest", auto_test_mode=True, null_renderer=False, cfg_args=[],
                                 timeout=300):
     """
     Runs the Editor with the specified script, and monitors for expected log lines.

+ 0 - 0
Tests/ly_shared/registry_utils.py → AutomatedTesting/Gem/PythonTests/automatedtesting_shared/registry_utils.py


+ 3 - 3
AutomatedTesting/Gem/PythonTests/editor/EditorScripts/SearchFiltering_Asset_Browser_Filtering.py → AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetBrowser_SearchFiltering.py

@@ -27,9 +27,9 @@ from automatedtesting_shared.editor_test_helper import EditorTestHelper
 import automatedtesting_shared.pyside_utils as pyside_utils
 
 
-class TestAssetBrowserSearchFiltering(EditorTestHelper):
+class AssetBrowserSearchFilteringTest(EditorTestHelper):
     def __init__(self):
-        EditorTestHelper.__init__(self, log_prefix="SearchFiltering_Asset_Browser_Filtering", args=["level"])
+        EditorTestHelper.__init__(self, log_prefix="AssetBrowser_SearchFiltering", args=["level"])
 
     @pyside_utils.wrap_async
     async def run_test(self):
@@ -161,5 +161,5 @@ class TestAssetBrowserSearchFiltering(EditorTestHelper):
         asset_browser.close()
 
 
-test = TestAssetBrowserSearchFiltering()
+test = AssetBrowserSearchFilteringTest()
 test.run()

+ 1 - 1
AutomatedTesting/Gem/PythonTests/editor/EditorScripts/TreeNavigation_Asset_Browser.py → AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetBrowser_TreeNavigation.py

@@ -27,7 +27,7 @@ import automatedtesting_shared.pyside_utils as pyside_utils
 
 class AssetBrowserTreeNavigationTest(EditorTestHelper):
     def __init__(self):
-        EditorTestHelper.__init__(self, log_prefix="TreeNavigation_Asset_Browser", args=["level"])
+        EditorTestHelper.__init__(self, log_prefix="AssetBrowser_TreeNavigation", args=["level"])
 
     def run_test(self):
         """

+ 262 - 0
AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetPicker_UI_UX.py

@@ -0,0 +1,262 @@
+"""
+All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+its licensors.
+
+For complete copyright and license terms please see the LICENSE at the root of this
+distribution (the "License"). All use of this software is governed by the License,
+or, if provided, by the license below or the license accompanying this file. Do not
+remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+"""
+
+"""
+C13751579: Asset Picker UI/UX
+"""
+
+import os
+import sys
+from PySide2 import QtWidgets, QtTest, QtCore
+from PySide2.QtCore import Qt
+
+import azlmbr.asset as asset
+import azlmbr.bus as bus
+import azlmbr.legacy.general as general
+import azlmbr.paths
+import azlmbr.math as math
+
+sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
+import automatedtesting_shared.hydra_editor_utils as hydra
+from automatedtesting_shared.editor_test_helper import EditorTestHelper
+import automatedtesting_shared.pyside_utils as pyside_utils
+
+
+class AssetPickerUIUXTest(EditorTestHelper):
+    def __init__(self):
+        EditorTestHelper.__init__(self, log_prefix="AssetPicker_UI_UX", args=["level"])
+
+    @pyside_utils.wrap_async
+    async def run_test(self):
+        """
+        Summary:
+        Verify the functionality of Asset Picker and UI/UX properties
+
+        Expected Behavior:
+        The asset picker opens and is labeled appropriately ("Pick Model Asset" in this instance).
+        The Asset Picker window can be resized and moved around the screen.
+        The file tree expands/retracts appropriately and a scroll bar is present when the menus extend 
+        beyond the length of the window.
+        The assets are limited to a valid type for the field selected (mesh assets in this instance)
+        The asset picker is closed and the selected asset is assigned to the mesh component.
+
+        Test Steps:
+        1) Open a new level
+        2) Create entity and add Mesh component
+        3) Access Entity Inspector
+        4) Click Asset Picker (Mesh Asset)
+            a) Collapse all the files initially and verify if scroll bar is not visible
+            b) Expand/Verify Top folder of file path
+            c) Expand/Verify Nested folder of file path
+            d) Verify if the ScrollBar appears after expanding folders
+            e) Collapse Nested and Top Level folders and verify if collapsed
+            f) Verify if the correct files are appearing in the Asset Picker
+            g) Move the widget and verify position
+            h) Resize the widget
+            g) Assign Mesh asset
+        5) Verify if Mesh Asset is assigned via both OK/Enter options
+
+        Note:
+        - This test file must be called from the Lumberyard Editor command terminal
+        - Any passed and failed tests are written to the Editor.log file.
+                Parsing the file or running a log_monitor are required to observe the test results.
+
+        :return: None
+        """
+
+        self.file_path = ["AutomatedTesting", "Assets", "Objects", "Foliage"]
+        self.incorrect_file_found = False
+        self.mesh_asset = "cedar.azmodel"
+        self.prefix = ""
+
+        def is_asset_assigned(component, interaction_option):
+            path = os.path.join("assets", "objects", "foliage", "cedar.azmodel")
+            expected_asset_id = asset.AssetCatalogRequestBus(bus.Broadcast, 'GetAssetIdByPath', path, math.Uuid(),
+                                                             False)
+            result = hydra.get_component_property_value(component, "Controller|Configuration|Mesh Asset")
+            expected_asset_str = expected_asset_id.invoke("ToString")
+            result_str = result.invoke("ToString")
+            print(f"Asset assigned for {interaction_option} option: {expected_asset_str == result_str}")
+            return expected_asset_str == result_str
+
+        def move_and_resize_widget(widget):
+            # Move the widget and verify position
+            initial_position = widget.pos()
+            x, y = initial_position.x() + 5, initial_position.y() + 5
+            widget.move(x, y)
+            curr_position = widget.pos()
+            move_success = curr_position.x() == x and curr_position.y() == y
+            self.test_success = move_success and self.test_success
+            self.log(f"Widget Move Test: {move_success}")
+
+            # Resize the widget and verify size
+            width, height = (
+                widget.geometry().width() + 10,
+                widget.geometry().height() + 10,
+            )
+            widget.resize(width, height)
+            resize_success = widget.geometry().width() == width and widget.geometry().height() == height
+            self.test_success = resize_success and self.test_success
+            self.log(f"Widget Resize Test: {resize_success}")
+
+        def verify_files_appeared(model, allowed_asset_extensions, parent_index=QtCore.QModelIndex()):
+            indices = [parent_index]
+            while len(indices) > 0:
+                parent_index = indices.pop(0)
+                for row in range(model.rowCount(parent_index)):
+                    cur_index = model.index(row, 0, parent_index)
+                    cur_data = cur_index.data(Qt.DisplayRole)
+                    if (
+                        "." in cur_data
+                        and (cur_data.lower().split(".")[-1] not in allowed_asset_extensions)
+                        and not cur_data[-1] == ")"
+                    ):
+                        print(f"Incorrect file found: {cur_data}")
+                        self.incorrect_file_found = True
+                        indices = list()
+                        break
+                    indices.append(cur_index)
+            self.test_success = not self.incorrect_file_found and self.test_success
+
+        def print_message_prefix(message):
+            print(f"{self.prefix}: {message}")
+
+        async def asset_picker(prefix, allowed_asset_extensions, asset, interaction_option):
+            active_modal_widget = await pyside_utils.wait_for_modal_widget()
+            if active_modal_widget and self.prefix == "":
+                self.prefix = prefix
+                dialog = active_modal_widget.findChildren(QtWidgets.QDialog, "AssetPickerDialogClass")[0]
+                print_message_prefix(f"Asset Picker title for Mesh: {dialog.windowTitle()}")
+                tree = dialog.findChildren(QtWidgets.QTreeView, "m_assetBrowserTreeViewWidget")[0]
+                scroll_area = tree.findChild(QtWidgets.QWidget, "qt_scrollarea_vcontainer")
+                scroll_bar = scroll_area.findChild(QtWidgets.QScrollBar)
+
+                # a) Collapse all the files initially and verify if scroll bar is not visible
+                tree.collapseAll()
+                await pyside_utils.wait_for_condition(lambda: not scroll_bar.isVisible(), 0.5)
+                print_message_prefix(
+                    f"Scroll Bar is not visible before expanding the tree: {not scroll_bar.isVisible()}"
+                )
+
+                # Get Model Index of the file paths
+                model_index_1 = pyside_utils.find_child_by_pattern(tree, self.file_path[0])
+                print(model_index_1.model())
+                model_index_2 = pyside_utils.find_child_by_pattern(model_index_1, self.file_path[1])
+
+                # b) Expand/Verify Top folder of file path
+                print_message_prefix(f"Top level folder initially collapsed: {not tree.isExpanded(model_index_1)}")
+                tree.expand(model_index_1)
+                print_message_prefix(f"Top level folder expanded: {tree.isExpanded(model_index_1)}")
+
+                # c) Expand/Verify Nested folder of file path
+                print_message_prefix(f"Nested folder initially collapsed: {not tree.isExpanded(model_index_2)}")
+                tree.expand(model_index_2)
+                print_message_prefix(f"Nested folder expanded: {tree.isExpanded(model_index_2)}")
+
+                # d) Verify if the ScrollBar appears after expanding folders
+                tree.expandAll()
+                await pyside_utils.wait_for_condition(lambda: scroll_bar.isVisible(), 0.5)
+                print_message_prefix(f"Scroll Bar appeared after expanding tree: {scroll_bar.isVisible()}")
+
+                # e) Collapse Nested and Top Level folders and verify if collapsed
+                tree.collapse(model_index_2)
+                print_message_prefix(f"Nested folder collapsed: {not tree.isExpanded(model_index_2)}")
+                tree.collapse(model_index_1)
+                print_message_prefix(f"Top level folder collapsed: {not tree.isExpanded(model_index_1)}")
+
+                # f) Verify if the correct files are appearing in the Asset Picker
+                verify_files_appeared(tree.model(), allowed_asset_extensions)
+                print_message_prefix(f"Expected Assets populated in the file picker: {not self.incorrect_file_found}")
+
+                # While we are here we can also check if we can resize and move the widget
+                move_and_resize_widget(active_modal_widget)
+
+                # g) Assign asset
+                tree.collapseAll()
+                await pyside_utils.wait_for_condition(
+                    lambda: len(dialog.findChildren(QtWidgets.QFrame, "m_searchWidget")) > 0, 0.5)
+                search_widget = dialog.findChildren(QtWidgets.QFrame, "m_searchWidget")[0]
+                search_line_edit = search_widget.findChildren(QtWidgets.QLineEdit, "textSearch")[0]
+                search_line_edit.setText(asset)
+                tree.expandAll()
+                asset_model_index = pyside_utils.find_child_by_pattern(tree, asset)
+                await pyside_utils.wait_for_condition(lambda: asset_model_index.isValid(), 2.0)
+                tree.expand(asset_model_index)
+                tree.setCurrentIndex(asset_model_index)
+                if interaction_option == "ok":
+                    button_box = dialog.findChild(QtWidgets.QDialogButtonBox, "m_buttonBox")
+                    ok_button = button_box.button(QtWidgets.QDialogButtonBox.Ok)
+                    await pyside_utils.click_button_async(ok_button)
+                elif interaction_option == "enter":
+                    QtTest.QTest.keyClick(tree, Qt.Key_Enter, Qt.NoModifier)
+                self.prefix = ""
+
+        # 1) Open a new level
+        self.test_success = self.create_level(
+            self.args["level"],
+            heightmap_resolution=1024,
+            heightmap_meters_per_pixel=1,
+            terrain_texture_resolution=4096,
+            use_terrain=False,
+        )
+
+        # 2) Create entity and add Mesh component
+        entity_position = math.Vector3(125.0, 136.0, 32.0)
+        entity = hydra.Entity("TestEntity")
+        entity.create_entity(entity_position, ["Mesh"])
+
+        # 3) Access Entity Inspector
+        editor_window = pyside_utils.get_editor_main_window()
+        entity_inspector = editor_window.findChild(QtWidgets.QDockWidget, "Entity Inspector")
+        component_list_widget = entity_inspector.findChild(QtWidgets.QWidget, "m_componentListContents")
+
+        # 4) Click on Asset Picker (Mesh Asset)
+        general.select_object("TestEntity")
+        general.idle_wait(0.5)
+        mesh_asset = component_list_widget.findChildren(QtWidgets.QFrame, "Mesh Asset")[0]
+        attached_button = mesh_asset.findChildren(QtWidgets.QPushButton, "attached-button")[0]
+
+        # Assign Mesh Asset via OK button
+        pyside_utils.click_button_async(attached_button)
+        await asset_picker("Mesh Asset", ["azmodel", "fbx"], "cedar (ModelAsset)", "ok")
+
+        # 5) Verify if Mesh Asset is assigned
+        try:
+            mesh_success = await pyside_utils.wait_for_condition(lambda: is_asset_assigned(entity.components[0],
+                                                                                           "ok"))
+        except pyside_utils.EventLoopTimeoutException as err:
+            print(err)
+            mesh_success = False
+        self.test_success = mesh_success and self.test_success
+
+        # Clear Mesh Asset
+        hydra.get_set_test(entity, 0, "Controller|Configuration|Mesh Asset", None)
+        general.select_object("TestEntity")
+        general.idle_wait(0.5)
+        mesh_asset = component_list_widget.findChildren(QtWidgets.QFrame, "Mesh Asset")[0]
+        attached_button = mesh_asset.findChildren(QtWidgets.QPushButton, "attached-button")[0]
+
+        # Assign Mesh Asset via Enter
+        pyside_utils.click_button_async(attached_button)
+        await asset_picker("Mesh Asset", ["azmodel", "fbx"], "cedar (ModelAsset)", "enter")
+
+        # 5) Verify if Mesh Asset is assigned
+        try:
+            mesh_success = await pyside_utils.wait_for_condition(lambda: is_asset_assigned(entity.components[0],
+                                                                                           "enter"))
+        except pyside_utils.EventLoopTimeoutException as err:
+            print(err)
+            mesh_success = False
+        self.test_success = mesh_success and self.test_success
+
+
+test = AssetPickerUIUXTest()
+test.run()

+ 3 - 5
AutomatedTesting/Gem/PythonTests/editor/EditorScripts/ComponentCRUD_Add_Delete_Components.py

@@ -72,6 +72,7 @@ class AddDeleteComponentsTest(EditorTestHelper):
             component_index = pyside_utils.find_child_by_pattern(tree, component_name)
             if component_index.isValid():
                 print(f"{component_name} found")
+            tree.expand(component_index)
             tree.setCurrentIndex(component_index)
             QtTest.QTest.keyClick(tree, Qt.Key_Enter, Qt.NoModifier)
 
@@ -93,8 +94,8 @@ class AddDeleteComponentsTest(EditorTestHelper):
             print("Entity Created")
 
         # 3) Select the newly created entity
-        general.clear_selection()
         general.select_object("Entity2")
+
         # Give the Entity Inspector time to fully create its contents
         general.idle_wait(0.5)
 
@@ -103,14 +104,11 @@ class AddDeleteComponentsTest(EditorTestHelper):
         entity_inspector = editor_window.findChild(QtWidgets.QDockWidget, "Entity Inspector")
         add_comp_btn = entity_inspector.findChild(QtWidgets.QPushButton, "m_addComponentButton")
         await add_component("Box Shape")
-    
         print(f"Box Shape Component added: {hydra.has_components(entity_id, ['Box Shape'])}")
 
         # 5) Add/verify Mesh component
         await add_component("Mesh")
-        print(
-            f"Box Shape and Mesh Components present in the entity: {hydra.has_components(entity_id, ['Box Shape', 'Mesh'])}"
-        )
+        print(f"Mesh Component added: {hydra.has_components(entity_id, ['Mesh'])}")
 
         # 6) Delete Mesh Component
         general.idle_wait(0.5)

+ 142 - 0
AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Docking_BasicDockedTools.py

@@ -0,0 +1,142 @@
+"""
+All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+its licensors.
+
+For complete copyright and license terms please see the LICENSE at the root of this
+distribution (the "License"). All use of this software is governed by the License,
+or, if provided, by the license below or the license accompanying this file. Do not
+remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+
+C6376081: Basic Function: Docked/Undocked Tools
+"""
+
+import os
+import sys
+from PySide2 import QtWidgets, QtTest, QtCore
+
+import azlmbr.legacy.general as general
+import azlmbr.bus as bus
+import azlmbr.editor as editor
+import azlmbr.entity as entity
+import azlmbr.paths
+
+sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
+from automatedtesting_shared.editor_test_helper import EditorTestHelper
+import automatedtesting_shared.pyside_utils as pyside_utils
+
+
+class TestDockingBasicDockedTools(EditorTestHelper):
+    def __init__(self):
+        EditorTestHelper.__init__(self, log_prefix="Docking_BasicDockedTools", args=["level"])
+
+    @pyside_utils.wrap_async
+    async def run_test(self):
+        """
+        Summary:
+        Test that tools still work as expected when docked together.
+
+        Expected Behavior:
+        Multiple tools can be docked together.
+        Tools function while docked together and the main editor responds appropriately.
+
+        Test Steps:
+        1) Open the tools and dock them together in a floating tabbed widget.
+        2) Perform actions in the docked tools to verify they still work as expected.
+            2.1) Select the Entity Outliner in the floating window.
+            2.2) Select an Entity in the Entity Outliner.
+            2.3) Select the Entity Inspector in the floating window.
+            2.4) Change the name of the selected Entity via the Entity Inspector.
+            2.5) Select the Console inside the floating window.
+            2.6) Send a console command.
+            2.7) Check the Editor to verify all changes were made.
+
+        :return: None
+        """
+
+        # Create a level since we are going to be dealing with an Entity.
+        self.create_level(
+            self.args["level"],
+            heightmap_resolution=1024,
+            heightmap_meters_per_pixel=1,
+            terrain_texture_resolution=4096,
+            use_terrain=False,
+        )
+
+        # Make sure the Entity Outliner, Entity Inspector and Console tools are open
+        general.open_pane("Entity Outliner (PREVIEW)")
+        general.open_pane("Entity Inspector")
+        general.open_pane("Console")
+
+        # Create an Entity to test with
+        entity_original_name = 'MyTestEntity'
+        entity_id = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', entity.EntityId())
+        editor.EditorEntityAPIBus(bus.Event, 'SetName', entity_id, entity_original_name)
+
+        editor_window = pyside_utils.get_editor_main_window()
+        entity_outliner = editor_window.findChild(QtWidgets.QDockWidget, "Entity Outliner (PREVIEW)")
+
+        # 1) Open the tools and dock them together in a floating tabbed widget.
+        # We drag/drop it over the viewport since it doesn't allow docking, so this will undock it
+        render_overlay = editor_window.findChild(QtWidgets.QWidget, "renderOverlay")
+        pyside_utils.drag_and_drop(entity_outliner, render_overlay)
+
+        # We need to grab a new reference to the Entity Outliner QDockWidget because when it gets moved
+        # to the floating window, its parent changes so the wrapped intance we had becomes invalid
+        entity_outliner = editor_window.findChild(QtWidgets.QDockWidget, "Entity Outliner (PREVIEW)")
+
+        # Dock the Entity Inspector tabbed with the floating Entity Outliner
+        entity_inspector = editor_window.findChild(QtWidgets.QDockWidget, "Entity Inspector")
+        pyside_utils.drag_and_drop(entity_inspector, entity_outliner)
+
+        # We need to grab a new reference to the Entity Inspector QDockWidget because when it gets moved
+        # to the floating window, its parent changes so the wrapped intance we had becomes invalid
+        entity_inspector = editor_window.findChild(QtWidgets.QDockWidget, "Entity Inspector")
+
+        # Dock the Console tabbed with the floating Entity Inspector
+        console = editor_window.findChild(QtWidgets.QDockWidget, "Console")
+        pyside_utils.drag_and_drop(console, entity_inspector)
+
+        # Check to ensure all the tools are parented to the same QStackedWidget
+        def check_all_panes_tabbed():
+            entity_inspector = editor_window.findChild(QtWidgets.QDockWidget, "Entity Inspector")
+            entity_outliner = editor_window.findChild(QtWidgets.QDockWidget, "Entity Outliner (PREVIEW)")
+            console = editor_window.findChild(QtWidgets.QDockWidget, "Console")
+            entity_inspector_parent = entity_inspector.parentWidget()
+            entity_outliner_parent = entity_outliner.parentWidget()
+            console_parent = console.parentWidget()
+            print(f"Entity Inspector parent = {entity_inspector_parent}, Entity Outliner parent = {entity_outliner_parent}, Console parent = {console_parent}")
+            return isinstance(entity_inspector_parent, QtWidgets.QStackedWidget) and (entity_inspector_parent == entity_outliner_parent) and (entity_outliner_parent == console_parent)
+
+        success = await pyside_utils.wait_for(check_all_panes_tabbed, timeout=3.0)
+        if success:
+            print("The tools are all docked together in a tabbed widget")
+
+        # 2.1,2) Select an Entity in the Entity Outliner.
+        entity_inspector = editor_window.findChild(QtWidgets.QDockWidget, "Entity Inspector")
+        entity_outliner = editor_window.findChild(QtWidgets.QDockWidget, "Entity Outliner (PREVIEW)")
+        console = editor_window.findChild(QtWidgets.QDockWidget, "Console")
+        object_tree = entity_outliner.findChild(QtWidgets.QTreeView, "m_objectTree")
+        test_entity_index = pyside_utils.find_child_by_pattern(object_tree, entity_original_name)
+        object_tree.clearSelection()
+        object_tree.setCurrentIndex(test_entity_index)
+        if object_tree.currentIndex():
+            print("Entity Outliner works when docked, can select an Entity")
+
+        # 2.3,4) Change the name of the selected Entity via the Entity Inspector.
+        entity_inspector_name_field = entity_inspector.findChild(QtWidgets.QLineEdit, "m_entityNameEditor")
+        expected_new_name = "DifferentName"
+        entity_inspector_name_field.setText(expected_new_name)
+        QtTest.QTest.keyClick(entity_inspector_name_field, QtCore.Qt.Key_Enter)
+        entity_new_name = editor.EditorEntityInfoRequestBus(bus.Event, "GetName", entity_id)
+        if entity_new_name == expected_new_name:
+            print(f"Entity Inspector works when docked, Entity name changed to {entity_new_name}")
+
+        # 2.5,6) Send a console command.
+        console_line_edit = console.findChild(QtWidgets.QLineEdit, "lineEdit")
+        console_line_edit.setText("Hello, world!")
+        QtTest.QTest.keyClick(console_line_edit, QtCore.Qt.Key_Enter)
+
+
+test = TestDockingBasicDockedTools()
+test.run()

+ 120 - 0
AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_EditMenuOptions.py

@@ -0,0 +1,120 @@
+"""
+All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+its licensors.
+
+For complete copyright and license terms please see the LICENSE at the root of this
+distribution (the "License"). All use of this software is governed by the License,
+or, if provided, by the license below or the license accompanying this file. Do not
+remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+"""
+
+"""
+C24064529: Base Edit Menu Options
+"""
+
+import os
+import sys
+
+import azlmbr.paths
+
+sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
+from automatedtesting_shared.editor_test_helper import EditorTestHelper
+import automatedtesting_shared.pyside_utils as pyside_utils
+
+
+class TestEditMenuOptions(EditorTestHelper):
+    def __init__(self):
+        EditorTestHelper.__init__(self, log_prefix="Menus_EditMenuOptions", args=["level"])
+
+    def run_test(self):
+        """
+        Summary:
+        Interact with Edit Menu options and verify if all the options are working.
+
+        Expected Behavior:
+        The Edit menu functions normally.
+
+        Test Steps:
+         1) Create a temp level
+         2) Interact with Edit Menu options
+
+        Note:
+        - This test file must be called from the Lumberyard Editor command terminal
+        - Any passed and failed tests are written to the Editor.log file.
+                Parsing the file or running a log_monitor are required to observe the test results.
+
+        :return: None
+        """
+        edit_menu_options = [
+            ("Undo",),
+            ("Redo",),
+            ("Duplicate",),
+            ("Delete",),
+            ("Select All",),
+            ("Invert Selection",),
+            ("Toggle Pivot Location",),
+            ("Reset Entity Transform",),
+            ("Reset Manipulator",),
+            ("Reset Transform (Local)",),
+            ("Reset Transform (World)",),
+            ("Hide Selection",),
+            ("Show All",),
+            ("Modify", "Snap", "Snap angle"),
+            ("Modify", "Transform Mode", "Move"),
+            ("Modify", "Transform Mode", "Rotate"),
+            ("Modify", "Transform Mode", "Scale"),
+            ("Lock Selection",),
+            ("Unlock All Entities",),
+            ("Editor Settings", "Global Preferences"),
+            ("Editor Settings", "Graphics Settings"),
+            ("Editor Settings", "Editor Settings Manager"),
+            ("Editor Settings", "Graphics Performance", "PC", "Very High"),
+            ("Editor Settings", "Graphics Performance", "PC", "High"),
+            ("Editor Settings", "Graphics Performance", "PC", "Medium"),
+            ("Editor Settings", "Graphics Performance", "PC", "Low"),
+            ("Editor Settings", "Graphics Performance", "OSX Metal", "Very High"),
+            ("Editor Settings", "Graphics Performance", "OSX Metal", "High"),
+            ("Editor Settings", "Graphics Performance", "OSX Metal", "Medium"),
+            ("Editor Settings", "Graphics Performance", "OSX Metal", "Low"),
+            ("Editor Settings", "Graphics Performance", "Android", "Very High"),
+            ("Editor Settings", "Graphics Performance", "Android", "High"),
+            ("Editor Settings", "Graphics Performance", "Android", "Medium"),
+            ("Editor Settings", "Graphics Performance", "Android", "Low"),
+            ("Editor Settings", "Graphics Performance", "iOS", "Very High"),
+            ("Editor Settings", "Graphics Performance", "iOS", "High"),
+            ("Editor Settings", "Graphics Performance", "iOS", "Medium"),
+            ("Editor Settings", "Graphics Performance", "iOS", "Low"),
+            ("Editor Settings", "Keyboard Customization", "Customize Keyboard"),
+            ("Editor Settings", "Keyboard Customization", "Export Keyboard Settings"),
+            ("Editor Settings", "Keyboard Customization", "Import Keyboard Settings"),
+        ]
+
+        # 1) Create and open the temp level
+        self.test_success = self.create_level(
+            self.args["level"],
+            heightmap_resolution=1024,
+            heightmap_meters_per_pixel=1,
+            terrain_texture_resolution=4096,
+            use_terrain=False,
+        )
+
+        def on_action_triggered(action_name):
+            print(f"{action_name} Action triggered")
+
+        # 2) Interact with Edit Menu options
+        try:
+            editor_window = pyside_utils.get_editor_main_window()
+            for option in edit_menu_options:
+                action = pyside_utils.get_action_for_menu_path(editor_window, "Edit", *option)
+                trig_func = lambda: on_action_triggered(action.iconText())
+                action.triggered.connect(trig_func)
+                action.trigger()
+                action.triggered.disconnect(trig_func)
+        except Exception as e:
+            self.test_success = False
+            print(e)
+
+
+test = TestEditMenuOptions()
+test.run()

+ 90 - 0
AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_FileMenuOptions.py

@@ -0,0 +1,90 @@
+"""
+All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+its licensors.
+
+For complete copyright and license terms please see the LICENSE at the root of this
+distribution (the "License"). All use of this software is governed by the License,
+or, if provided, by the license below or the license accompanying this file. Do not
+remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+"""
+
+"""
+C24064528: The File menu options function normally
+C16780778: The File menu options function normally-New view interaction Model enabled
+"""
+
+import os
+import sys
+
+import azlmbr.paths
+
+sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
+from automatedtesting_shared.editor_test_helper import EditorTestHelper
+import automatedtesting_shared.pyside_utils as pyside_utils
+
+
+class TestFileMenuOptions(EditorTestHelper):
+    def __init__(self):
+        EditorTestHelper.__init__(self, log_prefix="file_menu_options: ", args=["level"])
+
+    def run_test(self):
+        """
+        Summary:
+        Interact with File Menu options and verify if all the options are working.
+
+        Expected Behavior:
+        The File menu functions normally.
+
+        Test Steps:
+         1) Open level
+         2) Interact with File Menu options
+
+        Note:
+        - This test file must be called from the Lumberyard Editor command terminal
+        - Any passed and failed tests are written to the Editor.log file.
+                Parsing the file or running a log_monitor are required to observe the test results.
+
+        :return: None
+        """
+        file_menu_options = [
+            ("New Level",),
+            ("Open Level",),
+            ("Import",),
+            ("Save",),
+            ("Save As",),
+            ("Save Level Statistics",),
+            ("Project Settings", "Project Settings Tool"),
+            ("Show Log File",),
+            ("Resave All Slices",),
+            ("Exit",),
+        ]
+
+        # 1) Open level
+        self.test_success = self.create_level(
+            self.args["level"],
+            heightmap_resolution=1024,
+            heightmap_meters_per_pixel=1,
+            terrain_texture_resolution=4096,
+            use_terrain=False,
+        )
+
+        def on_action_triggered(action_name):
+            print(f"{action_name} Action triggered")
+
+        # 2) Interact with File Menu options
+        try:
+            editor_window = pyside_utils.get_editor_main_window()
+            for option in file_menu_options:
+                action = pyside_utils.get_action_for_menu_path(editor_window, "File", *option)
+                trig_func = lambda: on_action_triggered(action.iconText())
+                action.triggered.connect(trig_func)
+                action.trigger()
+                action.triggered.disconnect(trig_func)
+        except Exception as e:
+            self.test_success = False
+            print(e)
+
+
+test = TestFileMenuOptions()
+test.run()

+ 91 - 0
AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_ViewMenuOptions.py

@@ -0,0 +1,91 @@
+"""
+All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+its licensors.
+
+For complete copyright and license terms please see the LICENSE at the root of this
+distribution (the "License"). All use of this software is governed by the License,
+or, if provided, by the license below or the license accompanying this file. Do not
+remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+"""
+
+"""
+C24064534: The View menu options function normally
+"""
+
+import os
+import sys
+
+import azlmbr.paths
+
+sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
+from automatedtesting_shared.editor_test_helper import EditorTestHelper
+import automatedtesting_shared.pyside_utils as pyside_utils
+
+
+class TestViewMenuOptions(EditorTestHelper):
+    def __init__(self):
+        EditorTestHelper.__init__(self, log_prefix="Menus_EditMenuOptions", args=["level"])
+
+    def run_test(self):
+        """
+        Summary:
+        Interact with View Menu options and verify if all the options are working.
+
+        Expected Behavior:
+        The View menu functions normally.
+
+        Test Steps:
+         1) Create a temp level
+         2) Interact with View Menu options
+
+        Note:
+        - This test file must be called from the Lumberyard Editor command terminal
+        - Any passed and failed tests are written to the Editor.log file.
+                Parsing the file or running a log_monitor are required to observe the test results.
+
+        :return: None
+        """
+        view_menu_options = [
+            ("Center on Selection",),
+            ("Show Quick Access Bar",),
+            ("Viewport", "Wireframe"),
+            ("Viewport", "Grid Settings"),
+            ("Viewport", "Go to Position"),
+            ("Viewport", "Center on Selection"),
+            ("Viewport", "Go to Location"),
+            ("Viewport", "Remember Location"),
+            ("Viewport", "Change Move Speed"),
+            ("Viewport", "Switch Camera"),
+            ("Viewport", "Show/Hide Helpers"),
+            ("Refresh Style",),
+        ]
+
+        # 1) Create and open the temp level
+        self.test_success = self.create_level(
+            self.args["level"],
+            heightmap_resolution=1024,
+            heightmap_meters_per_pixel=1,
+            terrain_texture_resolution=4096,
+            use_terrain=False,
+        )
+
+        def on_action_triggered(action_name):
+            print(f"{action_name} Action triggered")
+
+        # 2) Interact with View Menu options
+        try:
+            editor_window = pyside_utils.get_editor_main_window()
+            for option in view_menu_options:
+                action = pyside_utils.get_action_for_menu_path(editor_window, "View", *option)
+                trig_func = lambda: on_action_triggered(action.iconText())
+                action.triggered.connect(trig_func)
+                action.trigger()
+                action.triggered.disconnect(trig_func)
+        except Exception as e:
+            self.test_success = False
+            print(e)
+
+
+test = TestViewMenuOptions()
+test.run()

+ 51 - 0
AutomatedTesting/Gem/PythonTests/editor/conftest.py

@@ -0,0 +1,51 @@
+"""
+All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+its licensors.
+
+For complete copyright and license terms please see the LICENSE at the root of this
+distribution (the "License"). All use of this software is governed by the License,
+or, if provided, by the license below or the license accompanying this file. Do not
+remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+"""
+
+import logging
+import pytest
+import winreg
+import automatedtesting_shared.registry_utils as reg
+
+
+logger = logging.getLogger(__name__)
+
+
+layout = {
+    'path': r'Software\Amazon\Lumberyard\Editor\fancyWindowLayouts',
+    'value': 'last'
+}
+restore_camera = {
+    'new': 16384,
+    'path': r'Software\Amazon\Lumberyard\Editor\AutoHide',
+    'value': 'ViewportCameraRestoreOnExitGameMode'
+}
+
+
[email protected](autouse=True)
+def set_editor_registry_defaults(request):
+    # Records editor settings at start, sets to default, then returns to original at teardown.
+    logger.debug('Executing an Editor settings fixture. If not executing an Editor test, this may be in error.')
+
+    layout['original'] = reg.get_ly_registry_value(layout['path'], layout['value'])
+    restore_camera['original'] = reg.get_ly_registry_value(restore_camera['path'], restore_camera['value'])
+
+    # Deleting current layout value to restore defaults
+    reg.delete_ly_registry_value(layout['path'], layout['value'])
+
+    # Setting restore camera dialog to not display
+    reg.set_ly_registry_value(restore_camera['path'], restore_camera['value'], restore_camera['new'])
+
+    # Revert settings to original values
+    def teardown():
+        reg.set_ly_registry_value(layout['path'], layout['value'], layout['original'], value_type=winreg.REG_BINARY)
+        reg.set_ly_registry_value(restore_camera['path'], restore_camera['value'], restore_camera['original'])
+
+    request.addfinalizer(teardown)

+ 92 - 0
AutomatedTesting/Gem/PythonTests/editor/test_AssetBrowser.py

@@ -0,0 +1,92 @@
+"""
+All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+its licensors.
+
+For complete copyright and license terms please see the LICENSE at the root of this
+distribution (the "License"). All use of this software is governed by the License,
+or, if provided, by the license below or the license accompanying this file. Do not
+remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+"""
+
+"""
+C13660195: Asset Browser - File Tree Navigation
+"""
+
+import os
+import pytest
+# Bail on the test if ly_test_tools doesn't exist.
+pytest.importorskip('ly_test_tools')
+import ly_test_tools.environment.file_system as file_system
+import automatedtesting_shared.hydra_test_utils as hydra
+
+test_directory = os.path.join(os.path.dirname(__file__), "EditorScripts")
+log_monitor_timeout = 180
+
+
[email protected]('project', ['AutomatedTesting'])
[email protected]('level', ['tmp_level'])
[email protected]("automatic_process_killer")
[email protected]("launcher_platform", ['windows_editor'])
+class TestAssetBrowser(object):
+
+    @pytest.fixture(autouse=True)
+    def setup_teardown(self, request, workspace, project, level):
+        def teardown():
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
+
+        request.addfinalizer(teardown)
+
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
+
+    @pytest.mark.test_case_id("C13660195")
+    @pytest.mark.SUITE_periodic
+    def test_AssetBrowser_TreeNavigation(self, request, editor, level, launcher_platform):
+        expected_lines = [
+            "Collapse/Expand tests: True",
+            "Asset visibility test: True",
+            "Scrollbar visibility test: True",
+            "AssetBrowser_TreeNavigation:  result=SUCCESS"
+
+        ]
+
+        hydra.launch_and_validate_results(
+            request,
+            test_directory,
+            editor,
+            "AssetBrowser_TreeNavigation.py",
+            expected_lines,
+            run_python="--runpython",
+            cfg_args=[level],
+            timeout=log_monitor_timeout
+        )
+
+    @pytest.mark.test_case_id("C13660194")
+    @pytest.mark.SUITE_periodic
+    def test_AssetBrowser_SearchFiltering(self, request, editor, level, launcher_platform):
+        expected_lines = [
+            "cedar.fbx asset is filtered in Asset Browser",
+            "Animation file type(s) is present in the file tree: True",
+            "FileTag file type(s) and Animation file type(s) is present in the file tree: True",
+            "FileTag file type(s) is present in the file tree after removing Animation filter: True",
+        ]
+
+        unexpected_lines = [
+            "Asset Browser opened: False",
+            "Animation file type(s) is present in the file tree: False",
+            "FileTag file type(s) and Animation file type(s) is present in the file tree: False",
+            "FileTag file type(s) is present in the file tree after removing Animation filter: False",
+        ]
+
+        hydra.launch_and_validate_results(
+            request,
+            test_directory,
+            editor,
+            "AssetBrowser_SearchFiltering.py",
+            expected_lines,
+            unexpected_lines=unexpected_lines,
+            cfg_args=[level],
+            auto_test_mode=False,
+            run_python="--runpython",
+            timeout=log_monitor_timeout,
+        )

+ 76 - 0
AutomatedTesting/Gem/PythonTests/editor/test_AssetPicker.py

@@ -0,0 +1,76 @@
+"""
+All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+its licensors.
+
+For complete copyright and license terms please see the LICENSE at the root of this
+distribution (the "License"). All use of this software is governed by the License,
+or, if provided, by the license below or the license accompanying this file. Do not
+remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+"""
+
+"""
+C13751579: Asset Picker UI/UX
+"""
+
+import os
+import pytest
+# Bail on the test if ly_test_tools doesn't exist.
+pytest.importorskip('ly_test_tools')
+import ly_test_tools.environment.file_system as file_system
+import automatedtesting_shared.hydra_test_utils as hydra
+
+test_directory = os.path.join(os.path.dirname(__file__), "EditorScripts")
+log_monitor_timeout = 90
+
+
[email protected]('project', ['AutomatedTesting'])
[email protected]('level', ['tmp_level'])
[email protected]("automatic_process_killer")
[email protected]("launcher_platform", ['windows_editor'])
+class TestAssetPicker(object):
+
+    @pytest.fixture(autouse=True)
+    def setup_teardown(self, request, workspace, project, level):
+        def teardown():
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
+
+        request.addfinalizer(teardown)
+
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
+
+    @pytest.mark.test_case_id("C13751579", "C1508814")
+    @pytest.mark.SUITE_periodic
+    def test_AssetPicker_UI_UX(self, request, editor, level, launcher_platform):
+        expected_lines = [
+            "TestEntity Entity successfully created",
+            "Mesh component was added to entity",
+            "Entity has a Mesh component",
+            "Mesh Asset: Asset Picker title for Mesh: Pick ModelAsset",
+            "Mesh Asset: Scroll Bar is not visible before expanding the tree: True",
+            "Mesh Asset: Top level folder initially collapsed: True",
+            "Mesh Asset: Top level folder expanded: True",
+            "Mesh Asset: Nested folder initially collapsed: True",
+            "Mesh Asset: Nested folder expanded: True",
+            "Mesh Asset: Scroll Bar appeared after expanding tree: True",
+            "Mesh Asset: Nested folder collapsed: True",
+            "Mesh Asset: Top level folder collapsed: True",
+            "Mesh Asset: Expected Assets populated in the file picker: True",
+            "Widget Move Test: True",
+            "Widget Resize Test: True",
+            "Asset assigned for ok option: True",
+            "Asset assigned for enter option: True",
+            "AssetPicker_UI_UX:  result=SUCCESS"
+        ]
+
+        hydra.launch_and_validate_results(
+            request,
+            test_directory,
+            editor,
+            "AssetPicker_UI_UX.py",
+            expected_lines,
+            cfg_args=[level],
+            run_python="--runpython",
+            auto_test_mode=False,
+            timeout=log_monitor_timeout,
+        )

+ 3 - 9
AutomatedTesting/Gem/PythonTests/editor/test_ComponentCRUD.py

@@ -33,11 +33,11 @@ class TestComponentCRUD(object):
     @pytest.fixture(autouse=True)
     def setup_teardown(self, request, workspace, project, level):
         def teardown():
-            file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
         request.addfinalizer(teardown)
 
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
     @pytest.mark.test_case_id("C16929880", "C16877220")
     @pytest.mark.SUITE_periodic
@@ -48,23 +48,17 @@ class TestComponentCRUD(object):
             "Box Shape found",
             "Box Shape Component added: True",
             "Mesh found",
-            "Box Shape and Mesh Components present in the entity: True",
+            "Mesh Component added: True",
             "Mesh Component deleted: True",
             "Mesh Component deletion undone: True",
         ]
 
-        unexpected_lines = [
-            "Box Shape Component added: False",
-            "Box Shape and Mesh Components present in the entity: False",
-        ]
-
         hydra.launch_and_validate_results(
             request,
             test_directory,
             editor,
             "ComponentCRUD_Add_Delete_Components.py",
             expected_lines,
-            unexpected_lines=unexpected_lines,
             cfg_args=[level],
             auto_test_mode=False,
             timeout=log_monitor_timeout

+ 58 - 0
AutomatedTesting/Gem/PythonTests/editor/test_Docking.py

@@ -0,0 +1,58 @@
+"""
+All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+its licensors.
+
+For complete copyright and license terms please see the LICENSE at the root of this
+distribution (the "License"). All use of this software is governed by the License,
+or, if provided, by the license below or the license accompanying this file. Do not
+remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+
+C6376081: Basic Function: Docked/Undocked Tools
+"""
+
+import os
+import pytest
+# Bail on the test if ly_test_tools doesn't exist.
+pytest.importorskip('ly_test_tools')
+import ly_test_tools.environment.file_system as file_system
+import automatedtesting_shared.hydra_test_utils as hydra
+
+test_directory = os.path.join(os.path.dirname(__file__), "EditorScripts")
+log_monitor_timeout = 180
+
+
[email protected]('project', ['AutomatedTesting'])
[email protected]('level', ['tmp_level'])
[email protected]("automatic_process_killer")
[email protected]("launcher_platform", ['windows_editor'])
+class TestDocking(object):
+
+    @pytest.fixture(autouse=True)
+    def setup_teardown(self, request, workspace, project, level):
+        def teardown():
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
+
+        request.addfinalizer(teardown)
+
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
+
+    @pytest.mark.test_case_id("C6376081")
+    @pytest.mark.SUITE_periodic
+    def test_basic_docked_tools(self, request, editor, level, launcher_platform):
+        expected_lines = [
+            "The tools are all docked together in a tabbed widget",
+            "Entity Outliner works when docked, can select an Entity",
+            "Entity Inspector works when docked, Entity name changed to DifferentName",
+            "Hello, world!"    # This line verifies the Console is working while docked
+        ]
+
+        hydra.launch_and_validate_results(
+            request,
+            test_directory,
+            editor,
+            "Docking_BasicDockedTools.py",
+            expected_lines,
+            cfg_args=[level],
+            timeout=log_monitor_timeout,
+        )

+ 2 - 2
AutomatedTesting/Gem/PythonTests/editor/test_InputBindings.py

@@ -33,11 +33,11 @@ class TestInputBindings(object):
     @pytest.fixture(autouse=True)
     def setup_teardown(self, request, workspace, project, level):
         def teardown():
-            file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
         request.addfinalizer(teardown)
 
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
     @pytest.mark.test_case_id("C1506881")
     @pytest.mark.SUITE_periodic

+ 143 - 0
AutomatedTesting/Gem/PythonTests/editor/test_Menus.py

@@ -0,0 +1,143 @@
+"""
+All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+its licensors.
+
+For complete copyright and license terms please see the LICENSE at the root of this
+distribution (the "License"). All use of this software is governed by the License,
+or, if provided, by the license below or the license accompanying this file. Do not
+remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+
+C16780783: Base Edit Menu Options (New Viewport Interaction Model)
+"""
+
+import os
+import pytest
+# Bail on the test if ly_test_tools doesn't exist.
+pytest.importorskip('ly_test_tools')
+import ly_test_tools.environment.file_system as file_system
+import automatedtesting_shared.hydra_test_utils as hydra
+
+test_directory = os.path.join(os.path.dirname(__file__), "EditorScripts")
+log_monitor_timeout = 180
+
+
[email protected]('project', ['AutomatedTesting'])
[email protected]('level', ['tmp_level'])
[email protected]("automatic_process_killer")
[email protected]("launcher_platform", ['windows_editor'])
+class TestMenus(object):
+
+    @pytest.fixture(autouse=True)
+    def setup_teardown(self, request, workspace, project, level):
+        def teardown():
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
+
+        request.addfinalizer(teardown)
+
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
+
+    @pytest.mark.test_case_id("C16780783", "C2174438")
+    @pytest.mark.SUITE_periodic
+    def test_Menus_EditMenuOptions_Work(self, request, editor, level, launcher_platform):
+        expected_lines = [
+            "Undo Action triggered",
+            "Redo Action triggered",
+            "Duplicate Action triggered",
+            "Delete Action triggered",
+            "Select All Action triggered",
+            "Invert Selection Action triggered",
+            "Toggle Pivot Location Action triggered",
+            "Reset Entity Transform",
+            "Reset Manipulator",
+            "Reset Transform (Local) Action triggered",
+            "Reset Transform (World) Action triggered",
+            "Hide Selection Action triggered",
+            "Show All Action triggered",
+            "Snap angle Action triggered",
+            "Move Action triggered",
+            "Rotate Action triggered",
+            "Scale Action triggered",
+            "Lock Selection Action triggered",
+            "Unlock All Entities Action triggered",
+            "Global Preferences Action triggered",
+            "Graphics Settings Action triggered",
+            "Editor Settings Manager Action triggered",
+            "Very High Action triggered",
+            "High Action triggered",
+            "Medium Action triggered",
+            "Low Action triggered",
+            "Customize Keyboard Action triggered",
+            "Export Keyboard Settings Action triggered",
+            "Import Keyboard Settings Action triggered",
+            "Menus_EditMenuOptions:  result=SUCCESS"
+        ]
+
+        hydra.launch_and_validate_results(
+            request,
+            test_directory,
+            editor,
+            "Menus_EditMenuOptions.py",
+            expected_lines,
+            cfg_args=[level],
+            run_python="--runpython",
+            auto_test_mode=True,
+            timeout=log_monitor_timeout,
+        )
+
+    @pytest.mark.test_case_id("C16780807")
+    @pytest.mark.SUITE_periodic
+    def test_Menus_ViewMenuOptions_Work(self, request, editor, level, launcher_platform):
+        expected_lines = [
+            "Center on Selection Action triggered",
+            "Show Quick Access Bar Action triggered",
+            "Wireframe Action triggered",
+            "Grid Settings Action triggered",
+            "Go to Position Action triggered",
+            "Center on Selection Action triggered",
+            "Go to Location Action triggered",
+            "Remember Location Action triggered",
+            "Change Move Speed Action triggered",
+            "Switch Camera Action triggered",
+            "Show/Hide Helpers Action triggered",
+            "Refresh Style Action triggered",
+        ]
+        hydra.launch_and_validate_results(
+            request,
+            test_directory,
+            editor,
+            "Menus_ViewMenuOptions.py",
+            expected_lines,
+            cfg_args=[level],
+            auto_test_mode=True,
+            run_python="--runpython",
+            timeout=log_monitor_timeout,
+        )
+
+    @pytest.mark.test_case_id("C16780778")
+    @pytest.mark.SUITE_periodic
+    def test_Menus_FileMenuOptions_Work(self, request, editor, level, launcher_platform):
+        expected_lines = [
+            "New Level Action triggered",
+            "Open Level Action triggered",
+            "Import Action triggered",
+            "Save Action triggered",
+            "Save As Action triggered",
+            "Save Level Statistics Action triggered",
+            "Project Settings Tool Action triggered",
+            "Show Log File Action triggered",
+            "Resave All Slices Action triggered",
+            "Exit Action triggered",
+        ]
+
+        hydra.launch_and_validate_results(
+            request,
+            test_directory,
+            editor,
+            "Menus_FileMenuOptions.py",
+            expected_lines,
+            cfg_args=[level],
+            auto_test_mode=True,
+            run_python="--runpython",
+            timeout=log_monitor_timeout,
+        )

+ 3 - 3
AutomatedTesting/Gem/PythonTests/editor/test_SearchFiltering.py

@@ -33,11 +33,11 @@ class TestSearchFiltering(object):
     @pytest.fixture(autouse=True)
     def setup_teardown(self, request, workspace, project, level):
         def teardown():
-            file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
         request.addfinalizer(teardown)
 
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
     @pytest.mark.test_case_id("C13660194")
     @pytest.mark.SUITE_periodic
@@ -60,7 +60,7 @@ class TestSearchFiltering(object):
             request,
             test_directory,
             editor,
-            "SearchFiltering_Asset_Browser_Filtering.py",
+            "AssetBrowser_SearchFiltering.py",
             expected_lines,
             unexpected_lines=unexpected_lines,
             cfg_args=[level],

+ 2 - 2
AutomatedTesting/Gem/PythonTests/editor/test_TreeNavigation.py

@@ -33,11 +33,11 @@ class TestTreeNavigation(object):
     @pytest.fixture(autouse=True)
     def setup_teardown(self, request, workspace, project, level):
         def teardown():
-            file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
         request.addfinalizer(teardown)
 
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
     @pytest.mark.test_case_id("C13660195")
     @pytest.mark.SUITE_periodic

+ 26 - 6
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AltitudeFilter_FilterStageToggle.py

@@ -11,6 +11,11 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
 import os
 import sys
+
+import azlmbr.bus as bus
+import azlmbr.components as components
+import azlmbr.editor as editor
+import azlmbr.legacy.general as general
 import azlmbr.math as math
 import azlmbr.paths
 
@@ -36,8 +41,8 @@ class TestAltitudeFilterFilterStageToggle(EditorTestHelper):
         :return: None
         """
 
-        PREPROCESS_INSTANCE_COUNT = 16
-        POSTPROCESS_INSTANCE_COUNT = 13
+        PREPROCESS_INSTANCE_COUNT = 24
+        POSTPROCESS_INSTANCE_COUNT = 18
 
         # Create empty level
         self.test_success = self.create_level(
@@ -60,7 +65,22 @@ class TestAltitudeFilterFilterStageToggle(EditorTestHelper):
         dynveg.create_surface_entity("Surface_Entity_Parent", position, 16.0, 16.0, 1.0)
 
         # Add entity with Mesh to replicate creation of hills
-        dynveg.create_mesh_surface_entity_with_slopes("hill", position, 40.0, 40.0, 40.0)
+        hill_entity = dynveg.create_mesh_surface_entity_with_slopes("hill", position, 40.0, 40.0, 40.0)
+
+        # Disable/Re-enable Mesh component due to ATOM-14299
+        general.idle_wait(1.0)
+        editor.EditorComponentAPIBus(bus.Broadcast, 'DisableComponents', [hill_entity.components[0]])
+        is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', hill_entity.components[0])
+        if is_enabled:
+            print("Mesh component is still enabled")
+        else:
+            print("Mesh component was disabled")
+        editor.EditorComponentAPIBus(bus.Broadcast, 'EnableComponents', [hill_entity.components[0]])
+        is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', hill_entity.components[0])
+        if is_enabled:
+            print("Mesh component is now enabled")
+        else:
+            print("Mesh component is still disabled")
 
         # Increase Box Shape size to encompass the hills
         vegetation.get_set_test(1, "Box Shape|Box Configuration|Dimensions", math.Vector3(100.0, 100.0, 100.0))
@@ -69,8 +89,8 @@ class TestAltitudeFilterFilterStageToggle(EditorTestHelper):
         vegetation.get_set_test(3, "Configuration|Altitude Min", 38.0)
         vegetation.get_set_test(3, "Configuration|Altitude Max", 40.0)
 
-        # Create a new entity as a child of the vegetation area entity with Random Noise Gradient Generator, Gradient Transform Modifier,
-        # and Box Shape component
+        # Create a new entity as a child of the vegetation area entity with Random Noise Gradient Generator, Gradient
+        # Transform Modifier, and Box Shape component
         random_noise = hydra.Entity("random_noise")
         random_noise.create_entity(position, ["Random Noise Gradient", "Gradient Transform Modifier", "Box Shape"])
         random_noise.set_test_parent_entity(vegetation)
@@ -91,4 +111,4 @@ class TestAltitudeFilterFilterStageToggle(EditorTestHelper):
 
 
 test = TestAltitudeFilterFilterStageToggle()
-test.run()
+test.run()

+ 33 - 9
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_FilterStageToggle.py

@@ -12,6 +12,9 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 import os
 import sys
 
+import azlmbr.bus as bus
+import azlmbr.editor as editor
+import azlmbr.legacy.general as general
 import azlmbr.math as math
 import azlmbr.paths
 
@@ -36,8 +39,8 @@ class TestLayerSpawnerFilterStageToggle(EditorTestHelper):
         :return: None
         """
 
-        PREPROCESS_INSTANCE_COUNT = 16
-        POSTPROCESS_INSTANCE_COUNT = 19
+        PREPROCESS_INSTANCE_COUNT = 425
+        POSTPROCESS_INSTANCE_COUNT = 430
 
         # Create empty level
         self.test_success = self.create_level(
@@ -48,13 +51,17 @@ class TestLayerSpawnerFilterStageToggle(EditorTestHelper):
             use_terrain=False,
         )
 
+        general.set_current_view_position(500.49, 498.69, 46.66)
+        general.set_current_view_rotation(-42.05, 0.00, -36.33)
+
         # Create a vegetation area with all needed components
         position = math.Vector3(512.0, 512.0, 32.0)
         asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
-        vegetation_entity = dynveg.create_vegetation_area("vegetation", position, 16.0, 16.0, 10.0, asset_path)
-        vegetation_entity.add_component("Vegetation Slope Filter")
+        vegetation_entity = dynveg.create_vegetation_area("vegetation", position, 16.0, 16.0, 16.0, asset_path)
+        vegetation_entity.add_component("Vegetation Altitude Filter")
         vegetation_entity.add_component("Vegetation Position Modifier")
 
+
         # Create a child entity under vegetation area
         child_entity = hydra.Entity("child_entity")
         components_to_add = ["Random Noise Gradient", "Gradient Transform Modifier", "Box Shape"]
@@ -64,12 +71,29 @@ class TestLayerSpawnerFilterStageToggle(EditorTestHelper):
         vegetation_entity.get_set_test(4, "Configuration|Position X|Gradient|Gradient Entity Id", child_entity.id)
         vegetation_entity.get_set_test(4, "Configuration|Position Y|Gradient|Gradient Entity Id", child_entity.id)
 
-        # Set the min and max values for Slope Filter
-        vegetation_entity.get_set_test(3, "Configuration|Slope Min", 25)
-        vegetation_entity.get_set_test(3, "Configuration|Slope Max", 35)
 
-        # Add entity with Mesh to replicate creation of hills
-        dynveg.create_mesh_surface_entity_with_slopes("hill", position, 5.0, 5.0, 5.0)
+        # Set the min and max values for Altitude Filter
+        vegetation_entity.get_set_test(3, "Configuration|Altitude Min", 32.0)
+        vegetation_entity.get_set_test(3, "Configuration|Altitude Max", 35.0)
+
+        # Add entity with Mesh to replicate creation of hills and a flat surface to plant on
+        dynveg.create_surface_entity("Flat Surface", position, 32.0, 32.0, 1.0)
+        hill_entity = dynveg.create_mesh_surface_entity_with_slopes("hill", position, 4.0, 4.0, 4.0)
+
+        # Disable/Re-enable Mesh component due to ATOM-14299
+        general.idle_wait(1.0)
+        editor.EditorComponentAPIBus(bus.Broadcast, 'DisableComponents', [hill_entity.components[0]])
+        is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', hill_entity.components[0])
+        if is_enabled:
+            print("Mesh component is still enabled")
+        else:
+            print("Mesh component was disabled")
+        editor.EditorComponentAPIBus(bus.Broadcast, 'EnableComponents', [hill_entity.components[0]])
+        is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', hill_entity.components[0])
+        if is_enabled:
+            print("Mesh component is now enabled")
+        else:
+            print("Mesh component is still disabled")
 
         # Set the filter stage to preprocess and postprocess respectively and verify instance count
         vegetation_entity.get_set_test(0, "Configuration|Filter Stage", 1)

+ 25 - 5
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshBlocker_InstancesBlockedByMesh.py

@@ -14,6 +14,9 @@ import os, sys
 sys.path.append(os.path.dirname(os.path.abspath(__file__)))
 import azlmbr.asset as asset
 import azlmbr.bus as bus
+import azlmbr.components as components
+import azlmbr.editor as editor
+import azlmbr.legacy.general as general
 import azlmbr.math as math
 
 sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
@@ -70,19 +73,36 @@ class test_MeshBlocker_InstancesBlockedByMesh(EditorTestHelper):
         dynveg.create_surface_entity("Surface Entity", entity_position, 10.0, 10.0, 1.0)
 
         # Create blocker entity with cube mesh
+        mesh_type_id = azlmbr.globals.property.EditorMeshComponentTypeId
         blocker_entity = hydra.Entity("Blocker Entity")
         blocker_entity.create_entity(entity_position,
-                                     ["Mesh", "Vegetation Layer Blocker (Mesh)"])
+                                     ["Vegetation Layer Blocker (Mesh)"])
+        blocker_entity.add_component_of_type(mesh_type_id)
         if blocker_entity.id.IsValid():
             print(f"'{blocker_entity.name}' created")
-
         cubeId = asset.AssetCatalogRequestBus(
-            bus.Broadcast, "GetAssetIdByPath", os.path.join("objects", "default", "primitive_cube.cgf"), math.Uuid(),
+            bus.Broadcast, "GetAssetIdByPath", os.path.join("objects", "_primitives", "_box_1x1.azmodel"), math.Uuid(),
             False)
-        blocker_entity.get_set_test(0, "MeshComponentRenderNode|Mesh asset", cubeId)
+        blocker_entity.get_set_test(1, "Controller|Configuration|Mesh Asset", cubeId)
+        components.TransformBus(bus.Event, "SetLocalScale", blocker_entity.id, math.Vector3(2.0, 2.0, 2.0))
+
+        # Disable/Re-enable Mesh component due to ATOM-14299
+        general.idle_wait(1.0)
+        editor.EditorComponentAPIBus(bus.Broadcast, 'DisableComponents', [blocker_entity.components[1]])
+        is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', blocker_entity.components[1])
+        if is_enabled:
+            print("Mesh component is still enabled")
+        else:
+            print("Mesh component was disabled")
+        editor.EditorComponentAPIBus(bus.Broadcast, 'EnableComponents', [blocker_entity.components[1]])
+        is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', blocker_entity.components[1])
+        if is_enabled:
+            print("Mesh component is now enabled")
+        else:
+            print("Mesh component is still disabled")
 
         # Verify spawned instance counts are accurate after addition of Blocker Entity
-        num_expected = 160  # Number of "PurpleFlower"s that plant on a 10 x 10 surface minus 1m blocker cube
+        num_expected = 160  # Number of "PurpleFlower"s that plant on a 10 x 10 surface minus 2m blocker cube
         result = self.wait_for_condition(lambda: dynveg.validate_instance_count_in_entity_shape(spawner_entity.id,
                                                                                                 num_expected), 2.0)
         self.test_success = self.test_success and result

+ 34 - 11
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshBlocker_InstancesBlockedByMeshHeightTuning.py

@@ -10,6 +10,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 """
 
 import os
+import math as pymath
 import sys
 
 sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -17,6 +18,8 @@ import azlmbr
 import azlmbr.asset as asset
 import azlmbr.bus as bus
 import azlmbr.components as components
+import azlmbr.editor as editor
+import azlmbr.legacy.general as general
 import azlmbr.math as math
 
 
@@ -63,6 +66,9 @@ class test_MeshBlocker_InstancesBlockedByMeshHeightTuning(EditorTestHelper):
             use_terrain=False,
         )
 
+        general.set_current_view_position(500.49, 498.69, 46.66)
+        general.set_current_view_rotation(-42.05, 0.00, -36.33)
+
         # 2) Create entity with components "Vegetation Layer Spawner", "Vegetation Asset List", "Box Shape"
         entity_position = math.Vector3(512.0, 512.0, 32.0)
         asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice")
@@ -74,29 +80,46 @@ class test_MeshBlocker_InstancesBlockedByMeshHeightTuning(EditorTestHelper):
         # 3) Create surface entity to plant on
         dynveg.create_surface_entity("Surface Entity", entity_position, 10.0, 10.0, 1.0)
 
-        # 4) Create blocker entity with cube mesh
-        entity_position = math.Vector3(512.0, 512.0, 36.0)
+        # 4) Create blocker entity with rotated cube mesh
+        y_rotation = pymath.radians(45.0)
+        mesh_type_id = azlmbr.globals.property.EditorMeshComponentTypeId
         blocker_entity = hydra.Entity("Blocker Entity")
         blocker_entity.create_entity(entity_position,
-                                     ["Mesh", "Vegetation Layer Blocker (Mesh)"])
+                                     ["Vegetation Layer Blocker (Mesh)"])
+        blocker_entity.add_component_of_type(mesh_type_id)
         if blocker_entity.id.IsValid():
             print(f"'{blocker_entity.name}' created")
-
-        sphereId = asset.AssetCatalogRequestBus(
-            bus.Broadcast, "GetAssetIdByPath", os.path.join("objects", "default", "primitive_sphere.cgf"), math.Uuid(),
+        sphere_id = asset.AssetCatalogRequestBus(
+            bus.Broadcast, "GetAssetIdByPath", os.path.join("objects", "_primitives", "_box_1x1.azmodel"), math.Uuid(),
             False)
-        blocker_entity.get_set_test(0, "MeshComponentRenderNode|Mesh asset", sphereId)
+        blocker_entity.get_set_test(1, "Controller|Configuration|Mesh Asset", sphere_id)
         components.TransformBus(bus.Event, "SetLocalScale", blocker_entity.id, math.Vector3(5.0, 5.0, 5.0))
+        components.TransformBus(bus.Event, "SetLocalRotation", blocker_entity.id, math.Vector3(0.0, y_rotation, 0.0))
+
+        # Disable/Re-enable Mesh component due to ATOM-14299
+        general.idle_wait(1.0)
+        editor.EditorComponentAPIBus(bus.Broadcast, 'DisableComponents', [blocker_entity.components[1]])
+        is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', blocker_entity.components[1])
+        if is_enabled:
+            print("Mesh component is still enabled")
+        else:
+            print("Mesh component was disabled")
+        editor.EditorComponentAPIBus(bus.Broadcast, 'EnableComponents', [blocker_entity.components[1]])
+        is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', blocker_entity.components[1])
+        if is_enabled:
+            print("Mesh component is now enabled")
+        else:
+            print("Mesh component is still disabled")
 
         # 5) Adjust the height Max percentage values of blocker
-        blocker_entity.get_set_test(1, "Configuration|Mesh Height Percent Max", 0.8)
+        blocker_entity.get_set_test(0, "Configuration|Mesh Height Percent Max", 0.8)
 
         # 6) Verify spawned instance counts are accurate after adjusting height Max percentage of Blocker Entity
-        # The number of "PurpleFlower" instances that plant on a 10 x 10 surface minus those blocked by the sphere at
+        # The number of "PurpleFlower" instances that plant on a 10 x 10 surface minus those blocked by the rotated at
         # 80% max height factored in.
-        num_expected = 117
+        num_expected = 127
         result = self.wait_for_condition(lambda: dynveg.validate_instance_count_in_entity_shape(spawner_entity.id,
-                                                                                                num_expected), 2.0)
+                                                                                                num_expected), 5.0)
         self.test_success = self.test_success and result
 
 

+ 26 - 4
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/PositionModifier_AutoSnapToSurfaceWorks.py

@@ -13,7 +13,9 @@ import os
 import sys
 
 sys.path.append(os.path.dirname(os.path.abspath(__file__)))
+import azlmbr.bus as bus
 import azlmbr.legacy.general as general
+import azlmbr.editor as editor
 import azlmbr.math as math
 import azlmbr.paths
 
@@ -82,14 +84,34 @@ class TestPositionModifierAutoSnapToSurface(EditorTestHelper):
         for path in position_modifier_paths:
             spawner_entity.get_set_test(3, path, 0)
 
-        # 3) Create a spherical planting surface
-        dynveg.create_mesh_surface_entity_with_slopes("Planting Surface", spawner_center_point, 5.0, 5.0, 5.0)
-
+        # 3) Create a spherical planting surface and a flat surface
+        flat_entity = dynveg.create_surface_entity("Flat Surface", spawner_center_point, 32.0, 32.0, 1.0)
+        hill_entity = dynveg.create_mesh_surface_entity_with_slopes("Planting Surface", spawner_center_point, 5.0, 5.0, 5.0)
+
+        # Disable/Re-enable Mesh component due to ATOM-14299
+        general.idle_wait(1.0)
+        editor.EditorComponentAPIBus(bus.Broadcast, 'DisableComponents', [hill_entity.components[0]])
+        is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', hill_entity.components[0])
+        if is_enabled:
+            print("Mesh component is still enabled")
+        else:
+            print("Mesh component was disabled")
+        editor.EditorComponentAPIBus(bus.Broadcast, 'EnableComponents', [hill_entity.components[0]])
+        is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', hill_entity.components[0])
+        if is_enabled:
+            print("Mesh component is now enabled")
+        else:
+            print("Mesh component is still disabled")
+
+        # Disable the Flat Surface Box Shape component, and temporarily ignore initial instance counts due to LYN-2245
+        editor.EditorComponentAPIBus(bus.Broadcast, 'DisableComponents', [flat_entity.components[0]])
+        """
         # 4) Verify initial instance counts pre-filter
-        num_expected = 121  # Single instance planted
+        num_expected = 121
         spawner_success = self.wait_for_condition(
             lambda: dynveg.validate_instance_count_in_entity_shape(spawner_entity.id, num_expected), 5.0)
         self.test_success = self.test_success and spawner_success
+        """
 
         # 5) Create a child entity of the spawner entity with a Constant Gradient component and pin to spawner
         components_to_add = ["Constant Gradient"]

+ 3 - 3
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SlopeAlignmentModifierOverrides_InstanceSurfaceAlignment.py

@@ -63,11 +63,11 @@ class TestSlopeAlignmentModifierOverrides(EditorTestHelper):
         spawner_entity = dynveg.create_vegetation_area("Instance Spawner", center_point, 16.0, 16.0, 32.0, asset_path)
 
         # Create a sloped mesh surface for the instances to plant on
-        mesh_asset_path = os.path.join("Objects", "default", "primitive_plane.cgf")
+        mesh_asset_path = os.path.join("objects", "_primitives", "_box_1x1.azmodel")
         mesh_asset = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", mesh_asset_path, math.Uuid(),
                                                   False)
         rotation = math.Vector3(0.0, radians(45.0), 0.0)
-        scale = math.Vector3(30.0, 30.0, 30.0)
+        scale = math.Vector3(10.0, 10.0, 10.0)
         surface_entity = hydra.Entity("Surface Entity")
         surface_entity.create_entity(
             center_point,
@@ -75,7 +75,7 @@ class TestSlopeAlignmentModifierOverrides(EditorTestHelper):
         )
         if surface_entity.id.IsValid():
             print(f"'{surface_entity.name}' created")
-        hydra.get_set_test(surface_entity, 0, "MeshComponentRenderNode|Mesh asset", mesh_asset)
+        hydra.get_set_test(surface_entity, 0, "Controller|Configuration|Mesh Asset", mesh_asset)
         components.TransformBus(bus.Event, "SetLocalRotation", surface_entity.id, rotation)
         components.TransformBus(bus.Event, "SetLocalScale", surface_entity.id, scale)
 

+ 3 - 3
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SlopeAlignmentModifier_InstanceSurfaceAlignment.py

@@ -66,11 +66,11 @@ class TestSlopeAlignmentModifier(EditorTestHelper):
         spawner_entity = dynveg.create_vegetation_area("Instance Spawner", center_point, 16.0, 16.0, 32.0, asset_path)
 
         # Create a sloped mesh surface for the instances to plant on
-        mesh_asset_path = os.path.join("Objects", "default", "primitive_plane.cgf")
+        mesh_asset_path = os.path.join("objects", "_primitives", "_box_1x1.azmodel")
         mesh_asset = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", mesh_asset_path, math.Uuid(),
                                                   False)
         rotation = math.Vector3(0.0, radians(45.0), 0.0)
-        scale = math.Vector3(30.0, 30.0, 30.0)
+        scale = math.Vector3(10.0, 10.0, 10.0)
         surface_entity = hydra.Entity("Surface Entity")
         surface_entity.create_entity(
             center_point,
@@ -78,7 +78,7 @@ class TestSlopeAlignmentModifier(EditorTestHelper):
         )
         if surface_entity.id.IsValid():
             print(f"'{surface_entity.name}' created")
-        hydra.get_set_test(surface_entity, 0, "MeshComponentRenderNode|Mesh asset", mesh_asset)
+        hydra.get_set_test(surface_entity, 0, "Controller|Configuration|Mesh Asset", mesh_asset)
         components.TransformBus(bus.Event, "SetLocalRotation", surface_entity.id, rotation)
         components.TransformBus(bus.Event, "SetLocalScale", surface_entity.id, scale)
 

+ 5 - 5
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_AltitudeFilter.py

@@ -30,13 +30,13 @@ class TestAltitudeFilter(object):
     @pytest.fixture(autouse=True)
     def setup_teardown(self, request, workspace, project, level):
         def teardown():
-            file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
         request.addfinalizer(teardown)
 
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
     @pytest.mark.test_case_id('C4814463', 'C4847477')
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_AltitudeFilter_ComponentAndOverrides_InstancesPlantAtSpecifiedAltitude(self, request, editor, level,
                                                                                     launcher_platform):
 
@@ -60,7 +60,7 @@ class TestAltitudeFilter(object):
         )
 
     @pytest.mark.test_case_id("C4847476")
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_AltitudeFilter_ShapeSample_InstancesPlantAtSpecifiedAltitude(self, request, editor, level,
                                                                           launcher_platform):
 
@@ -84,7 +84,7 @@ class TestAltitudeFilter(object):
         )
 
     @pytest.mark.test_case_id("C4847478")
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_AltitudeFilterFilterStageToggle(self, request, editor, level, workspace, launcher_platform):
         cfg_args = [level]
 

+ 7 - 7
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_AreaComponentSlices.py

@@ -30,28 +30,28 @@ class TestAreaComponents(object):
     @pytest.fixture(autouse=True)
     def setup_teardown(self, request, workspace, project, level):
         # Cleanup our temp level
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
         # Cleanup the test slices
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "slices", "TestSlice_1.slice")], True, True)
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "slices", "TestSlice_2.slice")], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "slices", "TestSlice_1.slice")], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "slices", "TestSlice_2.slice")], True, True)
 
         def teardown():
             # Cleanup our temp level
-            file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
             # Cleanup the test slices
             file_system.delete(
-                [os.path.join(workspace.paths.dev(), project, "slices", "TestSlice_1.slice")], True, True
+                [os.path.join(workspace.paths.engine_root(), project, "slices", "TestSlice_1.slice")], True, True
             )
             file_system.delete(
-                [os.path.join(workspace.paths.dev(), project, "slices", "TestSlice_2.slice")], True, True
+                [os.path.join(workspace.paths.engine_root(), project, "slices", "TestSlice_2.slice")], True, True
             )
 
         request.addfinalizer(teardown)
 
     @pytest.mark.test_case_id("C2627900", "C2627905", "C2627904")
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_AreaComponents_SliceCreationVisibilityToggleWorks(self, request, editor, level, workspace,
                                                               launcher_platform):
         cfg_args = [level]

+ 3 - 3
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_AssetListCombiner.py

@@ -31,13 +31,13 @@ class TestAssetListCombiner(object):
     @pytest.fixture(autouse=True)
     def setup_teardown(self, request, workspace, project, level):
         def teardown():
-            file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
         request.addfinalizer(teardown)
 
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
     @pytest.mark.test_case_id("C4762374", "C4762373")
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea(self, request, editor, level,
                                                                           launcher_platform):
 

+ 2 - 2
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_AssetWeightSelector.py

@@ -35,10 +35,10 @@ class TestAssetWeightSelector(object):
     @pytest.fixture(autouse=True)
     def setup_teardown(self, request, workspace, project, level):
         def teardown():
-            file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
         request.addfinalizer(teardown)
 
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
     @pytest.mark.test_case_id("C6269654", "C4762368")
     @pytest.mark.SUITE_sandbox

+ 3 - 3
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_Debugger.py

@@ -30,16 +30,16 @@ class TestDebugger(object):
     @pytest.fixture(autouse=True)
     def setup_teardown(self, request, workspace, project, level):
         # Cleanup our temp level
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
         def teardown():
             # Cleanup our temp level
-            file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
         request.addfinalizer(teardown)
 
     @pytest.mark.test_case_id("C2789148")
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_Debugger_DebugCVarsWork(self, request, editor, level, workspace, launcher_platform):
         cfg_args = [level]
 

+ 2 - 2
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_DistanceBetweenFilter.py

@@ -31,10 +31,10 @@ class TestDistanceBetweenFilter(object):
     @pytest.fixture(autouse=True)
     def setup_teardown(self, request, workspace, project, level):
         def teardown():
-            file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
         request.addfinalizer(teardown)
 
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
     @pytest.mark.test_case_id("C4851066")
     @pytest.mark.SUITE_periodic

+ 2 - 2
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_DynVeg_Regressions.py

@@ -30,13 +30,13 @@ class Test_DynVeg_Regressions(object):
     def setup_teardown(self, request, workspace, project, level):
         def teardown():
             # delete temp level
-            file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
         # Setup - add the teardown finalizer
         request.addfinalizer(teardown)
 
         # Make sure the temp level doesn't already exist
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
     @pytest.mark.test_case_id("C29470845")
     @pytest.mark.SUITE_periodic

+ 8 - 6
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_DynamicSliceInstanceSpawner.py

@@ -46,7 +46,7 @@ class TestDynamicSliceInstanceSpawner(object):
     def test_DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks(self, request, editor, level, workspace, project,
                                                                   launcher_platform):
         # Ensure temp level does not already exist
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
         cfg_args = [level]
 
@@ -61,7 +61,7 @@ class TestDynamicSliceInstanceSpawner(object):
                                           expected_lines=expected_lines, cfg_args=cfg_args)
 
         # Cleanup our temp level
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
     @pytest.mark.test_case_id('C2574330')
     @pytest.mark.BAT
@@ -70,7 +70,7 @@ class TestDynamicSliceInstanceSpawner(object):
     def test_DynamicSliceInstanceSpawner_Embedded_E2E_Editor(self, workspace, request, editor, level, project,
                                                              launcher_platform):
         # Ensure temp level does not already exist
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
         expected_lines = [
             "'Instance Spawner' created",
@@ -86,6 +86,7 @@ class TestDynamicSliceInstanceSpawner(object):
     @pytest.mark.BAT
     @pytest.mark.SUITE_periodic
     @pytest.mark.parametrize("launcher_platform", ['windows'])
+    @pytest.mark.skip      # ATOM-14703
     def test_DynamicSliceInstanceSpawner_Embedded_E2E_Launcher(self, workspace, launcher, level,
                                                                remote_console_instance, project, launcher_platform):
 
@@ -96,7 +97,7 @@ class TestDynamicSliceInstanceSpawner(object):
         hydra.launch_and_validate_results_launcher(launcher, level, remote_console_instance, expected_lines)
 
         # Cleanup our temp level
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
     @pytest.mark.test_case_id('C4762367')
     @pytest.mark.SUITE_periodic
@@ -104,7 +105,7 @@ class TestDynamicSliceInstanceSpawner(object):
     def test_DynamicSliceInstanceSpawner_External_E2E_Editor(self, workspace, request, editor, level, project,
                                                              launcher_platform):
         # Ensure temp level does not already exist
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
         expected_lines = [
             "Spawner entity created",
@@ -119,6 +120,7 @@ class TestDynamicSliceInstanceSpawner(object):
     @pytest.mark.test_case_id('C4762367')
     @pytest.mark.SUITE_periodic
     @pytest.mark.parametrize("launcher_platform", ['windows'])
+    @pytest.mark.skip      # ATOM-14703
     def test_DynamicSliceInstanceSpawner_External_E2E_Launcher(self, workspace, launcher, level,
                                                                remote_console_instance, project, launcher_platform):
 
@@ -129,5 +131,5 @@ class TestDynamicSliceInstanceSpawner(object):
         hydra.launch_and_validate_results_launcher(launcher, level, remote_console_instance, expected_lines)
 
         # Cleanup our temp level
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 

+ 2 - 2
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_EmptyInstanceSpawner.py

@@ -30,10 +30,10 @@ class TestEmptyInstanceSpawner(object):
     @pytest.fixture(autouse=True)
     def setup_teardown(self, request, workspace, project, level):
         def teardown():
-            file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
         request.addfinalizer(teardown)
 
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
     @pytest.mark.test_case_id("C28851762")
     @pytest.mark.SUITE_main

+ 3 - 3
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_InstanceSpawnerPriority.py

@@ -36,13 +36,13 @@ class TestInstanceSpawnerPriority(object):
     @pytest.fixture(autouse=True)
     def setup_teardown(self, request, workspace, project, level):
         def teardown():
-            file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
         request.addfinalizer(teardown)
 
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
     @pytest.mark.test_case_id("C5747383", "C4762382")
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_InstanceSpawnerPriority_LayerAndSubPriority_HigherValuesPlantOverLower(self, request, editor, level,
                                                                                     launcher_platform):
 

+ 4 - 4
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_LayerBlender.py

@@ -57,11 +57,11 @@ class TestLayerBlender(object):
 
     @pytest.mark.test_case_id("C2627906")
     @pytest.mark.BAT
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     @pytest.mark.parametrize("launcher_platform", ['windows_editor'])
     def test_LayerBlender_E2E_Editor(self, workspace, request, editor, project, level, launcher_platform):
         # Make sure temp level doesn't already exist
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
         expected_lines = [
             "'Purple Spawner' created",
@@ -94,7 +94,7 @@ class TestLayerBlender(object):
 
     @pytest.mark.test_case_id("C2627906")
     @pytest.mark.BAT
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     @pytest.mark.xfail
     @pytest.mark.parametrize("launcher_platform", ['windows'])
     def test_LayerBlender_E2E_Launcher(self, workspace, project, launcher, level, remote_console_instance,
@@ -112,4 +112,4 @@ class TestLayerBlender(object):
         assert ret_code == 0, "Test failed. See Game.log for details"
 
         # Cleanup our temp level
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)

+ 3 - 3
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_LayerBlocker.py

@@ -31,13 +31,13 @@ class TestLayerBlocker(object):
     @pytest.fixture(autouse=True)
     def setup_teardown(self, request, workspace, project, level):
         def teardown():
-            file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
         request.addfinalizer(teardown)
 
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
     @pytest.mark.test_case_id("C2793772")
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_LayerBlocker_InstancesBlockedInConfiguredArea(self, request, editor, level, launcher_platform):
 
         expected_lines = [

+ 7 - 6
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_LayerSpawner.py

@@ -30,16 +30,16 @@ class TestLayerSpawner(object):
     @pytest.fixture(autouse=True)
     def setup_teardown(self, request, workspace, project, level):
         # Cleanup our temp level
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
         def teardown():
             # Cleanup our temp level
-            file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
         request.addfinalizer(teardown)
 
     @pytest.mark.test_case_id("C4762381")
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_LayerSpawner_InheritBehaviorFlag(self, request, editor, level, workspace, launcher_platform):
 
         expected_lines = [
@@ -59,7 +59,7 @@ class TestLayerSpawner(object):
         )
 
     @pytest.mark.test_case_id("C2802020")
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_LayerSpawner_InstancesPlantInAllSupportedShapes(self, request, editor, level, launcher_platform):
 
         expected_lines = [
@@ -100,7 +100,7 @@ class TestLayerSpawner(object):
         )
 
     @pytest.mark.test_case_id("C4765973")
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_LayerSpawner_FilterStageToggle(self, request, editor, level, workspace, launcher_platform):
 
         expected_lines = [
@@ -120,7 +120,8 @@ class TestLayerSpawner(object):
         )
 
     @pytest.mark.test_case_id("C30000751")
-    @pytest.mark.SUITE_periodic
+    @pytest.mark.SUITE_sandbox
+    @pytest.mark.skip   # ATOM-14828
     def test_LayerSpawner_InstancesRefreshUsingCorrectViewportCamera(self, request, editor, level, launcher_platform):
 
         expected_lines = [

+ 5 - 5
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_MeshBlocker.py

@@ -34,18 +34,18 @@ class TestMeshBlocker(object):
 
         def teardown():
             # delete temp level
-            file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
         # Setup - add the teardown finalizer
         request.addfinalizer(teardown)
         # Make sure the temp level doesn't already exist
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
     """
     C3980834: A simple Vegetation Blocker Mesh can be created
     """
     @pytest.mark.test_case_id("C3980834")
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_MeshBlocker_InstancesBlockedByMesh(self, request, editor, level, launcher_platform):
         expected_lines = [
             "'Instance Spawner' created",
@@ -68,14 +68,14 @@ class TestMeshBlocker(object):
     C4766030: Mesh Height Percent Min/Max values can be set to fine tune the blocked area
     """
     @pytest.mark.test_case_id("C4766030")
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_MeshBlocker_InstancesBlockedByMeshHeightTuning(self, request, editor, level, launcher_platform):
         expected_lines = [
             "'Instance Spawner' created",
             "'Surface Entity' created",
             "'Blocker Entity' created",
             "Blocker Entity Configuration|Mesh Height Percent Max: SUCCESS",
-            "instance count validation: True (found=117, expected=117)",
+            "instance count validation: True (found=127, expected=127)",
             "MeshBlocker_InstancesBlockedByMeshHeightTuning:  result=SUCCESS",
         ]
 

+ 2 - 2
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_MeshSurfaceTagEmitter.py

@@ -31,10 +31,10 @@ class TestMeshSurfaceTagEmitter(object):
     @pytest.fixture(autouse=True)
     def setup_teardown(self, request, workspace, project, level):
         def teardown():
-            file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
         request.addfinalizer(teardown)
 
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
     @pytest.mark.test_case_id("C2908172")
     @pytest.mark.SUITE_periodic

+ 3 - 3
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_PhysXColliderSurfaceTagEmitter.py

@@ -31,13 +31,13 @@ class TestPhysXColliderSurfaceTagEmitter(object):
     @pytest.fixture(autouse=True)
     def setup_teardown(self, request, workspace, project, level):
         def teardown():
-            file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
         request.addfinalizer(teardown)
 
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
     @pytest.mark.test_case_id("C29053640")
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_PhysXColliderSurfaceTagEmitter_E2E_Editor(self, request, editor, level, launcher_platform):
 
         expected_lines = [

+ 4 - 5
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_PositionModifier.py

@@ -30,13 +30,13 @@ class TestPositionModifier(object):
     @pytest.fixture(autouse=True)
     def setup_teardown(self, request, workspace, project, level):
         def teardown():
-            file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
         request.addfinalizer(teardown)
 
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
     @pytest.mark.test_case_id("C4874099", "C4814461")
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_PositionModifier_ComponentAndOverrides_InstancesPlantAtSpecifiedOffsets(self, request, editor, level,
                                                                                      launcher_platform):
 
@@ -58,13 +58,12 @@ class TestPositionModifier(object):
         )
 
     @pytest.mark.test_case_id("C4874100")
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_sandbox
     def test_PositionModifier_AutoSnapToSurfaceWorks(self, request, editor, level, launcher_platform):
 
         expected_lines = [
             "'Instance Spawner' created",
             "'Planting Surface' created",
-            "instance count validation: True (found=121, expected=121)",
             "Instance Spawner Configuration|Position X|Range Min: SUCCESS",
             "Instance Spawner Configuration|Position X|Range Max: SUCCESS",
             "PositionModifier_AutoSnapToSurface:  result=SUCCESS"

+ 4 - 4
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_RotationModifier.py

@@ -33,15 +33,15 @@ class TestRotationModifier(object):
     def setup_teardown(self, request, workspace, project, level):
         def teardown():
             # delete temp level
-            file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
         # Setup - add the teardown finalizer
         request.addfinalizer(teardown)
 
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
     @pytest.mark.test_case_id("C4896922")
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_RotationModifier_InstancesRotateWithinRange(self, request, editor, level, launcher_platform) -> None:
         """
         Launches editor and run test script to test that rotation modifier works for all axis.
@@ -70,7 +70,7 @@ class TestRotationModifier(object):
         )
 
     @pytest.mark.test_case_id("C4814460")
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_RotationModifierOverrides_InstancesRotateWithinRange(self, request, editor, level, launcher_platform) -> None:
 
         expected_lines = [

+ 4 - 4
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_ScaleModifier.py

@@ -34,13 +34,13 @@ class TestScaleOverrideWorksSuccessfully(object):
     @pytest.fixture(autouse=True)
     def setup_teardown(self, request, workspace, project, level):
         def teardown():
-            file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
         request.addfinalizer(teardown)
 
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
     @pytest.mark.test_case_id("C4814462")
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_ScaleModifierOverrides_InstancesProperlyScale(self, request, editor, level, launcher_platform):
 
         expected_lines = [
@@ -69,7 +69,7 @@ class TestScaleOverrideWorksSuccessfully(object):
         )
 
     @pytest.mark.test_case_id("C4896937")
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_ScaleModifier_InstancesProperlyScale(self, request, editor, level, launcher_platform):
 
         expected_lines = [

+ 3 - 3
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_ShapeIntersectionFilter.py

@@ -30,13 +30,13 @@ class TestShapeIntersectionFilter(object):
     @pytest.fixture(autouse=True)
     def setup_teardown(self, request, workspace, project, level):
         def teardown():
-            file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
         request.addfinalizer(teardown)
 
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
     @pytest.mark.test_case_id("C4874094")
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_ShapeIntersectionFilter_InstancesPlantInAssignedShape(self, request, editor, level, launcher_platform):
 
         expected_lines = [

+ 6 - 4
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_SlopeAlignmentModifier.py

@@ -33,13 +33,14 @@ class TestSlopeAlignmentModifier(object):
     @pytest.fixture(autouse=True)
     def setup_teardown(self, request, workspace, project, level):
         def teardown():
-            file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
         request.addfinalizer(teardown)
 
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
     @pytest.mark.test_case_id("C4896941")
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
+    @pytest.mark.skip   # ATOM-14299
     def test_SlopeAlignmentModifier_InstanceSurfaceAlignment(self, request, editor, level, launcher_platform):
 
         expected_lines = [
@@ -60,7 +61,8 @@ class TestSlopeAlignmentModifier(object):
         )
 
     @pytest.mark.test_case_id("C4814459")
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
+    @pytest.mark.skip  # ATOM-14299
     def test_SlopeAlignmentModifierOverrides_InstanceSurfaceAlignment(self, request, editor, level, launcher_platform):
 
         expected_lines = [

+ 5 - 4
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_SlopeFilter.py

@@ -30,15 +30,15 @@ class TestSlopeFilter(object):
     @pytest.fixture(autouse=True)
     def setup_teardown(self, request, workspace, project, level):
         # Cleanup our temp level
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
         def teardown():
             # Cleanup our temp level
-            file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
         request.addfinalizer(teardown)
 
     @pytest.mark.test_case_id("C4874097")
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_SlopeFilter_FilterStageToggle(self, request, editor, level, workspace, launcher_platform):
         cfg_args = [level]
 
@@ -69,7 +69,8 @@ class TestSlopeFilter(object):
         )
 
     @pytest.mark.test_case_id("C4814464", "C4874096")
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
+    @pytest.mark.skip  # LYN-2211
     def test_SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlopes(self, request, editor, level,
                                                                            launcher_platform):
 

+ 5 - 5
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_SurfaceMaskFilter.py

@@ -30,13 +30,13 @@ class TestSurfaceMaskFilter(object):
     def setup_teardown(self, request, workspace, project, level):
         def teardown():
             # delete temp level
-            file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
         # Setup - add the teardown finalizer
         request.addfinalizer(teardown)
 
         # Make sure the temp level doesn't already exist
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
     # Simple validation test to ensure that SurfaceTag can be created, set to a value, and compared to another SurfaceTag.
     @pytest.mark.SUITE_periodic
@@ -60,7 +60,7 @@ class TestSurfaceMaskFilter(object):
         )
 
     @pytest.mark.test_case_id("C2561342")
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_SurfaceMaskFilter_ExclusiveSurfaceTags_Function(self, request, editor, level, launcher_platform):
 
         expected_lines = [
@@ -92,7 +92,7 @@ class TestSurfaceMaskFilter(object):
         )
 
     @pytest.mark.test_case_id("C2561341")
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_SurfaceMaskFilter_InclusiveSurfaceTags_Function(self, request, editor, level, launcher_platform):
 
         expected_lines = [
@@ -124,7 +124,7 @@ class TestSurfaceMaskFilter(object):
         )
 
     @pytest.mark.test_case_id("C3711666")
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_SurfaceMaskFilterOverrides_MultipleDescriptorOverridesPlantAsExpected(self, request, editor, level,
                                                                                    launcher_platform):
 

+ 4 - 4
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_SystemSettings.py

@@ -30,14 +30,14 @@ class TestSystemSettings(object):
     @pytest.fixture(autouse=True)
     def setup_teardown(self, request, workspace, project, level):
         def teardown():
-            file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
         request.addfinalizer(teardown)
 
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
     @pytest.mark.test_case_id("C2646869")
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_SystemSettings_SectorPointDensity(self, request, editor, level, launcher_platform):
 
         expected_lines = [
@@ -63,7 +63,7 @@ class TestSystemSettings(object):
         )
 
     @pytest.mark.test_case_id("C2646870")
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_SystemSettings_SectorSize(self, request, editor, level, launcher_platform):
 
         expected_lines = [

+ 1 - 1
AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/test_GradientIncompatibilities.py

@@ -63,7 +63,7 @@ class TestGradientIncompatibilities(object):
     @pytest.fixture(autouse=True)
     def setup_teardown(self, request, workspace, project, level):
         def teardown():
-            file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
         request.addfinalizer(teardown)
     

+ 2 - 2
AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/test_GradientPreviewSettings.py

@@ -28,10 +28,10 @@ class TestGradientPreviewSettings(object):
     @pytest.fixture(autouse=True)
     def setup_teardown(self, request, workspace, project, level):
         def teardown():
-            file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
         request.addfinalizer(teardown)
 
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
     @pytest.mark.test_case_id('C3980668', 'C2676825', 'C2676828', 'C2676822', 'C3416547', 'C3961320', 'C3961325',
                               'C3980658', 'C3980663')

+ 2 - 2
AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/test_GradientSampling.py

@@ -31,10 +31,10 @@ class TestGradientSampling(object):
     @pytest.fixture(autouse=True)
     def setup_teardown(self, request, workspace, project, level):
         def teardown():
-            file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
         request.addfinalizer(teardown)
 
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
     @pytest.mark.test_case_id("C3526311")
     @pytest.mark.SUITE_periodic

+ 4 - 4
AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/test_GradientSurfaceTagEmitter.py

@@ -32,13 +32,13 @@ class TestGradientSurfaceTagEmitter(object):
     def setup_teardown(self, request, workspace, project, level):
         # Cleanup temp level before and after test runs
         def teardown():
-            file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
         request.addfinalizer(teardown)
 
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
     @pytest.mark.test_case_id("C3297302")
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_GradientSurfaceTagEmitter_ComponentDependencies(self, request, editor, level, workspace,
                                                              launcher_platform):
         cfg_args = [level]
@@ -98,7 +98,7 @@ class TestGradientSurfaceTagEmitter(object):
         )
 
     @pytest.mark.test_case_id("C3297303")
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_GradientSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully(self, request, editor, level,
                                                                         launcher_platform):
 

+ 2 - 2
AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/test_GradientTransform.py

@@ -34,10 +34,10 @@ class TestGradientTransformRequiresShape(object):
     @pytest.fixture(autouse=True)
     def setup_teardown(self, request, workspace, project, level):
         def teardown():
-            file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
         request.addfinalizer(teardown)
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
     @pytest.mark.test_case_id('C3430289')
     @pytest.mark.SUITE_periodic

+ 1 - 1
AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/test_ImageGradient.py

@@ -27,7 +27,7 @@ class TestImageGradientRequiresShape(object):
     @pytest.fixture(autouse=True)
     def setup_teardown(self, request, workspace, project, level):
         def teardown():
-            file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
         request.addfinalizer(teardown)
 

+ 6 - 6
AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/test_AreaNodes.py

@@ -35,14 +35,14 @@ class TestAreaNodes(object):
     @pytest.fixture(autouse=True)
     def setup_teardown(self, request, workspace, project, level):
         def teardown():
-            file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
         request.addfinalizer(teardown)
 
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
     @pytest.mark.test_case_id('C13815919')
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_LandscapeCanvas_AreaNodes_DependentComponentsAdded(self, request, editor, level, launcher_platform):
         cfg_args = [level]
 
@@ -60,7 +60,7 @@ class TestAreaNodes(object):
                                           expected_lines, cfg_args=cfg_args)
 
     @pytest.mark.test_case_id('C13767844')
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_LandscapeCanvas_AreaNodes_EntityCreatedOnNodeAdd(self, request, editor, level, launcher_platform):
         """
         Verifies all Area nodes can be successfully added to a Landscape Canvas graph, and the proper entity
@@ -83,7 +83,7 @@ class TestAreaNodes(object):
                                           expected_lines, cfg_args=cfg_args)
 
     @pytest.mark.test_case_id('C17605868')
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_LandscapeCanvas_AreaNodes_EntityRemovedOnNodeDelete(self, request, editor, level, launcher_platform):
         """
         Verifies all Area nodes can be successfully removed from a Landscape Canvas graph, and the proper entity
@@ -106,7 +106,7 @@ class TestAreaNodes(object):
                                           'AreaNodes_EntityRemovedOnNodeDelete.py', expected_lines, cfg_args=cfg_args)
 
     @pytest.mark.test_case_id('C13815873')
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_LandscapeCanvas_LayerExtenderNodes_ComponentEntitySync(self, request, editor, level, launcher_platform):
         """
         Verifies all Area Extender nodes can be successfully added to and removed from a Landscape Canvas graph, and the

+ 4 - 4
AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/test_EditFunctionality.py

@@ -33,13 +33,13 @@ class TestEditFunctionality(object):
     @pytest.fixture(autouse=True)
     def setup_teardown(self, request, workspace, project, level):
         def teardown():
-            file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
         request.addfinalizer(teardown)
 
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
 
     @pytest.mark.test_case_id('C29278563')
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_LandscapeCanvas_DuplicateDisabledNodes(self, request, editor, level, launcher_platform):
         cfg_args = [level]
 
@@ -67,7 +67,7 @@ class TestEditFunctionality(object):
                                           expected_lines, cfg_args=cfg_args)
 
     @pytest.mark.test_case_id('C30813586')
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_LandscapeCanvas_UndoNodeDelete_SliceEntity(self, request, editor, level, launcher_platform):
         cfg_args = [level]
 

+ 10 - 10
AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/test_GeneralGraphFunctionality.py

@@ -34,16 +34,16 @@ class TestGeneralGraphFunctionality(object):
     @pytest.fixture(autouse=True)
     def setup_teardown(self, request, workspace, project, level):
         def teardown():
-            file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
-            file_system.delete([os.path.join(workspace.paths.dev(), project, "slices", "TestSlice.slice")], True, True)
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
+            file_system.delete([os.path.join(workspace.paths.engine_root(), project, "slices", "TestSlice.slice")], True, True)
 
         request.addfinalizer(teardown)
 
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "Levels", level)], True, True)
-        file_system.delete([os.path.join(workspace.paths.dev(), project, "slices", "TestSlice.slice")], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
+        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "slices", "TestSlice.slice")], True, True)
 
     @pytest.mark.test_case_id("C2735988", "C13815862", "C13767840")
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_LandscapeCanvas_NewGraph_CreatedSuccessfully(self, request, editor, level, launcher_platform):
         cfg_args = [level]
 
@@ -66,7 +66,7 @@ class TestGeneralGraphFunctionality(object):
         )
 
     @pytest.mark.test_case_id("C2735990")
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_LandscapeCanvas_Component_AddedRemoved(self, request, editor, level, launcher_platform):
         cfg_args = [level]
 
@@ -86,7 +86,7 @@ class TestGeneralGraphFunctionality(object):
         )
 
     @pytest.mark.test_case_id("C14212352")
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_LandscapeCanvas_GraphClosed_OnLevelChange(self, request, editor, level, launcher_platform):
         cfg_args = [level]
 
@@ -108,7 +108,7 @@ class TestGeneralGraphFunctionality(object):
         )
 
     @pytest.mark.test_case_id("C17488412")
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_LandscapeCanvas_GraphClosed_OnEntityDelete(self, request, editor, level, launcher_platform):
         cfg_args = [level]
 
@@ -129,7 +129,7 @@ class TestGeneralGraphFunctionality(object):
         )
 
     @pytest.mark.test_case_id("C15167461")
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_LandscapeCanvas_GraphClosed_TabbedGraphClosesIndependently(self, request, editor, level,
                                                                         launcher_platform):
         cfg_args = [level]
@@ -154,7 +154,7 @@ class TestGeneralGraphFunctionality(object):
         )
 
     @pytest.mark.test_case_id("C22602016")
-    @pytest.mark.SUITE_main
+    @pytest.mark.SUITE_periodic
     def test_LandscapeCanvas_SliceCreateInstantiate(self, request, editor, level, workspace, launcher_platform):
         cfg_args = [level]
 

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