Skip to content

Commit

Permalink
Adding tests for remix categories
Browse files Browse the repository at this point in the history
  • Loading branch information
Shona Gillard committed Aug 9, 2024
1 parent b5c08d9 commit 0d0b5e8
Show file tree
Hide file tree
Showing 9 changed files with 359 additions and 5 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- REMIX-3401: Added Centralized Generic factory
- Add github windows and linux build actions
- Add Data Migration documentation
- Adding tests for Remix Categories
- Adding tests for layer validation

### Changed
- REMIX-3401: Changed all usages of factories to use the Centralized Generic factory
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[package]
version = "1.1.0"
version = "1.1.1"
authors =["Damien Bataille <[email protected]>"]
title = "NVIDIA RTX Remix Mesh Properties implementation for the StageCraft"
description = "Mesh Properties implementation for NVIDIA RTX Remix StageCraft App"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Changelog
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## [1.1.1]
### Added
- Added Remix Categories tests

## [1.1.0]
### Added
- Added Remix Categories settings
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ def __create_ui(self):
vertical_scrollbar_policy=ui.ScrollBarPolicy.SCROLLBAR_AS_NEEDED,
tooltip="To set categories, use the Remix Categories window.",
mouse_pressed_fn=lambda x, y, b, m: self._add_remix_category(b),
name="CategoriesFrame",
)

def refresh(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import carb.input
import omni.ui as ui
import omni.usd
from carb.input import KeyboardInput
from carb.input import KeyboardEventType, KeyboardInput
from lightspeed.common import constants as _constants
from lightspeed.layer_manager.core import LayerManagerCore as _LayerManagerCore
from lightspeed.layer_manager.core import LayerType as _LayerType
Expand All @@ -30,6 +30,31 @@
from omni.kit.test_suite.helpers import arrange_windows, open_stage, wait_stage_loading


class ModifierKeyDownScope:
"""
A context creator to emulate the holding down of modifier keys within a scope. This is a workaround to using
KeyDownScope which did not directly work with modifiers such as left shift.
"""

def __init__(self, key: KeyboardInput, human_delay_speed: int = 2):
self._key = key
self._human_delay_speed = human_delay_speed

async def __aenter__(self):
# The key must be passed as both key and modifier to get the modifier effect to work
await self.emulate_keyboard(carb.input.KeyboardEventType.KEY_PRESS, self._key, self._key)
await ui_test.human_delay(self._human_delay_speed)

async def __aexit__(self, exc_type, exc, tb):
# No modifier should be passed so the modifier effect does not get stuck
await self.emulate_keyboard(carb.input.KeyboardEventType.KEY_RELEASE, self._key)
await ui_test.human_delay(self._human_delay_speed)

async def emulate_keyboard(self, event_type: KeyboardEventType, key: KeyboardInput, modifier: KeyboardInput = 0):
keyboard = omni.appwindow.get_default_app_window().get_keyboard()
carb.input.acquire_input_provider().buffer_keyboard_key_event(keyboard, event_type, key, modifier)


class TestSelectionTreeWidget(AsyncTestCase):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
Expand Down Expand Up @@ -609,3 +634,130 @@ async def __replace_mesh_ref_using_string_field_bad_ingested_asset_ignore(self,
item_prims = ui_test.find_all(f"{_window.title}//Frame/**/Label[*].identifier=='item_prim'")
self.assertEquals(len(item_prims), 5)
await self.__destroy(_window, _selection_wid, _mesh_property_wid)

async def test_assign_single_remix_category(self):
# setup
_window, _selection_wid, _mesh_property_wid = await self.__setup_widget() # Keep in memory during test

# select
usd_context = omni.usd.get_context()
usd_context.get_selection().set_selected_prim_paths(
["/RootNode/instances/inst_BAC90CAA733B0859_0/ref_c89e0497f4ff4dc4a7b70b79c85692da/Cube"], False
)

await ui_test.human_delay(human_delay_speed=3)

category_button = ui_test.find(f"{_window.title}//Frame/**/Image[*].name=='Categories'")
await category_button.click()
await ui_test.human_delay(3)

# Set a random remix category for us to assign
box = ui_test.find("Remix Categories//Frame/**/CheckBox[*].name=='remix_category:world_ui'")
await ui_test.emulate_mouse_move_and_click(box.position)
await ui_test.human_delay(3)

# Assign the category
assign_button = ui_test.find("Remix Categories//Frame/**/Button[*].identifier=='AssignCategoryButton'")
await assign_button.click()
await ui_test.human_delay(3)

# Check that the category got assigned on the prim
stage = usd_context.get_stage()
prim = stage.GetPrimAtPath(
"/RootNode/instances/inst_BAC90CAA733B0859_0/ref_c89e0497f4ff4dc4a7b70b79c85692da/Cube"
)
attrs = prim.GetAttributes()
test_attr = [attr for attr in attrs if attr.GetName() == "remix_category:world_ui"]

self.assertEqual(len(test_attr), 1)

await self.__destroy(_window, _selection_wid, _mesh_property_wid)

async def test_assign_multiple_remix_category(self):
# setup
_window, _selection_wid, _mesh_property_wid = await self.__setup_widget() # Keep in memory during test

# select
usd_context = omni.usd.get_context()
usd_context.get_selection().set_selected_prim_paths(
["/RootNode/instances/inst_BAC90CAA733B0859_0/ref_c89e0497f4ff4dc4a7b70b79c85692da/Cube"], False
)

await ui_test.human_delay(human_delay_speed=3)

category_button = ui_test.find(f"{_window.title}//Frame/**/Image[*].name=='Categories'")
await category_button.click()
await ui_test.human_delay(3)

# Set a random remix category for us to assign
box = ui_test.find("Remix Categories//Frame/**/CheckBox[*].name=='remix_category:world_ui'")
await ui_test.emulate_mouse_move_and_click(box.position)
await ui_test.human_delay(3)
box2 = ui_test.find("Remix Categories//Frame/**/CheckBox[*].name=='remix_category:decal_Static'")
await ui_test.emulate_mouse_move_and_click(box2.position)
await ui_test.human_delay(3)

# Assign the category
assign_button = ui_test.find("Remix Categories//Frame/**/Button[*].identifier=='AssignCategoryButton'")
await assign_button.click()

await ui_test.human_delay(3)

# Check that the category got assigned on the prim
stage = usd_context.get_stage()
prim = stage.GetPrimAtPath(
"/RootNode/instances/inst_BAC90CAA733B0859_0/ref_c89e0497f4ff4dc4a7b70b79c85692da/Cube"
)
attrs = prim.GetAttributes()
test_attr = [
attr for attr in attrs if attr.GetName() in ("remix_category:world_ui", "remix_category:decal_Static")
]

self.assertEqual(len(test_attr), 2)
await self.__destroy(_window, _selection_wid, _mesh_property_wid)

async def test_remix_categories_button_visibility(self):
# setup
_window, _selection_wid, _mesh_property_wid = await self.__setup_widget() # Keep in memory during test

# select
usd_context = omni.usd.get_context()
usd_context.get_selection().set_selected_prim_paths(
["/RootNode/instances/inst_BAC90CAA733B0859_0/ref_c89e0497f4ff4dc4a7b70b79c85692da/Cube"], False
)

category_button = ui_test.find(f"{_window.title}//Frame/**/ScrollingFrame[*].name=='CategoriesFrame'")
await ui_test.human_delay(50)
self.assertTrue(category_button.widget.visible)

items = ui_test.find_all(f"{_window.title}//Frame/**/ScrollingFrame[*].name=='TreePanelBackground'")

await items[1].click()
await ui_test.human_delay(60)

category_button = ui_test.find(f"{_window.title}//Frame/**/ScrollingFrame[*].name=='CategoriesFrame'")
self.assertFalse(category_button.widget.visible)

async def test_remix_categories_button_visibility_multi_select(self):
# setup
_window, _selection_wid, _mesh_property_wid = await self.__setup_widget() # Keep in memory during test

# select
usd_context = omni.usd.get_context()
usd_context.get_selection().set_selected_prim_paths(
["/RootNode/instances/inst_BAC90CAA733B0859_0/ref_c89e0497f4ff4dc4a7b70b79c85692da/Cube"], False
)

category_button = ui_test.find(f"{_window.title}//Frame/**/ScrollingFrame[*].name=='CategoriesFrame'")
await ui_test.human_delay(50)
self.assertTrue(category_button.widget.visible)

prims = ui_test.find_all(f"{_window.title}//Frame/**/Label[*].identifier=='item_prim'")

for prim in prims:
async with ModifierKeyDownScope(key=KeyboardInput.LEFT_SHIFT):
await prim.click()
await ui_test.human_delay(3)

category_button = ui_test.find(f"{_window.title}//Frame/**/ScrollingFrame[*].name=='CategoriesFrame'")
self.assertFalse(category_button.widget.visible)
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[package]
version = "1.2.8"
version = "1.2.9"
authors =["Damien Bataille <[email protected]>"]
title = "NVIDIA RTX Remix Properties Pane Asset Replacements widget for the StageCraft"
description = "Asset Replacements Properties Pane widget for NVIDIA RTX Remix StageCraft App"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Changelog
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## [1.2.9]
### Fixed
- Adding layer validation tests

## [1.2.8]
### Fixed
- Fixed layer validation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
from omni.flux.utils.widget.collapsable_frame import (
PropertyCollapsableFrameWithInfoPopup as _PropertyCollapsableFrameWithInfoPopup,
)
from pxr import Sdf
from pxr import Sdf, Tf


class AssetReplacementsPane:
Expand Down Expand Up @@ -340,7 +340,10 @@ def __on_selection_collapsable_frame_changed(self, collapsed):
self._selection_tree_widget.refresh()

def __validate_existing_layer(self, path):
sublayer = Sdf.Layer.FindOrOpen(str(path))
try:
sublayer = Sdf.Layer.FindOrOpen(str(path))
except Tf.ErrorException:
sublayer = None
if not sublayer:
self._layer_validation_error_msg = f"Unable to open layer {path.name}"
return False
Expand Down
Loading

0 comments on commit 0d0b5e8

Please sign in to comment.