find_package(Python3 COMPONENTS Interpreter REQUIRED)

add_test(NAME panopainter_clangd_nav_regex_self_test
    COMMAND "${Python3_EXECUTABLE}" "${PROJECT_SOURCE_DIR}/scripts/dev/clangd_nav.py" self-test)
set_tests_properties(panopainter_clangd_nav_regex_self_test PROPERTIES
    LABELS "tooling;desktop-fast")

add_test(NAME panopainter_platform_build_target_matrix_self_test
    COMMAND "${Python3_EXECUTABLE}" "${PROJECT_SOURCE_DIR}/scripts/dev/check_platform_build_targets.py")
set_tests_properties(panopainter_platform_build_target_matrix_self_test PROPERTIES
    LABELS "tooling;desktop-fast")

add_test(NAME panopainter_package_smoke_readiness_self_test
    COMMAND "${Python3_EXECUTABLE}" "${PROJECT_SOURCE_DIR}/scripts/dev/check_package_smoke_readiness.py")
set_tests_properties(panopainter_package_smoke_readiness_self_test PROPERTIES
    LABELS "tooling;desktop-fast")

add_test(NAME panopainter_retained_platform_cmake_self_test
    COMMAND "${Python3_EXECUTABLE}" "${PROJECT_SOURCE_DIR}/scripts/dev/check_retained_platform_cmake.py")
set_tests_properties(panopainter_retained_platform_cmake_self_test PROPERTIES
    LABELS "tooling;desktop-fast")

add_library(pp_test_harness INTERFACE)
target_include_directories(pp_test_harness INTERFACE
    "${CMAKE_CURRENT_SOURCE_DIR}")
target_link_libraries(pp_test_harness INTERFACE
    pp_project_options
    pp_project_warnings)

add_executable(pp_foundation_binary_stream_tests
    foundation/binary_stream_tests.cpp
)
target_link_libraries(pp_foundation_binary_stream_tests PRIVATE
    pp_foundation
    pp_test_harness)

add_test(NAME pp_foundation_binary_stream_tests COMMAND pp_foundation_binary_stream_tests)
set_tests_properties(pp_foundation_binary_stream_tests PROPERTIES
    LABELS "foundation;desktop-fast;fuzz")

add_executable(pp_foundation_event_tests
    foundation/event_tests.cpp)
target_link_libraries(pp_foundation_event_tests PRIVATE
    pp_foundation
    pp_test_harness)

add_test(NAME pp_foundation_event_tests COMMAND pp_foundation_event_tests)
set_tests_properties(pp_foundation_event_tests PROPERTIES
    LABELS "foundation;desktop-fast")

add_executable(pp_foundation_log_tests
    foundation/log_tests.cpp)
target_link_libraries(pp_foundation_log_tests PRIVATE
    pp_foundation
    pp_test_harness)

add_test(NAME pp_foundation_log_tests COMMAND pp_foundation_log_tests)
set_tests_properties(pp_foundation_log_tests PROPERTIES
    LABELS "foundation;desktop-fast")

add_executable(pp_foundation_parse_tests
    foundation/parse_tests.cpp)
target_link_libraries(pp_foundation_parse_tests PRIVATE
    pp_foundation
    pp_test_harness)

add_test(NAME pp_foundation_parse_tests COMMAND pp_foundation_parse_tests)
set_tests_properties(pp_foundation_parse_tests PROPERTIES
    LABELS "foundation;desktop-fast")

add_executable(pp_foundation_task_queue_tests
    foundation/task_queue_tests.cpp)
target_link_libraries(pp_foundation_task_queue_tests PRIVATE
    pp_foundation
    pp_test_harness)

add_test(NAME pp_foundation_task_queue_tests COMMAND pp_foundation_task_queue_tests)
set_tests_properties(pp_foundation_task_queue_tests PROPERTIES
    LABELS "foundation;desktop-fast")

add_executable(pp_foundation_trace_tests
    foundation/trace_tests.cpp)
target_link_libraries(pp_foundation_trace_tests PRIVATE
    pp_foundation
    pp_test_harness)

add_test(NAME pp_foundation_trace_tests COMMAND pp_foundation_trace_tests)
set_tests_properties(pp_foundation_trace_tests PROPERTIES
    LABELS "foundation;desktop-fast")

add_executable(pp_assets_image_format_tests
    assets/image_format_tests.cpp)
target_link_libraries(pp_assets_image_format_tests PRIVATE
    pp_assets
    pp_test_harness)

add_test(NAME pp_assets_image_format_tests COMMAND pp_assets_image_format_tests)
set_tests_properties(pp_assets_image_format_tests PROPERTIES
    LABELS "assets;desktop-fast")

add_executable(pp_assets_brush_package_tests
    assets/brush_package_tests.cpp)
target_link_libraries(pp_assets_brush_package_tests PRIVATE
    pp_assets
    pp_test_harness)

add_test(NAME pp_assets_brush_package_tests COMMAND pp_assets_brush_package_tests)
set_tests_properties(pp_assets_brush_package_tests PROPERTIES
    LABELS "assets;paint;desktop-fast;fuzz")

add_executable(pp_assets_image_metadata_tests
    assets/image_metadata_tests.cpp)
target_link_libraries(pp_assets_image_metadata_tests PRIVATE
    pp_assets
    pp_test_harness)

add_test(NAME pp_assets_image_metadata_tests COMMAND pp_assets_image_metadata_tests)
set_tests_properties(pp_assets_image_metadata_tests PROPERTIES
    LABELS "assets;desktop-fast;fuzz")

add_executable(pp_assets_image_pixels_tests
    assets/image_pixels_tests.cpp)
target_link_libraries(pp_assets_image_pixels_tests PRIVATE
    pp_assets
    pp_test_harness)

add_test(NAME pp_assets_image_pixels_tests COMMAND pp_assets_image_pixels_tests)
set_tests_properties(pp_assets_image_pixels_tests PROPERTIES
    LABELS "assets;desktop-fast")

add_executable(pp_assets_ppi_header_tests
    assets/ppi_header_tests.cpp)
target_link_libraries(pp_assets_ppi_header_tests PRIVATE
    pp_assets
    pp_test_harness)

add_test(NAME pp_assets_ppi_header_tests COMMAND pp_assets_ppi_header_tests)
set_tests_properties(pp_assets_ppi_header_tests PROPERTIES
    LABELS "assets;desktop-fast;fuzz")

add_executable(pp_assets_settings_document_tests
    assets/settings_document_tests.cpp)
target_link_libraries(pp_assets_settings_document_tests PRIVATE
    pp_assets
    pp_test_harness)

add_test(NAME pp_assets_settings_document_tests COMMAND pp_assets_settings_document_tests)
set_tests_properties(pp_assets_settings_document_tests PROPERTIES
    LABELS "assets;desktop-fast")

add_executable(pp_paint_brush_tests
    paint/brush_tests.cpp)
target_link_libraries(pp_paint_brush_tests PRIVATE
    pp_paint
    pp_test_harness)

add_test(NAME pp_paint_brush_tests COMMAND pp_paint_brush_tests)
set_tests_properties(pp_paint_brush_tests PROPERTIES
    LABELS "paint;desktop-fast")

add_executable(pp_paint_blend_tests
    paint/blend_tests.cpp)
target_link_libraries(pp_paint_blend_tests PRIVATE
    pp_paint
    pp_test_harness)

add_test(NAME pp_paint_blend_tests COMMAND pp_paint_blend_tests)
set_tests_properties(pp_paint_blend_tests PROPERTIES
    LABELS "paint;desktop-fast")

add_executable(pp_paint_stroke_tests
    paint/stroke_tests.cpp)
target_link_libraries(pp_paint_stroke_tests PRIVATE
    pp_paint
    pp_test_harness)

add_test(NAME pp_paint_stroke_tests COMMAND pp_paint_stroke_tests)
set_tests_properties(pp_paint_stroke_tests PROPERTIES
    LABELS "paint;desktop-fast;stress")

add_executable(pp_paint_stroke_script_tests
    paint/stroke_script_tests.cpp)
target_link_libraries(pp_paint_stroke_script_tests PRIVATE
    pp_paint
    pp_test_harness)

add_test(NAME pp_paint_stroke_script_tests COMMAND pp_paint_stroke_script_tests)
set_tests_properties(pp_paint_stroke_script_tests PROPERTIES
    LABELS "paint;desktop-fast;fuzz")

add_executable(pp_document_tests
    document/document_tests.cpp)
target_link_libraries(pp_document_tests PRIVATE
    pp_document
    pp_test_harness)

add_test(NAME pp_document_tests COMMAND pp_document_tests)
set_tests_properties(pp_document_tests PROPERTIES
    LABELS "document;desktop-fast")

add_executable(pp_document_ppi_import_tests
    document/ppi_import_tests.cpp)
target_link_libraries(pp_document_ppi_import_tests PRIVATE
    pp_document
    pp_test_harness)

add_test(NAME pp_document_ppi_import_tests COMMAND pp_document_ppi_import_tests)
set_tests_properties(pp_document_ppi_import_tests PROPERTIES
    LABELS "assets;document;integration;desktop-fast")

add_executable(pp_document_ppi_export_tests
    document/ppi_export_tests.cpp)
target_link_libraries(pp_document_ppi_export_tests PRIVATE
    pp_document
    pp_test_harness)

add_test(NAME pp_document_ppi_export_tests COMMAND pp_document_ppi_export_tests)
set_tests_properties(pp_document_ppi_export_tests PROPERTIES
    LABELS "assets;document;integration;desktop-fast")

add_executable(pp_renderer_api_tests
    renderer_api/renderer_api_tests.cpp)
target_link_libraries(pp_renderer_api_tests PRIVATE
    pp_renderer_api
    pp_test_harness)

add_test(NAME pp_renderer_api_tests COMMAND pp_renderer_api_tests)
set_tests_properties(pp_renderer_api_tests PROPERTIES
    LABELS "renderer;desktop-fast")

if(TARGET pp_renderer_gl)
    add_executable(pp_renderer_gl_capabilities_tests
        renderer_gl/capabilities_tests.cpp)
    target_link_libraries(pp_renderer_gl_capabilities_tests PRIVATE
        pp_renderer_gl
        pp_test_harness)

    add_test(NAME pp_renderer_gl_capabilities_tests COMMAND pp_renderer_gl_capabilities_tests)
    set_tests_properties(pp_renderer_gl_capabilities_tests PROPERTIES
        LABELS "renderer;desktop-fast")

    add_executable(pp_renderer_gl_command_plan_tests
        renderer_gl/command_plan_tests.cpp)
    target_link_libraries(pp_renderer_gl_command_plan_tests PRIVATE
        pp_renderer_gl
        pp_test_harness)

    add_test(NAME pp_renderer_gl_command_plan_tests COMMAND pp_renderer_gl_command_plan_tests)
    set_tests_properties(pp_renderer_gl_command_plan_tests PROPERTIES
        LABELS "renderer;desktop-fast")
endif()

add_executable(pp_paint_renderer_compositor_tests
    paint_renderer/compositor_tests.cpp)
target_link_libraries(pp_paint_renderer_compositor_tests PRIVATE
    pp_paint_renderer
    pp_test_harness)

add_test(NAME pp_paint_renderer_compositor_tests COMMAND pp_paint_renderer_compositor_tests)
set_tests_properties(pp_paint_renderer_compositor_tests PROPERTIES
    LABELS "renderer;paint;desktop-fast")

add_executable(pp_platform_api_tests
    platform_api/platform_services_tests.cpp)
target_link_libraries(pp_platform_api_tests PRIVATE
    pp_platform_api
    pp_test_harness)

add_test(NAME pp_platform_api_tests COMMAND pp_platform_api_tests)
set_tests_properties(pp_platform_api_tests PROPERTIES
    LABELS "os-api;desktop-fast")

add_executable(pp_ui_core_color_tests
    ui_core/color_tests.cpp)
target_link_libraries(pp_ui_core_color_tests PRIVATE
    pp_ui_core
    pp_test_harness)

add_test(NAME pp_ui_core_color_tests COMMAND pp_ui_core_color_tests)
set_tests_properties(pp_ui_core_color_tests PROPERTIES
    LABELS "ui;desktop-fast")

add_executable(pp_ui_core_layout_value_tests
    ui_core/layout_value_tests.cpp)
target_link_libraries(pp_ui_core_layout_value_tests PRIVATE
    pp_ui_core
    pp_test_harness)

add_test(NAME pp_ui_core_layout_value_tests COMMAND pp_ui_core_layout_value_tests)
set_tests_properties(pp_ui_core_layout_value_tests PROPERTIES
    LABELS "ui;desktop-fast")

add_executable(pp_ui_core_layout_xml_tests
    ui_core/layout_xml_tests.cpp)
target_link_libraries(pp_ui_core_layout_xml_tests PRIVATE
    pp_ui_core
    pp_test_harness)

add_test(NAME pp_ui_core_layout_xml_tests COMMAND pp_ui_core_layout_xml_tests)
set_tests_properties(pp_ui_core_layout_xml_tests PROPERTIES
    LABELS "ui;desktop-fast;fuzz")

add_executable(pp_app_core_about_menu_tests
    app_core/about_menu_tests.cpp)
target_link_libraries(pp_app_core_about_menu_tests PRIVATE
    pp_app_core
    pp_test_harness)

add_test(NAME pp_app_core_about_menu_tests COMMAND pp_app_core_about_menu_tests)
set_tests_properties(pp_app_core_about_menu_tests PROPERTIES
    LABELS "app;ui;desktop-fast;fuzz")

add_executable(pp_app_core_brush_ui_tests
    app_core/brush_ui_tests.cpp)
target_link_libraries(pp_app_core_brush_ui_tests PRIVATE
    pp_app_core
    pp_test_harness)

add_test(NAME pp_app_core_brush_ui_tests COMMAND pp_app_core_brush_ui_tests)
set_tests_properties(pp_app_core_brush_ui_tests PROPERTIES
    LABELS "app;paint;desktop-fast;fuzz")

add_executable(pp_app_core_brush_package_export_tests
    app_core/brush_package_export_tests.cpp)
target_link_libraries(pp_app_core_brush_package_export_tests PRIVATE
    pp_app_core
    pp_test_harness)

add_test(NAME pp_app_core_brush_package_export_tests COMMAND pp_app_core_brush_package_export_tests)
set_tests_properties(pp_app_core_brush_package_export_tests PROPERTIES
    LABELS "app;paint;assets;desktop-fast;fuzz")

add_executable(pp_app_core_brush_package_import_tests
    app_core/brush_package_import_tests.cpp)
target_link_libraries(pp_app_core_brush_package_import_tests PRIVATE
    pp_app_core
    pp_test_harness)

add_test(NAME pp_app_core_brush_package_import_tests COMMAND pp_app_core_brush_package_import_tests)
set_tests_properties(pp_app_core_brush_package_import_tests PROPERTIES
    LABELS "app;paint;assets;desktop-fast;fuzz")

add_executable(pp_app_core_canvas_tool_ui_tests
    app_core/canvas_tool_ui_tests.cpp)
target_link_libraries(pp_app_core_canvas_tool_ui_tests PRIVATE
    pp_app_core
    pp_test_harness)

add_test(NAME pp_app_core_canvas_tool_ui_tests COMMAND pp_app_core_canvas_tool_ui_tests)
set_tests_properties(pp_app_core_canvas_tool_ui_tests PROPERTIES
    LABELS "app;ui;desktop-fast;fuzz")

add_executable(pp_app_core_canvas_hotkey_tests
    app_core/canvas_hotkey_tests.cpp)
target_link_libraries(pp_app_core_canvas_hotkey_tests PRIVATE
    pp_app_core
    pp_test_harness)

add_test(NAME pp_app_core_canvas_hotkey_tests COMMAND pp_app_core_canvas_hotkey_tests)
set_tests_properties(pp_app_core_canvas_hotkey_tests PROPERTIES
    LABELS "app;ui;document;paint;desktop-fast;fuzz")

add_executable(pp_app_core_canvas_view_tests
    app_core/canvas_view_tests.cpp)
target_link_libraries(pp_app_core_canvas_view_tests PRIVATE
    pp_app_core
    pp_test_harness)

add_test(NAME pp_app_core_canvas_view_tests COMMAND pp_app_core_canvas_view_tests)
set_tests_properties(pp_app_core_canvas_view_tests PROPERTIES
    LABELS "app;ui;desktop-fast")

add_executable(pp_app_core_grid_ui_tests
    app_core/grid_ui_tests.cpp)
target_link_libraries(pp_app_core_grid_ui_tests PRIVATE
    pp_app_core
    pp_test_harness)

add_test(NAME pp_app_core_grid_ui_tests COMMAND pp_app_core_grid_ui_tests)
set_tests_properties(pp_app_core_grid_ui_tests PROPERTIES
    LABELS "app;ui;renderer;desktop-fast;fuzz")

add_executable(pp_app_core_history_ui_tests
    app_core/history_ui_tests.cpp)
target_link_libraries(pp_app_core_history_ui_tests PRIVATE
    pp_app_core
    pp_test_harness)

add_test(NAME pp_app_core_history_ui_tests COMMAND pp_app_core_history_ui_tests)
set_tests_properties(pp_app_core_history_ui_tests PROPERTIES
    LABELS "app;document;ui;desktop-fast;fuzz")

add_executable(pp_app_core_main_toolbar_tests
    app_core/main_toolbar_tests.cpp)
target_link_libraries(pp_app_core_main_toolbar_tests PRIVATE
    pp_app_core
    pp_test_harness)

add_test(NAME pp_app_core_main_toolbar_tests COMMAND pp_app_core_main_toolbar_tests)
set_tests_properties(pp_app_core_main_toolbar_tests PROPERTIES
    LABELS "app;document;ui;desktop-fast;fuzz")

add_executable(pp_app_core_quick_ui_tests
    app_core/quick_ui_tests.cpp)
target_link_libraries(pp_app_core_quick_ui_tests PRIVATE
    pp_app_core
    pp_test_harness)

add_test(NAME pp_app_core_quick_ui_tests COMMAND pp_app_core_quick_ui_tests)
set_tests_properties(pp_app_core_quick_ui_tests PROPERTIES
    LABELS "app;ui;paint;desktop-fast;fuzz")

add_executable(pp_app_core_tools_menu_tests
    app_core/tools_menu_tests.cpp)
target_link_libraries(pp_app_core_tools_menu_tests PRIVATE
    pp_app_core
    pp_test_harness)

add_test(NAME pp_app_core_tools_menu_tests COMMAND pp_app_core_tools_menu_tests)
set_tests_properties(pp_app_core_tools_menu_tests PROPERTIES
    LABELS "app;ui;desktop-fast;fuzz")

add_executable(pp_app_core_document_route_tests
    app_core/document_route_tests.cpp)
target_link_libraries(pp_app_core_document_route_tests PRIVATE
    pp_app_core
    pp_test_harness)

add_test(NAME pp_app_core_document_route_tests COMMAND pp_app_core_document_route_tests)
set_tests_properties(pp_app_core_document_route_tests PROPERTIES
    LABELS "app;desktop-fast;fuzz")

add_executable(pp_app_core_file_menu_tests
    app_core/file_menu_tests.cpp)
target_link_libraries(pp_app_core_file_menu_tests PRIVATE
    pp_app_core
    pp_test_harness)

add_test(NAME pp_app_core_file_menu_tests COMMAND pp_app_core_file_menu_tests)
set_tests_properties(pp_app_core_file_menu_tests PROPERTIES
    LABELS "app;desktop-fast;fuzz")

add_executable(pp_app_core_document_canvas_tests
    app_core/document_canvas_tests.cpp)
target_link_libraries(pp_app_core_document_canvas_tests PRIVATE
    pp_app_core
    pp_test_harness)

add_test(NAME pp_app_core_document_canvas_tests COMMAND pp_app_core_document_canvas_tests)
set_tests_properties(pp_app_core_document_canvas_tests PROPERTIES
    LABELS "app;document;desktop-fast;fuzz")

add_executable(pp_app_core_document_import_tests
    app_core/document_import_tests.cpp)
target_link_libraries(pp_app_core_document_import_tests PRIVATE
    pp_app_core
    pp_test_harness)

add_test(NAME pp_app_core_document_import_tests COMMAND pp_app_core_document_import_tests)
set_tests_properties(pp_app_core_document_import_tests PROPERTIES
    LABELS "app;document;desktop-fast;fuzz")

add_executable(pp_app_core_document_export_tests
    app_core/document_export_tests.cpp)
target_link_libraries(pp_app_core_document_export_tests PRIVATE
    pp_app_core
    pp_test_harness)

add_test(NAME pp_app_core_document_export_tests COMMAND pp_app_core_document_export_tests)
set_tests_properties(pp_app_core_document_export_tests PROPERTIES
    LABELS "app;desktop-fast;fuzz")

add_executable(pp_app_core_document_cloud_tests
    app_core/document_cloud_tests.cpp)
target_link_libraries(pp_app_core_document_cloud_tests PRIVATE
    pp_app_core
    pp_test_harness)

add_test(NAME pp_app_core_document_cloud_tests COMMAND pp_app_core_document_cloud_tests)
set_tests_properties(pp_app_core_document_cloud_tests PROPERTIES
    LABELS "app;desktop-fast;fuzz")

add_executable(pp_app_core_document_platform_io_tests
    app_core/document_platform_io_tests.cpp)
target_link_libraries(pp_app_core_document_platform_io_tests PRIVATE
    pp_app_core
    pp_test_harness)

add_test(NAME pp_app_core_document_platform_io_tests COMMAND pp_app_core_document_platform_io_tests)
set_tests_properties(pp_app_core_document_platform_io_tests PROPERTIES
    LABELS "app;desktop-fast;fuzz")

add_executable(pp_app_core_document_recording_tests
    app_core/document_recording_tests.cpp)
target_link_libraries(pp_app_core_document_recording_tests PRIVATE
    pp_app_core
    pp_test_harness)

add_test(NAME pp_app_core_document_recording_tests COMMAND pp_app_core_document_recording_tests)
set_tests_properties(pp_app_core_document_recording_tests PROPERTIES
    LABELS "app;desktop-fast;fuzz")

add_executable(pp_app_core_document_animation_tests
    app_core/document_animation_tests.cpp)
target_link_libraries(pp_app_core_document_animation_tests PRIVATE
    pp_app_core
    pp_test_harness)

add_test(NAME pp_app_core_document_animation_tests COMMAND pp_app_core_document_animation_tests)
set_tests_properties(pp_app_core_document_animation_tests PROPERTIES
    LABELS "app;desktop-fast;fuzz")

add_executable(pp_app_core_document_layer_tests
    app_core/document_layer_tests.cpp)
target_link_libraries(pp_app_core_document_layer_tests PRIVATE
    pp_app_core
    pp_test_harness)

add_test(NAME pp_app_core_document_layer_tests COMMAND pp_app_core_document_layer_tests)
set_tests_properties(pp_app_core_document_layer_tests PROPERTIES
    LABELS "app;desktop-fast;fuzz")

add_executable(pp_app_core_document_resize_tests
    app_core/document_resize_tests.cpp)
target_link_libraries(pp_app_core_document_resize_tests PRIVATE
    pp_app_core
    pp_test_harness)

add_test(NAME pp_app_core_document_resize_tests COMMAND pp_app_core_document_resize_tests)
set_tests_properties(pp_app_core_document_resize_tests PROPERTIES
    LABELS "app;desktop-fast;fuzz")

add_executable(pp_app_core_app_preferences_tests
    app_core/app_preferences_tests.cpp)
target_link_libraries(pp_app_core_app_preferences_tests PRIVATE
    pp_app_core
    pp_test_harness)

add_test(NAME pp_app_core_app_preferences_tests COMMAND pp_app_core_app_preferences_tests)
set_tests_properties(pp_app_core_app_preferences_tests PROPERTIES
    LABELS "app;desktop-fast;fuzz")

add_executable(pp_app_core_app_status_tests
    app_core/app_status_tests.cpp)
target_link_libraries(pp_app_core_app_status_tests PRIVATE
    pp_app_core
    pp_test_harness)

add_test(NAME pp_app_core_app_status_tests COMMAND pp_app_core_app_status_tests)
set_tests_properties(pp_app_core_app_status_tests PROPERTIES
    LABELS "app;desktop-fast;fuzz")

add_executable(pp_app_core_app_dialog_tests
    app_core/app_dialog_tests.cpp)
target_link_libraries(pp_app_core_app_dialog_tests PRIVATE
    pp_app_core
    pp_test_harness)

add_test(NAME pp_app_core_app_dialog_tests COMMAND pp_app_core_app_dialog_tests)
set_tests_properties(pp_app_core_app_dialog_tests PROPERTIES
    LABELS "app;desktop-fast;fuzz")

add_executable(pp_app_core_app_startup_tests
    app_core/app_startup_tests.cpp)
target_link_libraries(pp_app_core_app_startup_tests PRIVATE
    pp_app_core
    pp_test_harness)

add_test(NAME pp_app_core_app_startup_tests COMMAND pp_app_core_app_startup_tests)
set_tests_properties(pp_app_core_app_startup_tests PROPERTIES
    LABELS "app;desktop-fast;fuzz")

add_executable(pp_app_core_app_frame_tests
    app_core/app_frame_tests.cpp)
target_link_libraries(pp_app_core_app_frame_tests PRIVATE
    pp_app_core
    pp_test_harness)

add_test(NAME pp_app_core_app_frame_tests COMMAND pp_app_core_app_frame_tests)
set_tests_properties(pp_app_core_app_frame_tests PROPERTIES
    LABELS "app;desktop-fast;fuzz")

add_executable(pp_app_core_app_thread_tests
    app_core/app_thread_tests.cpp)
target_link_libraries(pp_app_core_app_thread_tests PRIVATE
    pp_app_core
    pp_test_harness)

add_test(NAME pp_app_core_app_thread_tests COMMAND pp_app_core_app_thread_tests)
set_tests_properties(pp_app_core_app_thread_tests PROPERTIES
    LABELS "app;desktop-fast;fuzz")

add_executable(pp_app_core_app_input_tests
    app_core/app_input_tests.cpp)
target_link_libraries(pp_app_core_app_input_tests PRIVATE
    pp_app_core
    pp_test_harness)

add_test(NAME pp_app_core_app_input_tests COMMAND pp_app_core_app_input_tests)
set_tests_properties(pp_app_core_app_input_tests PROPERTIES
    LABELS "app;desktop-fast;fuzz")

add_executable(pp_app_core_app_shutdown_tests
    app_core/app_shutdown_tests.cpp)
target_link_libraries(pp_app_core_app_shutdown_tests PRIVATE
    pp_app_core
    pp_test_harness)

add_test(NAME pp_app_core_app_shutdown_tests COMMAND pp_app_core_app_shutdown_tests)
set_tests_properties(pp_app_core_app_shutdown_tests PROPERTIES
    LABELS "app;desktop-fast")

add_executable(pp_app_core_command_convert_tests
    app_core/command_convert_tests.cpp)
target_link_libraries(pp_app_core_command_convert_tests PRIVATE
    pp_app_core
    pp_test_harness)

add_test(NAME pp_app_core_command_convert_tests COMMAND pp_app_core_command_convert_tests)
set_tests_properties(pp_app_core_command_convert_tests PROPERTIES
    LABELS "app;desktop-fast;fuzz")

add_executable(pp_app_core_document_sharing_tests
    app_core/document_sharing_tests.cpp)
target_link_libraries(pp_app_core_document_sharing_tests PRIVATE
    pp_app_core
    pp_test_harness)

add_test(NAME pp_app_core_document_sharing_tests COMMAND pp_app_core_document_sharing_tests)
set_tests_properties(pp_app_core_document_sharing_tests PROPERTIES
    LABELS "app;desktop-fast;fuzz")

add_executable(pp_app_core_document_session_tests
    app_core/document_session_tests.cpp)
target_link_libraries(pp_app_core_document_session_tests PRIVATE
    pp_app_core
    pp_test_harness)

add_test(NAME pp_app_core_document_session_tests COMMAND pp_app_core_document_session_tests)
set_tests_properties(pp_app_core_document_session_tests PROPERTIES
    LABELS "app;desktop-fast")

if(TARGET pano_cli)
    add_test(NAME pano_cli_create_document_smoke
        COMMAND pano_cli create-document --width 64 --height 32 --layers 2)
    set_tests_properties(pano_cli_create_document_smoke PROPERTIES
        LABELS "integration;desktop-fast")

    add_test(NAME pano_cli_create_animation_document_smoke
        COMMAND pano_cli create-document --width 64 --height 32 --layers 2 --frames 3 --frame-duration-ms 250)
    set_tests_properties(pano_cli_create_animation_document_smoke PROPERTIES
        LABELS "document;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"frames\":3.*\"activeFrame\":2.*\"animationDurationMs\":750")

    add_test(NAME pano_cli_inspect_image_rejects_unsupported
        COMMAND pano_cli inspect-image --path "${CMAKE_CURRENT_SOURCE_DIR}/data/images/unsupported-image.txt")
    set_tests_properties(pano_cli_inspect_image_rejects_unsupported PROPERTIES
        LABELS "assets;integration;desktop-fast"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_inspect_png_metadata_smoke
        COMMAND pano_cli inspect-image --path "${CMAKE_CURRENT_SOURCE_DIR}/data/images/tiny-rgba-header.png")
    set_tests_properties(pano_cli_inspect_png_metadata_smoke PROPERTIES
        LABELS "assets;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"format\":\"png\".*\"width\":320.*\"height\":240.*\"components\":4.*\"colorType\":\"rgba\"")

    add_test(NAME pano_cli_import_image_rejects_truncated_png
        COMMAND "${CMAKE_COMMAND}"
            -DPANO_CLI=$<TARGET_FILE:pano_cli>
            -DIMAGE_PATH=${CMAKE_CURRENT_SOURCE_DIR}/data/images/tiny-rgba-header.png
            "-DEXPECTED_OUTPUT=PNG payload could not be decoded"
            -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/expect_pano_cli_import_image_failure.cmake")
    set_tests_properties(pano_cli_import_image_rejects_truncated_png PROPERTIES
        LABELS "assets;document;integration;desktop-fast")

    add_test(NAME pano_cli_import_image_smoke
        COMMAND pano_cli import-image
            --path "${CMAKE_CURRENT_SOURCE_DIR}/data/images/tiny-rgba-1x1.png"
            --document-width 64
            --document-height 32
            --face 5
            --x 7
            --y 11)
    set_tests_properties(pano_cli_import_image_smoke PROPERTIES
        LABELS "assets;document;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"import-image\".*\"image\":\\{\"format\":\"png\",\"width\":1,\"height\":1,\"bytes\":4\\}.*\"document\":\\{\"width\":64,\"height\":32,\"layers\":1,\"frames\":1,\"facePayloads\":1\\}.*\"payload\":\\{\"face\":5,\"x\":7,\"y\":11,\"width\":1,\"height\":1,\"bytes\":4\\}")

    add_test(NAME pano_cli_export_image_roundtrip_smoke
        COMMAND "${CMAKE_COMMAND}"
            -DPANO_CLI=$<TARGET_FILE:pano_cli>
            -DOUTPUT_PATH=${CMAKE_CURRENT_BINARY_DIR}/data/generated/export-roundtrip.png
            -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/pano_cli_export_image_roundtrip.cmake")
    set_tests_properties(pano_cli_export_image_roundtrip_smoke PROPERTIES
        LABELS "assets;document;integration;desktop-fast")

    add_test(NAME pano_cli_inspect_project_layout_smoke
        COMMAND pano_cli inspect-project --path "${CMAKE_CURRENT_SOURCE_DIR}/data/projects/minimal-project.ppi")
    set_tests_properties(pano_cli_inspect_project_layout_smoke PROPERTIES
        LABELS "assets;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"thumbnail\":\\{\"width\":128,\"height\":128,\"components\":4,\"bytes\":65536\\}.*\"body\":\\{\"offset\":65576,\"bytes\":73,\"width\":64,\"height\":32,\"layers\":1,\"frames\":1,\"dirtyFaces\":0,\"rgbaFacePayloads\":0,\"compressedBytes\":0,\"infoBytes\":0\\}.*\"layers\":\\[\\{\"index\":0,\"storedOrder\":0,\"name\":\"Ink\"")

    add_test(NAME pano_cli_load_project_metadata_smoke
        COMMAND pano_cli load-project --path "${CMAKE_CURRENT_SOURCE_DIR}/data/projects/minimal-project.ppi")
    set_tests_properties(pano_cli_load_project_metadata_smoke PROPERTIES
        LABELS "assets;document;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"load-project\".*\"pixelDataLoaded\":false.*\"facePayloads\":0.*\"document\":\\{\"width\":64,\"height\":32,\"layers\":1,\"frames\":1,\"animationDurationMs\":100,\"layerNames\":\\[\"Ink\"\\],\"layerFrameCounts\":\\[1\\],\"layerDurationsMs\":\\[100\\]")

    add_test(NAME pano_cli_classify_open_project_smoke
        COMMAND pano_cli classify-open --path "D:/Paint/Scenes/demo.ppi")
    set_tests_properties(pano_cli_classify_open_project_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"classify-open\".*\"kind\":\"open-project\".*\"directory\":\"D:/Paint/Scenes\".*\"name\":\"demo\".*\"extension\":\"ppi\"")

    add_test(NAME pano_cli_classify_open_brush_import_smoke
        COMMAND pano_cli classify-open --path "D:/Paint/Brushes/clouds.ABR")
    set_tests_properties(pano_cli_classify_open_brush_import_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"classify-open\".*\"kind\":\"import-abr\".*\"name\":\"clouds\".*\"extension\":\"abr\"")

    add_test(NAME pano_cli_classify_open_ppbr_import_smoke
        COMMAND pano_cli classify-open --path "D:/Paint/Brushes/palette.PpBr")
    set_tests_properties(pano_cli_classify_open_ppbr_import_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"classify-open\".*\"kind\":\"import-ppbr\".*\"name\":\"palette\".*\"extension\":\"ppbr\"")

    add_test(NAME pano_cli_classify_open_rejects_missing_directory
        COMMAND "${CMAKE_COMMAND}"
            -DPANO_CLI=$<TARGET_FILE:pano_cli>
            -DOPEN_PATH=demo.ppi
            "-DEXPECTED_OUTPUT=document path must include a directory and file name"
            -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/expect_pano_cli_classify_open_failure.cmake")
    set_tests_properties(pano_cli_classify_open_rejects_missing_directory PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
    )

    add_test(NAME pano_cli_plan_open_route_project_clean_smoke
        COMMAND pano_cli plan-open-route --path "D:/Paint/Scenes/demo.ppi")
    set_tests_properties(pano_cli_plan_open_route_project_clean_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-open-route\".*\"kind\":\"open-project\".*\"unsaved\":false.*\"action\":\"open-project-now\"")

    add_test(NAME pano_cli_plan_open_route_project_unsaved_smoke
        COMMAND pano_cli plan-open-route --path "D:/Paint/Scenes/demo.ppi" --unsaved)
    set_tests_properties(pano_cli_plan_open_route_project_unsaved_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-open-route\".*\"kind\":\"open-project\".*\"unsaved\":true.*\"action\":\"prompt-discard-unsaved-project\"")

    add_test(NAME pano_cli_plan_open_route_abr_import_smoke
        COMMAND pano_cli plan-open-route --path "D:/Paint/Brushes/clouds.ABR" --unsaved)
    set_tests_properties(pano_cli_plan_open_route_abr_import_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-open-route\".*\"kind\":\"import-abr\".*\"unsaved\":true.*\"action\":\"prompt-import-abr\"")

    add_test(NAME pano_cli_plan_file_menu_import_smoke
        COMMAND pano_cli plan-file-menu --command import)
    set_tests_properties(pano_cli_plan_file_menu_import_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-file-menu\".*\"command\":\"import\".*\"action\":\"pick-image-for-import\"")

    add_test(NAME pano_cli_plan_file_menu_save_as_smoke
        COMMAND pano_cli plan-file-menu --command save-as)
    set_tests_properties(pano_cli_plan_file_menu_save_as_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-file-menu\".*\"command\":\"save-as\".*\"action\":\"save-document\".*\"saveIntent\":\"save-as\"")

    add_test(NAME pano_cli_plan_file_menu_export_smoke
        COMMAND pano_cli plan-file-menu --command export)
    set_tests_properties(pano_cli_plan_file_menu_export_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-file-menu\".*\"command\":\"export\".*\"action\":\"show-export-jpeg-dialog\".*\"exportKind\":\"jpeg\"")

    add_test(NAME pano_cli_plan_file_menu_cloud_upload_smoke
        COMMAND pano_cli plan-file-menu --command cloud-upload)
    set_tests_properties(pano_cli_plan_file_menu_cloud_upload_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-file-menu\".*\"command\":\"cloud-upload\".*\"action\":\"upload-to-cloud\"")

    add_test(NAME pano_cli_plan_file_menu_rejects_unknown
        COMMAND pano_cli plan-file-menu --command nope)
    set_tests_properties(pano_cli_plan_file_menu_rejects_unknown PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_document_file_save_now_smoke
        COMMAND pano_cli plan-document-file --work-dir D:/Paint --name demo)
    set_tests_properties(pano_cli_plan_document_file_save_now_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-document-file\".*\"name\":\"demo\".*\"directory\":\"D:/Paint\".*\"path\":\"D:/Paint/demo.ppi\".*\"exists\":false.*\"decision\":\"save-now\"")

    add_test(NAME pano_cli_plan_document_file_overwrite_smoke
        COMMAND pano_cli plan-document-file --work-dir D:/Paint --name demo --target-exists)
    set_tests_properties(pano_cli_plan_document_file_overwrite_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-document-file\".*\"path\":\"D:/Paint/demo.ppi\".*\"exists\":true.*\"decision\":\"prompt-overwrite\"")

    add_test(NAME pano_cli_plan_new_document_smoke
        COMMAND pano_cli plan-new-document --work-dir D:/Paint --name demo --resolution-index 3)
    set_tests_properties(pano_cli_plan_new_document_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-new-document\".*\"path\":\"D:/Paint/demo.ppi\".*\"exists\":false.*\"resolution\":2048.*\"decision\":\"save-now\"")

    add_test(NAME pano_cli_plan_new_document_overwrite_smoke
        COMMAND pano_cli plan-new-document --work-dir D:/Paint --name demo --resolution-index 1 --target-exists)
    set_tests_properties(pano_cli_plan_new_document_overwrite_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-new-document\".*\"path\":\"D:/Paint/demo.ppi\".*\"exists\":true.*\"resolution\":1024.*\"decision\":\"prompt-overwrite\"")

    add_test(NAME pano_cli_plan_new_document_rejects_invalid_resolution
        COMMAND "${CMAKE_COMMAND}"
            -DPANO_CLI=$<TARGET_FILE:pano_cli>
            "-DEXPECTED_OUTPUT=document resolution index is out of range"
            -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/expect_pano_cli_plan_new_document_failure.cmake")
    set_tests_properties(pano_cli_plan_new_document_rejects_invalid_resolution PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz")

    add_test(NAME pano_cli_plan_document_version_first_smoke
        COMMAND pano_cli plan-document-version --directory D:/Paint --doc-name demo)
    set_tests_properties(pano_cli_plan_document_version_first_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-document-version\".*\"documentName\":\"demo\".*\"name\":\"demo.01\".*\"path\":\"D:/Paint/demo.01.ppi\"")

    add_test(NAME pano_cli_plan_document_version_skip_existing_smoke
        COMMAND pano_cli plan-document-version --directory D:/Paint --doc-name demo.01 --existing-path D:/Paint/demo.02.ppi)
    set_tests_properties(pano_cli_plan_document_version_skip_existing_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-document-version\".*\"documentName\":\"demo.01\".*\"existingPaths\":1.*\"name\":\"demo.03\".*\"path\":\"D:/Paint/demo.03.ppi\"")

    add_test(NAME pano_cli_plan_document_session_prompt_close_smoke
        COMMAND pano_cli plan-document-session-prompt --kind close-unsaved)
    set_tests_properties(pano_cli_plan_document_session_prompt_close_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-document-session-prompt\".*\"kind\":\"close-unsaved\".*\"title\":\"Unsaved document\".*\"message\":\"Do you want to close without saving\\?\".*\"okCaption\":\"Yes\".*\"cancelCaption\":\"No\".*\"showCancel\":true")

    add_test(NAME pano_cli_plan_document_session_prompt_overwrite_smoke
        COMMAND pano_cli plan-document-session-prompt --kind file-overwrite --name demo)
    set_tests_properties(pano_cli_plan_document_session_prompt_overwrite_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-document-session-prompt\".*\"kind\":\"file-overwrite\".*\"message\":\"Are you sure you want to overwrite demo\\?\".*\"showCancel\":true")

    add_test(NAME pano_cli_plan_document_session_prompt_rejects_unknown
        COMMAND pano_cli plan-document-session-prompt --kind nope)
    set_tests_properties(pano_cli_plan_document_session_prompt_rejects_unknown PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-document-session-prompt\".*\"message\":\"unknown document session prompt kind\"")

    add_test(NAME pano_cli_plan_export_start_allowed_smoke
        COMMAND pano_cli plan-export-start --requires-license)
    set_tests_properties(pano_cli_plan_export_start_allowed_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-export-start\".*\"requiresLicense\":true.*\"licenseValid\":true.*\"hasCanvas\":true.*\"decision\":\"start-now\"")

    add_test(NAME pano_cli_plan_export_start_demo_blocked_smoke
        COMMAND pano_cli plan-export-start --requires-license --demo)
    set_tests_properties(pano_cli_plan_export_start_demo_blocked_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-export-start\".*\"requiresLicense\":true.*\"licenseValid\":false.*\"decision\":\"show-license-disabled\"")

    add_test(NAME pano_cli_plan_export_start_no_canvas_smoke
        COMMAND pano_cli plan-export-start --no-canvas)
    set_tests_properties(pano_cli_plan_export_start_no_canvas_smoke PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-export-start\".*\"requiresLicense\":false.*\"hasCanvas\":false.*\"decision\":\"unavailable-no-canvas\"")

    add_test(NAME pano_cli_plan_export_menu_png_smoke
        COMMAND pano_cli plan-export-menu --kind png)
    set_tests_properties(pano_cli_plan_export_menu_png_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-export-menu\".*\"kind\":\"png\".*\"action\":\"show-png-dialog\".*\"opensDialog\":true")

    add_test(NAME pano_cli_plan_export_menu_mp4_demo_blocked_smoke
        COMMAND pano_cli plan-export-menu --kind animation-mp4 --demo)
    set_tests_properties(pano_cli_plan_export_menu_mp4_demo_blocked_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-export-menu\".*\"kind\":\"animation-mp4\".*\"licenseValid\":false.*\"action\":\"show-license-disabled\".*\"opensDialog\":false")

    add_test(NAME pano_cli_plan_export_menu_no_canvas_smoke
        COMMAND pano_cli plan-export-menu --kind layers --no-canvas)
    set_tests_properties(pano_cli_plan_export_menu_no_canvas_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-export-menu\".*\"kind\":\"layers\".*\"hasCanvas\":false.*\"action\":\"unavailable-no-canvas\".*\"opensDialog\":false")

    add_test(NAME pano_cli_plan_export_menu_rejects_unknown
        COMMAND pano_cli plan-export-menu --kind unknown)
    set_tests_properties(pano_cli_plan_export_menu_rejects_unknown PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_export_target_file_smoke
        COMMAND pano_cli plan-export-target --kind file --work-dir D:/Paint --doc-name demo --extension .png)
    set_tests_properties(pano_cli_plan_export_target_file_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-export-target\".*\"kind\":\"file\".*\"path\":\"D:/Paint/demo.png\".*\"suggestedName\":\"demo.png\"")

    add_test(NAME pano_cli_plan_export_target_collection_smoke
        COMMAND pano_cli plan-export-target --kind collection --work-dir D:/Paint --doc-name demo --suffix _layers)
    set_tests_properties(pano_cli_plan_export_target_collection_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-export-target\".*\"kind\":\"collection\".*\"directory\":\"D:/Paint/demo_layers\".*\"stemPath\":\"D:/Paint/demo_layers/demo\"")

    add_test(NAME pano_cli_plan_export_target_name_smoke
        COMMAND pano_cli plan-export-target --kind name --doc-name demo --suffix -timelapse)
    set_tests_properties(pano_cli_plan_export_target_name_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-export-target\".*\"kind\":\"name\".*\"suggestedName\":\"demo-timelapse\"")

    add_test(NAME pano_cli_plan_export_message_equirect_work_smoke
        COMMAND pano_cli plan-export-message --kind equirectangular --destination work --detail D:/Paint)
    set_tests_properties(pano_cli_plan_export_message_equirect_work_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-export-message\".*\"kind\":\"equirectangular\".*\"destination\":\"work-directory\".*\"showDialog\":true.*\"title\":\"Export Equirectangular\".*\"message\":\"Image exported to D:/Paint\"")

    add_test(NAME pano_cli_plan_export_message_layers_files_smoke
        COMMAND pano_cli plan-export-message --kind layers --destination files)
    set_tests_properties(pano_cli_plan_export_message_layers_files_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-export-message\".*\"kind\":\"layers\".*\"destination\":\"files-panopainter\".*\"showDialog\":true.*\"message\":\"Image layers exported to Files/PanoPainter\"")

    add_test(NAME pano_cli_plan_export_message_timelapse_success_smoke
        COMMAND pano_cli plan-export-message --kind timelapse --destination success)
    set_tests_properties(pano_cli_plan_export_message_timelapse_success_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-export-message\".*\"kind\":\"timelapse\".*\"destination\":\"generic-success\".*\"showDialog\":true.*\"message\":\"Timelapse exported successfully\\.\"")

    add_test(NAME pano_cli_plan_export_message_suppressed_smoke
        COMMAND pano_cli plan-export-message --kind depth --destination suppressed)
    set_tests_properties(pano_cli_plan_export_message_suppressed_smoke PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-export-message\".*\"kind\":\"depth\".*\"destination\":\"suppressed\".*\"showDialog\":false.*\"title\":\"\".*\"message\":\"\"")

    add_test(NAME pano_cli_plan_export_message_rejects_unknown
        COMMAND pano_cli plan-export-message --kind nope)
    set_tests_properties(pano_cli_plan_export_message_rejects_unknown PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-export-message\".*\"message\":\"unknown export message kind\"")

    add_test(NAME pano_cli_plan_export_report_failure_smoke
        COMMAND pano_cli plan-export-report --kind animation-mp4 --message "video export path must not be empty")
    set_tests_properties(pano_cli_plan_export_report_failure_smoke PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-export-report\".*\"kind\":\"animation-mp4\".*\"title\":\"Export Animation\".*\"message\":\"video export path must not be empty\".*\"showCancel\":false")

    add_test(NAME pano_cli_plan_export_report_license_smoke
        COMMAND pano_cli plan-export-report --kind license-disabled)
    set_tests_properties(pano_cli_plan_export_report_license_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-export-report\".*\"kind\":\"license-disabled\".*\"title\":\"License\".*\"message\":\"This function is disabled in demo mode\\.\".*\"showCancel\":false")

    add_test(NAME pano_cli_plan_export_report_rejects_unknown
        COMMAND pano_cli plan-export-report --kind nope)
    set_tests_properties(pano_cli_plan_export_report_rejects_unknown PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-export-report\".*\"message\":\"unknown export message kind\"")

    add_test(NAME pano_cli_plan_cloud_upload_clean_smoke
        COMMAND pano_cli plan-cloud-upload)
    set_tests_properties(pano_cli_plan_cloud_upload_clean_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-cloud-upload\".*\"hasCanvas\":true.*\"newDocument\":false.*\"unsaved\":false.*\"decision\":\"prompt-publish\".*\"saveBeforeUpload\":false.*\"title\":\"Publish document\".*\"okCaption\":\"Yes\".*\"cancelCaption\":\"No\"")

    add_test(NAME pano_cli_plan_cloud_upload_unsaved_smoke
        COMMAND pano_cli plan-cloud-upload --unsaved)
    set_tests_properties(pano_cli_plan_cloud_upload_unsaved_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-cloud-upload\".*\"unsaved\":true.*\"decision\":\"prompt-publish\".*\"saveBeforeUpload\":true")

    add_test(NAME pano_cli_plan_cloud_upload_new_document_smoke
        COMMAND pano_cli plan-cloud-upload --new-document --unsaved)
    set_tests_properties(pano_cli_plan_cloud_upload_new_document_smoke PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-cloud-upload\".*\"newDocument\":true.*\"decision\":\"show-save-required-warning\".*\"saveBeforeUpload\":false.*\"title\":\"Warning\".*\"message\":\"This document needs to be saved before upload\\.\".*\"showCancel\":false")

    add_test(NAME pano_cli_plan_cloud_upload_no_canvas_smoke
        COMMAND pano_cli plan-cloud-upload --no-canvas --new-document --unsaved)
    set_tests_properties(pano_cli_plan_cloud_upload_no_canvas_smoke PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-cloud-upload\".*\"hasCanvas\":false.*\"decision\":\"unavailable-no-canvas\".*\"saveBeforeUpload\":false")

    add_test(NAME pano_cli_plan_cloud_browse_waiting_smoke
        COMMAND pano_cli plan-cloud-browse)
    set_tests_properties(pano_cli_plan_cloud_browse_waiting_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-cloud-browse\".*\"hasCanvas\":true.*\"selectedFile\":\"\".*\"browseDecision\":\"show-browser\".*\"selectionDecision\":\"wait-for-selection\"")

    add_test(NAME pano_cli_plan_cloud_browse_selected_smoke
        COMMAND pano_cli plan-cloud-browse --selected-file demo.ppi)
    set_tests_properties(pano_cli_plan_cloud_browse_selected_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-cloud-browse\".*\"hasCanvas\":true.*\"selectedFile\":\"demo.ppi\".*\"browseDecision\":\"show-browser\".*\"selectionDecision\":\"start-download\"")

    add_test(NAME pano_cli_plan_cloud_browse_no_canvas_smoke
        COMMAND pano_cli plan-cloud-browse --no-canvas --selected-file demo.ppi)
    set_tests_properties(pano_cli_plan_cloud_browse_no_canvas_smoke PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-cloud-browse\".*\"hasCanvas\":false.*\"browseDecision\":\"unavailable-no-canvas\".*\"selectionDecision\":\"start-download\"")

    add_test(NAME pano_cli_plan_cloud_upload_all_progress_smoke
        COMMAND pano_cli plan-cloud-upload-all --file-count 3)
    set_tests_properties(pano_cli_plan_cloud_upload_all_progress_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-cloud-upload-all\".*\"fileCount\":3.*\"progressUiAvailable\":true.*\"progressTotal\":3.*\"showProgress\":true.*\"progressDialog\":\\{\"title\":\"Export Pano Image\".*\"total\":3")

    add_test(NAME pano_cli_plan_cloud_upload_all_headless_smoke
        COMMAND pano_cli plan-cloud-upload-all --file-count 3 --no-progress-ui)
    set_tests_properties(pano_cli_plan_cloud_upload_all_headless_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-cloud-upload-all\".*\"fileCount\":3.*\"progressUiAvailable\":false.*\"progressTotal\":3.*\"showProgress\":false")

    add_test(NAME pano_cli_plan_cloud_transfer_download_smoke
        COMMAND pano_cli plan-cloud-transfer --direction download --progress --disable-tls-verification --progress-total 100 --progress-current 25)
    set_tests_properties(pano_cli_plan_cloud_transfer_download_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-cloud-transfer\".*\"direction\":\"download\".*\"action\":\"start-transfer\".*\"enableProgress\":true.*\"disableTlsVerification\":true.*\"notify\":true.*\"fraction\":0.25.*\"progressPrompt\":\\{\"title\":\"Downloading\".*\"formattedMessage\":\"Download in progress 25.00%\"")

    add_test(NAME pano_cli_plan_cloud_transfer_upload_smoke
        COMMAND pano_cli plan-cloud-transfer --direction upload --source D:/Paint/demo.ppi --progress-total 10 --progress-current 20)
    set_tests_properties(pano_cli_plan_cloud_transfer_upload_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-cloud-transfer\".*\"direction\":\"upload\".*\"action\":\"start-transfer\".*\"enableProgress\":false.*\"notify\":true.*\"fraction\":1")

    add_test(NAME pano_cli_plan_cloud_transfer_rejects_missing_destination
        COMMAND pano_cli plan-cloud-transfer --direction download --destination "")
    set_tests_properties(pano_cli_plan_cloud_transfer_rejects_missing_destination PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-cloud-transfer\".*\"action\":\"reject-missing-destination\".*\"enableProgress\":false")

    add_test(NAME pano_cli_plan_cloud_transfer_zero_total_smoke
        COMMAND pano_cli plan-cloud-transfer --progress --progress-total 0 --progress-current 10)
    set_tests_properties(pano_cli_plan_cloud_transfer_zero_total_smoke PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-cloud-transfer\".*\"action\":\"start-transfer\".*\"notify\":false.*\"fraction\":0")

    add_test(NAME pano_cli_plan_app_dialog_progress_smoke
        COMMAND pano_cli plan-app-dialog --kind progress --title Saving --total -4)
    set_tests_properties(pano_cli_plan_app_dialog_progress_smoke PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-dialog\".*\"kind\":\"progress\".*\"title\":\"Saving\".*\"total\":0.*\"count\":0.*\"progressFraction\":0")

    add_test(NAME pano_cli_plan_app_dialog_message_smoke
        COMMAND pano_cli plan-app-dialog --kind message --title Import --message Brushes --cancel)
    set_tests_properties(pano_cli_plan_app_dialog_message_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-dialog\".*\"kind\":\"message\".*\"title\":\"Import\".*\"message\":\"Brushes\".*\"okCaption\":\"Ok\".*\"showCancel\":true")

    add_test(NAME pano_cli_plan_app_dialog_input_smoke
        COMMAND pano_cli plan-app-dialog --kind input --title Rename --field-name Layer --ok-caption Save)
    set_tests_properties(pano_cli_plan_app_dialog_input_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-dialog\".*\"kind\":\"input\".*\"title\":\"Rename\".*\"fieldName\":\"Layer\".*\"okCaption\":\"Save")

    add_test(NAME pano_cli_plan_app_dialog_rejects_empty_ok_caption
        COMMAND pano_cli plan-app-dialog --kind input --ok-caption "")
    set_tests_properties(pano_cli_plan_app_dialog_rejects_empty_ok_caption PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-dialog\".*\"message\":\"input dialog ok caption")

    add_test(NAME pano_cli_plan_recording_session_stopped_smoke
        COMMAND pano_cli plan-recording-session --frame-count 12)
    set_tests_properties(pano_cli_plan_recording_session_stopped_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-recording-session\".*\"running\":false.*\"frameCount\":12.*\"startDecision\":\"start-thread\".*\"stopDecision\":\"no-op-not-running\".*\"stopRunningRecording\":false.*\"deleteRecordedFiles\":false.*\"progressTotal\":12.*\"progressDialog\":\\{\"title\":\"Exporting MP4 movie\",\"total\":12,\"count\":0,\"progressFraction\":0")

    add_test(NAME pano_cli_plan_recording_session_running_smoke
        COMMAND pano_cli plan-recording-session --running --frame-count 12)
    set_tests_properties(pano_cli_plan_recording_session_running_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-recording-session\".*\"running\":true.*\"startDecision\":\"no-op-already-running\".*\"stopDecision\":\"stop-thread\".*\"stopRunningRecording\":true.*\"progressTotal\":12.*\"worker\":\\{\"continueRunning\":true,\"encodeFrame\":true,\"clearDirtyStroke\":true,\"updateFrameLabel\":true\\}")

    add_test(NAME pano_cli_plan_recording_session_platform_cleanup_smoke
        COMMAND pano_cli plan-recording-session --platform-deletes-recorded-files)
    set_tests_properties(pano_cli_plan_recording_session_platform_cleanup_smoke PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-recording-session\".*\"platformDeletesRecordedFiles\":true.*\"deleteRecordedFiles\":true.*\"frameCountAfterClear\":0")

    add_test(NAME pano_cli_plan_recording_session_missing_encoder_smoke
        COMMAND pano_cli plan-recording-session --running --no-encoder)
    set_tests_properties(pano_cli_plan_recording_session_missing_encoder_smoke PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-recording-session\".*\"running\":true.*\"encoderAvailable\":false.*\"worker\":\\{\"continueRunning\":true,\"encodeFrame\":false,\"clearDirtyStroke\":false,\"updateFrameLabel\":false\\}")

    add_test(NAME pano_cli_plan_app_preferences_smoke
        COMMAND pano_cli plan-app-preferences
            --ui-scale 1.5
            --display-density 2
            --current-scale 1.6
            --scale-option 0.75
            --scale-option 1
            --scale-option 1.5
            --viewport-scale 0.5
            --rtl
            --cursor-mode 2)
    set_tests_properties(pano_cli_plan_app_preferences_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-preferences\".*\"fontScale\":3.*\"scaleSelection\":\\{\"hasSelection\":true,\"index\":2\\}.*\"viewportScale\":\\{\"scale\":0.5\\}.*\"direction\":\"right-to-left\".*\"recordingAction\":\"start-recording\".*\"vrControllers\":\\{\"enabled\":true\\}.*\"cursor\":\\{\"mode\":2\\}")

    add_test(NAME pano_cli_plan_app_preferences_stops_timelapse_smoke
        COMMAND pano_cli plan-app-preferences
            --current-scale 0.5
            --scale-option 1
            --timelapse-disabled
            --recording-running
            --vr-controllers-disabled)
    set_tests_properties(pano_cli_plan_app_preferences_stops_timelapse_smoke PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-preferences\".*\"scaleSelection\":\\{\"hasSelection\":false,\"index\":0\\}.*\"direction\":\"left-to-right\".*\"timelapse\":\\{\"enabled\":false,\"recordingAction\":\"stop-recording\"\\}.*\"vrControllers\":\\{\"enabled\":false\\}")

    add_test(NAME pano_cli_plan_app_startup_smoke
        COMMAND pano_cli plan-app-startup
            --run-counter 7
            --vr-controllers-disabled
            --license-invalid)
    set_tests_properties(pano_cli_plan_app_startup_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-startup\".*\"runCounter\":7.*\"licenseValid\":false.*\"previousRunCounter\":7.*\"nextRunCounter\":8.*\"savePreferences\":true.*\"startTimelapse\":true.*\"vrControllersEnabled\":false.*\"showLicenseWarning\":true")

    add_test(NAME pano_cli_plan_app_startup_rejects_negative_counter
        COMMAND pano_cli plan-app-startup --run-counter -1)
    set_tests_properties(pano_cli_plan_app_startup_rejects_negative_counter PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-startup\".*\"message\":\"run counter must not be negative\"")

    add_test(NAME pano_cli_plan_app_startup_resources_smoke
        COMMAND pano_cli plan-app-startup-resources --width 1280 --height 720)
    set_tests_properties(pano_cli_plan_app_startup_resources_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-startup-resources\".*\"uiRenderTargetWidth\":1280.*\"uiRenderTargetHeight\":720.*\"initializeShaders\":true.*\"initializeAssets\":true.*\"initializeLayout\":true.*\"updateTitle\":true.*\"createUiRenderTarget\":true")

    add_test(NAME pano_cli_plan_app_startup_resources_rejects_bad_size
        COMMAND pano_cli plan-app-startup-resources --bad-size)
    set_tests_properties(pano_cli_plan_app_startup_resources_rejects_bad_size PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-startup-resources\".*\"message\":\"startup resource dimensions")

    add_test(NAME pano_cli_plan_app_frame_vr_smoke
        COMMAND pano_cli plan-app-frame --redraw --vr-active)
    set_tests_properties(pano_cli_plan_app_frame_vr_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-frame\".*\"surface\":\\{\"width\":960,\"height\":540\\}.*\"updateFrame\":true.*\"updateLayouts\":true.*\"refreshCanvasToolbar\":true.*\"drawCanvasStroke\":true.*\"drawVrUi\":true.*\"drawMainUi\":true.*\"resetRedraw\":true")

    add_test(NAME pano_cli_plan_app_frame_idle_missing_canvas_smoke
        COMMAND pano_cli plan-app-frame --no-canvas --ui-hidden --vr-only --no-designer-layout)
    set_tests_properties(pano_cli_plan_app_frame_idle_missing_canvas_smoke PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-frame\".*\"updateFrame\":false.*\"tickDesignerLayout\":false.*\"tickMainLayout\":true.*\"drawCanvasStroke\":false.*\"drawVrUi\":false.*\"drawMainUi\":false.*\"resetRedraw\":true")

    add_test(NAME pano_cli_plan_app_frame_resize_smoke
        COMMAND pano_cli plan-app-frame --resize-width 1024.9 --resize-height 512.1)
    set_tests_properties(pano_cli_plan_app_frame_resize_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-frame\".*\"resize\":\\{\"width\":1024.9,\"height\":512.1,\"renderTargetWidth\":1024,\"renderTargetHeight\":512,\"recreateUiRenderTarget\":true,\"requestRedraw\":true\\}")

    add_test(NAME pano_cli_plan_app_frame_rejects_bad_resize
        COMMAND pano_cli plan-app-frame --bad-resize)
    set_tests_properties(pano_cli_plan_app_frame_rejects_bad_resize PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-frame\".*\"message\":\"resize dimensions")

    add_test(NAME pano_cli_plan_app_frame_observer_smoke
        COMMAND pano_cli plan-app-frame)
    set_tests_properties(pano_cli_plan_app_frame_observer_smoke PROPERTIES
        LABELS "app;ui;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-frame\".*\"observer\":\\{\"drawNode\":true,\"notifyEnterScreen\":true,\"notifyLeaveScreen\":false,\"nextOnScreen\":true,\"visibleWidth\":65,\"visibleHeight\":35,\"scissorX\":28,\"scissorY\":433,\"scissorWidth\":134,\"scissorHeight\":74\\}")

    add_test(NAME pano_cli_plan_app_frame_observer_clipped_smoke
        COMMAND pano_cli plan-app-frame --observer-on-screen --observer-clipped-out)
    set_tests_properties(pano_cli_plan_app_frame_observer_clipped_smoke PROPERTIES
        LABELS "app;ui;integration;desktop-fast;fuzz"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-frame\".*\"observer\":\\{\"drawNode\":false,\"notifyEnterScreen\":false,\"notifyLeaveScreen\":true,\"nextOnScreen\":false")

    add_test(NAME pano_cli_plan_app_frame_rejects_bad_observer
        COMMAND pano_cli plan-app-frame --observer-bad-geometry)
    set_tests_properties(pano_cli_plan_app_frame_rejects_bad_observer PROPERTIES
        LABELS "app;ui;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-frame\".*\"message\":\"UI observer geometry")

    add_test(NAME pano_cli_plan_app_thread_dispatch_smoke
        COMMAND pano_cli plan-app-thread --kind dispatch --unique --queued-tasks 2 --wait)
    set_tests_properties(pano_cli_plan_app_thread_dispatch_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-thread\".*\"kind\":\"dispatch\".*\"queueTask\":true.*\"removeMatchingUniqueTask\":true.*\"notifyWorker\":true.*\"waitForCompletion\":true")

    add_test(NAME pano_cli_plan_app_thread_ui_loop_smoke
        COMMAND pano_cli plan-app-thread --kind ui-loop --dt 0.25 --frame-accumulator 0.5 --fps-accumulator 0.9 --reload-accumulator 0.9 --rendered-frames 7 --live-reload)
    set_tests_properties(pano_cli_plan_app_thread_ui_loop_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-thread\".*\"kind\":\"ui-loop\".*\"frameAccumulator\":0.75.*\"fpsAccumulator\":0.*\"reportRenderedFrames\":true.*\"reportedFrameCount\":7.*\"checkLiveAssetReload\":true")

    add_test(NAME pano_cli_plan_app_thread_stop_smoke
        COMMAND pano_cli plan-app-thread --kind stop --not-joinable)
    set_tests_properties(pano_cli_plan_app_thread_stop_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-thread\".*\"kind\":\"stop\".*\"markNotRunning\":true.*\"notifyWorker\":true.*\"joinThread\":false")

    add_test(NAME pano_cli_plan_app_thread_rejects_bad_timer
        COMMAND pano_cli plan-app-thread --kind ui-loop --bad-timer)
    set_tests_properties(pano_cli_plan_app_thread_rejects_bad_timer PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-thread\".*\"message\":\"UI loop timer values")

    add_test(NAME pano_cli_plan_app_input_pointer_smoke
        COMMAND pano_cli plan-app-input --kind pointer --x 100 --y 50 --zoom 2)
    set_tests_properties(pano_cli_plan_app_input_pointer_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-input\".*\"kind\":\"pointer\".*\"dispatchDesignerFirst\":true.*\"dispatchMainIfNotConsumed\":true.*\"normalizedX\":50.*\"normalizedY\":25")

    add_test(NAME pano_cli_plan_app_input_gesture_smoke
        COMMAND pano_cli plan-app-input --kind gesture --x 0 --y 0 --x1 6 --y1 8 --prev-x 0 --prev-y 0 --prev-x1 3 --prev-y1 4 --zoom 2)
    set_tests_properties(pano_cli_plan_app_input_gesture_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-input\".*\"kind\":\"gesture\".*\"dispatchMain\":true.*\"normalizedX\":1.5.*\"normalizedY\":2.*\"distance\":10.*\"distanceDelta\":5")

    add_test(NAME pano_cli_plan_app_input_key_vr_smoke
        COMMAND pano_cli plan-app-input --kind key --spacebar --vr-active)
    set_tests_properties(pano_cli_plan_app_input_key_vr_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-input\".*\"kind\":\"key\".*\"dispatchMain\":true.*\"setKeyDown\":true.*\"syncVrCameraRotation\":true")

    add_test(NAME pano_cli_plan_app_input_ui_toggle_smoke
        COMMAND pano_cli plan-app-input --kind ui-toggle --panel-child-count 4)
    set_tests_properties(pano_cli_plan_app_input_ui_toggle_smoke PROPERTIES
        LABELS "app;ui;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-input\".*\"kind\":\"ui-toggle\".*\"nextUiVisible\":false.*\"firstPanelChildIndex\":1.*\"panelChildCount\":4")

    add_test(NAME pano_cli_plan_app_input_stylus_smoke
        COMMAND pano_cli plan-app-input --kind stylus --no-canvas)
    set_tests_properties(pano_cli_plan_app_input_stylus_smoke PROPERTIES
        LABELS "app;ui;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-input\".*\"kind\":\"stylus\".*\"setHasStylus\":true.*\"enableCanvasTouchLock\":false")

    add_test(NAME pano_cli_plan_app_input_rejects_bad_float
        COMMAND pano_cli plan-app-input --kind pointer --bad-float)
    set_tests_properties(pano_cli_plan_app_input_rejects_bad_float PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-input\".*\"message\":\"input zoom must be finite and positive\"")

    add_test(NAME pano_cli_plan_app_input_rejects_missing_ui_panel
        COMMAND pano_cli plan-app-input --kind ui-toggle --main-child-count 1)
    set_tests_properties(pano_cli_plan_app_input_rejects_missing_ui_panel PROPERTIES
        LABELS "app;ui;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-input\".*\"message\":\"UI toggle requires a panel container child\"")

    add_test(NAME pano_cli_plan_app_shutdown_smoke
        COMMAND pano_cli plan-app-shutdown)
    set_tests_properties(pano_cli_plan_app_shutdown_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-shutdown\".*\"saveUiState\":true.*\"terminateStrokePreviewRenderer\":true.*\"stopRecording\":true.*\"invalidateTextures\":true.*\"invalidateShaders\":true.*\"unloadLayouts\":true.*\"destroyUiRenderTarget\":true.*\"destroyFacePlane\":true.*\"releasePanelNodes\":true.*\"clearQuickModeState\":true")

    add_test(NAME pano_cli_plan_app_shutdown_rejects_unknown_option
        COMMAND pano_cli plan-app-shutdown --unexpected)
    set_tests_properties(pano_cli_plan_app_shutdown_rejects_unknown_option PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-shutdown\".*\"message\":\"unknown option\"")

    add_test(NAME pano_cli_plan_command_convert_smoke
        COMMAND pano_cli plan-command-convert --project D:/Paint/demo.ppi --output D:/Paint/demo.png --canvas-resolution 2048)
    set_tests_properties(pano_cli_plan_command_convert_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-command-convert\".*\"project\":\"D:/Paint/demo.ppi\".*\"output\":\"D:/Paint/demo.png\".*\"canvasResolution\":2048.*\"steps\":\\[\"apply-renderer-state\",\"create-canvas\",\"open-project\",\"export-equirectangular\"\\]")

    add_test(NAME pano_cli_plan_command_convert_rejects_empty_project
        COMMAND pano_cli plan-command-convert --project "" --output D:/Paint/demo.png)
    set_tests_properties(pano_cli_plan_command_convert_rejects_empty_project PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-command-convert\".*\"message\":\"convert project path must not be empty\"")

    add_test(NAME pano_cli_plan_command_convert_rejects_bad_resolution
        COMMAND pano_cli plan-command-convert --canvas-resolution 0)
    set_tests_properties(pano_cli_plan_command_convert_rejects_bad_resolution PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-command-convert\".*\"message\":\"convert canvas resolution must be positive\"")

    add_test(NAME pano_cli_plan_brush_package_import_ppbr_smoke
        COMMAND pano_cli plan-brush-package-import
            --kind ppbr
            --path D:/Paint/Brushes/clouds.ppbr)
    set_tests_properties(pano_cli_plan_brush_package_import_ppbr_smoke PROPERTIES
        LABELS "app;paint;assets;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-brush-package-import\".*\"kind\":\"ppbr\".*\"path\":\"D:/Paint/Brushes/clouds.ppbr\".*\"dispatches\":1")

    add_test(NAME pano_cli_plan_brush_package_import_abr_smoke
        COMMAND pano_cli plan-brush-package-import
            --kind abr
            --path D:/Paint/Brushes/clouds.abr)
    set_tests_properties(pano_cli_plan_brush_package_import_abr_smoke PROPERTIES
        LABELS "app;paint;assets;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-brush-package-import\".*\"kind\":\"abr\".*\"path\":\"D:/Paint/Brushes/clouds.abr\".*\"dispatches\":1")

    add_test(NAME pano_cli_plan_brush_package_import_rejects_empty_path
        COMMAND "${CMAKE_COMMAND}"
            -DPANO_CLI=$<TARGET_FILE:pano_cli>
            "-DEXPECTED_OUTPUT=brush package import path must not be empty"
            -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/expect_pano_cli_plan_brush_package_import_failure.cmake")
    set_tests_properties(pano_cli_plan_brush_package_import_rejects_empty_path PROPERTIES
        LABELS "app;paint;assets;integration;desktop-fast;fuzz")

    add_test(NAME pano_cli_plan_brush_package_import_rejects_unknown_kind
        COMMAND "${CMAKE_COMMAND}"
            -DPANO_CLI=$<TARGET_FILE:pano_cli>
            -DEXPECT_UNKNOWN_KIND=ON
            "-DEXPECTED_OUTPUT=unknown brush package import kind"
            -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/expect_pano_cli_plan_brush_package_import_failure.cmake")
    set_tests_properties(pano_cli_plan_brush_package_import_rejects_unknown_kind PROPERTIES
        LABELS "app;paint;assets;integration;desktop-fast;fuzz")

    add_test(NAME pano_cli_plan_brush_package_export_smoke
        COMMAND pano_cli plan-brush-package-export
            --path D:/Paint/clouds.ppbr
            --author Artist
            --email artist@example.test
            --url https://example.test/brushes
            --description "Cloud brush set"
            --dest-path D:/Paint/BrushPreviews
            --export-data
            --header-image)
    set_tests_properties(pano_cli_plan_brush_package_export_smoke PROPERTIES
        LABELS "app;paint;assets;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-brush-package-export\".*\"path\":\"D:/Paint/clouds.ppbr\".*\"author\":\"Artist\".*\"destPath\":\"D:/Paint/BrushPreviews\".*\"exportData\":true.*\"hasHeaderImage\":true.*\"paths\":\\{\"package\":\"D:/Paint/clouds.ppbr\".*\"dataDirectory\":\"D:/Paint/BrushPreviews/clouds_data\".*\"dataDirectoryEnabled\":true.*\"dispatches\":1")

    add_test(NAME pano_cli_plan_brush_package_export_success_dialog_smoke
        COMMAND pano_cli plan-brush-package-export --path D:/Paint/clouds.ppbr)
    set_tests_properties(pano_cli_plan_brush_package_export_success_dialog_smoke PROPERTIES
        LABELS "app;paint;assets;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-brush-package-export\".*\"successDialog\":\\{\"title\":\"Export PPBR\",\"message\":\"Brushes exported to:\\\\nD:/Paint/clouds.ppbr\",\"showCancel\":false\\}")

    add_test(NAME pano_cli_plan_brush_package_export_rejects_empty_path
        COMMAND "${CMAKE_COMMAND}"
            -DPANO_CLI=$<TARGET_FILE:pano_cli>
            "-DEXPECTED_OUTPUT=brush package export path must not be empty"
            -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/expect_pano_cli_plan_brush_package_export_failure.cmake")
    set_tests_properties(pano_cli_plan_brush_package_export_rejects_empty_path PROPERTIES
        LABELS "app;paint;assets;integration;desktop-fast;fuzz")

    add_test(NAME pano_cli_plan_brush_package_export_rejects_path_without_directory
        COMMAND "${CMAKE_COMMAND}"
            -DPANO_CLI=$<TARGET_FILE:pano_cli>
            -DEXPECT_NO_DIRECTORY=ON
            "-DEXPECTED_OUTPUT=PPBR export path must include a directory and file name"
            -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/expect_pano_cli_plan_brush_package_export_failure.cmake")
    set_tests_properties(pano_cli_plan_brush_package_export_rejects_path_without_directory PROPERTIES
        LABELS "app;paint;assets;integration;desktop-fast;fuzz")

    add_test(NAME pano_cli_plan_brush_package_export_dest_without_data_smoke
        COMMAND pano_cli plan-brush-package-export
            --path D:/Paint/clouds.ppbr
            --dest-path D:/Paint/BrushPreviews
            --no-export-data)
    set_tests_properties(pano_cli_plan_brush_package_export_dest_without_data_smoke PROPERTIES
        LABELS "app;paint;assets;integration;desktop-fast;fuzz"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-brush-package-export\".*\"destPath\":\"D:/Paint/BrushPreviews\".*\"exportData\":false.*\"dataDirectory\":\"D:/Paint/BrushPreviews/clouds_data\".*\"dataDirectoryEnabled\":false.*\"dispatches\":1")

    add_test(NAME pano_cli_plan_tools_menu_shortcuts_smoke
        COMMAND pano_cli plan-tools-menu --command shortcuts)
    set_tests_properties(pano_cli_plan_tools_menu_shortcuts_smoke PROPERTIES
        LABELS "app;ui;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-tools-menu\".*\"command\":\"shortcuts\".*\"action\":\"show-shortcuts-dialog\".*\"closesRootPopup\":true")

    add_test(NAME pano_cli_plan_tools_menu_sonarpen_unavailable_smoke
        COMMAND pano_cli plan-tools-menu --command sonarpen)
    set_tests_properties(pano_cli_plan_tools_menu_sonarpen_unavailable_smoke PROPERTIES
        LABELS "app;ui;integration;desktop-fast;fuzz"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-tools-menu\".*\"sonarpenAvailable\":false.*\"action\":\"no-op-unavailable\".*\"closesRootPopup\":false")

    add_test(NAME pano_cli_plan_tools_panel_layers_smoke
        COMMAND pano_cli plan-tools-panel --panel layers)
    set_tests_properties(pano_cli_plan_tools_panel_layers_smoke PROPERTIES
        LABELS "app;ui;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-tools-panel\".*\"panel\":\"layers\".*\"action\":\"open-floating-panel\".*\"title\":\"Layers\".*\"height\":300.*\"minHeight\":100.*\"hidesEmbeddedTitle\":true")

    add_test(NAME pano_cli_plan_tools_panel_visible_noop_smoke
        COMMAND pano_cli plan-tools-panel --panel animation --already-visible)
    set_tests_properties(pano_cli_plan_tools_panel_visible_noop_smoke PROPERTIES
        LABELS "app;ui;integration;desktop-fast;fuzz"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-tools-panel\".*\"alreadyVisible\":true.*\"action\":\"no-op-already-visible\".*\"title\":\"Animation\".*\"droppable\":false")

    add_test(NAME pano_cli_plan_tools_panel_rejects_unknown
        COMMAND pano_cli plan-tools-panel --panel missing)
    set_tests_properties(pano_cli_plan_tools_panel_rejects_unknown PROPERTIES
        LABELS "app;ui;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_about_menu_news_smoke
        COMMAND pano_cli plan-about-menu --command news --version-major 2 --version-minor 5 --version-fix 7)
    set_tests_properties(pano_cli_plan_about_menu_news_smoke PROPERTIES
        LABELS "app;ui;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-about-menu\".*\"command\":\"news\".*\"versionMajor\":2.*\"action\":\"show-whats-new-dialog\".*\"label\":\"What's new in 2.5.7\\?\".*\"closesRootPopup\":true")

    add_test(NAME pano_cli_plan_about_menu_performance_no_canvas_smoke
        COMMAND pano_cli plan-about-menu --command performance --no-canvas)
    set_tests_properties(pano_cli_plan_about_menu_performance_no_canvas_smoke PROPERTIES
        LABELS "app;ui;integration;desktop-fast;fuzz"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-about-menu\".*\"hasCanvas\":false.*\"action\":\"no-op-unavailable\".*\"label\":\"Performance test \\(No canvas\\)\".*\"closesRootPopup\":false.*\"requiresCanvas\":true")

    add_test(NAME pano_cli_plan_about_menu_crash_disabled_smoke
        COMMAND pano_cli plan-about-menu --command crash --no-diagnostics)
    set_tests_properties(pano_cli_plan_about_menu_crash_disabled_smoke PROPERTIES
        LABELS "app;ui;integration;desktop-fast;fuzz"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-about-menu\".*\"diagnosticsAvailable\":false.*\"action\":\"no-op-unavailable\".*\"closesRootPopup\":false")

    add_test(NAME pano_cli_plan_about_menu_rejects_unknown
        COMMAND pano_cli plan-about-menu --command missing)
    set_tests_properties(pano_cli_plan_about_menu_rejects_unknown PROPERTIES
        LABELS "app;ui;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_app_status_smoke
        COMMAND pano_cli plan-app-status
            --doc-name demo
            --unsaved
            --resolution 2048
            --resolution-index 3
            --zoom 1.26
            --history-bytes 1572864
            --recording-running
            --encoder-available
            --encoded-frames 12
            --framebuffer-fetch
            --float32
            --float32-linear
            --float16)
    set_tests_properties(pano_cli_plan_app_status_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-status\".*\"title\":\"Panodoc: demo\\* \\(8K\\)\".*\"dpi\":\"1.3x-dpi\".*\"memory\":\"History memory: 1.50 Mb\".*\"recording\":\\{\"visible\":true,\"text\":\"Recorded 12 frames\"\\}.*\"rendererDiagnostics\":\\{\"framebufferFetch\":\\{\"supported\":true,\"label\":\"FBF\"\\},\"floatingPointTargets\":\\{\"supported\":true,\"label\":\"F32L\"\\}\\}.*\"fromIndexValid\":true.*\"fromIndex\":2048.*\"toIndexValid\":true.*\"toIndex\":3.*\"labelValid\":true.*\"label\":\"8K\"")

    add_test(NAME pano_cli_plan_app_status_unknown_resolution_smoke
        COMMAND pano_cli plan-app-status --doc-name demo --resolution 1234 --resolution-index 9 --recording-running)
    set_tests_properties(pano_cli_plan_app_status_unknown_resolution_smoke PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-status\".*\"title\":\"Panodoc: demo \\(unknown\\)\".*\"recording\":\\{\"visible\":false,\"text\":\"\"\\}.*\"rendererDiagnostics\":\\{\"framebufferFetch\":\\{\"supported\":false,\"label\":\"FBF\"\\},\"floatingPointTargets\":\\{\"supported\":false,\"label\":\"\"\\}\\}.*\"fromIndexValid\":false.*\"toIndexValid\":false.*\"labelValid\":false.*\"label\":\"\"")

    add_test(NAME pano_cli_plan_document_resize_smoke
        COMMAND pano_cli plan-document-resize --current-resolution 2048 --selected-resolution-index 4)
    set_tests_properties(pano_cli_plan_document_resize_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-document-resize\".*\"currentResolutionText\":\"Current: 8K\".*\"currentResolutionIndex\":3.*\"selectedResolutionIndex\":4.*\"resolution\":4096.*\"width\":4096.*\"height\":4096.*\"clearsHistory\":true")

    add_test(NAME pano_cli_plan_document_resize_rejects_invalid_selection
        COMMAND pano_cli plan-document-resize --current-resolution 2048 --selected-resolution-index 9)
    set_tests_properties(pano_cli_plan_document_resize_rejects_invalid_selection PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_canvas_clear_smoke
        COMMAND pano_cli plan-canvas-clear --r 0 --g 0.1 --b 0.2 --a 0.3)
    set_tests_properties(pano_cli_plan_canvas_clear_smoke PROPERTIES
        LABELS "app;document;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-canvas-clear\".*\"r\":0.*\"g\":0.1.*\"b\":0.2.*\"a\":0.3.*\"clearsCanvas\":true.*\"recordsUndo\":true.*\"marksUnsaved\":true")

    add_test(NAME pano_cli_plan_canvas_clear_no_canvas_smoke
        COMMAND pano_cli plan-canvas-clear --no-canvas)
    set_tests_properties(pano_cli_plan_canvas_clear_no_canvas_smoke PROPERTIES
        LABELS "app;document;integration;desktop-fast;fuzz"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-canvas-clear\".*\"hasCanvas\":false.*\"clearsCanvas\":false.*\"recordsUndo\":false.*\"marksUnsaved\":false.*\"noOp\":true")

    add_test(NAME pano_cli_plan_canvas_clear_rejects_bad_color
        COMMAND pano_cli plan-canvas-clear --r 1.5)
    set_tests_properties(pano_cli_plan_canvas_clear_rejects_bad_color PROPERTIES
        LABELS "app;document;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_canvas_document_snapshot_smoke
        COMMAND pano_cli plan-canvas-document-snapshot --width 128 --height 64 --layers 3 --frames 2 --current-layer 2 --current-frame 1 --hidden-layer 0 --alpha-locked-layer 2 --opacity 0.5 --blend-mode 4 --pending-face-payloads-per-layer 6)
    set_tests_properties(pano_cli_plan_canvas_document_snapshot_smoke PROPERTIES
        LABELS "app;document;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-canvas-document-snapshot\".*\"width\":128.*\"height\":64.*\"layers\":3.*\"frames\":2.*\"activeLayer\":2.*\"activeFrame\":1.*\"activeLayerName\":\"Layer 3\".*\"activeLayerOpacity\":0.5.*\"activeLayerBlend\":\"overlay\".*\"activeLayerAlphaLocked\":true.*\"pendingFacePayloads\":18.*\"metadataOnly\":true.*\"requiresRendererPayloadReadback\":true.*\"documentFacePayloads\":0.*\"saveReport\":\\{\"payloadComplete\":false,\"canExportPpi\":false\\}")

    add_test(NAME pano_cli_plan_canvas_document_snapshot_payload_smoke
        COMMAND pano_cli plan-canvas-document-snapshot --width 128 --height 64 --layers 2 --frames 2 --current-layer 1 --current-frame 1 --pending-face-payloads-per-layer 2 --captured-face-payloads-per-layer 2)
    set_tests_properties(pano_cli_plan_canvas_document_snapshot_payload_smoke PROPERTIES
        LABELS "app;document;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-canvas-document-snapshot\".*\"layers\":2.*\"frames\":2.*\"activeLayer\":1.*\"activeFrame\":1.*\"pendingFacePayloads\":4.*\"capturedFacePayloads\":4.*\"metadataOnly\":false.*\"requiresRendererPayloadReadback\":false.*\"documentFacePayloads\":4.*\"saveReport\":\\{\"payloadComplete\":true,\"canExportPpi\":true\\}")

    add_test(NAME pano_cli_plan_canvas_document_snapshot_no_canvas
        COMMAND pano_cli plan-canvas-document-snapshot --no-canvas)
    set_tests_properties(pano_cli_plan_canvas_document_snapshot_no_canvas PROPERTIES
        LABELS "app;document;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_image_import_wide_equirect_smoke
        COMMAND pano_cli plan-image-import --width 4096 --height 2048)
    set_tests_properties(pano_cli_plan_image_import_wide_equirect_smoke PROPERTIES
        LABELS "app;document;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-image-import\".*\"width\":4096.*\"height\":2048.*\"action\":\"import-equirectangular\".*\"importsEquirectangular\":true.*\"entersTransformMode\":false")

    add_test(NAME pano_cli_plan_image_import_transform_smoke
        COMMAND pano_cli plan-image-import --width 1024 --height 1024)
    set_tests_properties(pano_cli_plan_image_import_transform_smoke PROPERTIES
        LABELS "app;document;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-image-import\".*\"width\":1024.*\"height\":1024.*\"action\":\"place-transform\".*\"importsEquirectangular\":false.*\"entersTransformMode\":true")

    add_test(NAME pano_cli_plan_image_import_rejects_invalid_dimensions
        COMMAND pano_cli plan-image-import --width 0 --height 1024)
    set_tests_properties(pano_cli_plan_image_import_rejects_invalid_dimensions PROPERTIES
        LABELS "app;document;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_layer_rename_smoke
        COMMAND pano_cli plan-layer-rename --old-name Base --new-name Paint)
    set_tests_properties(pano_cli_plan_layer_rename_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-layer-rename\".*\"oldName\":\"Base\".*\"newName\":\"Paint\".*\"action\":\"rename-and-record-undo\"")

    add_test(NAME pano_cli_plan_layer_rename_no_op_smoke
        COMMAND pano_cli plan-layer-rename --old-name Ink --new-name Ink)
    set_tests_properties(pano_cli_plan_layer_rename_no_op_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-layer-rename\".*\"oldName\":\"Ink\".*\"newName\":\"Ink\".*\"action\":\"no-op-same-name\"")

    add_test(NAME pano_cli_plan_layer_rename_rejects_empty_name
        COMMAND pano_cli plan-layer-rename --old-name Ink --new-name "")
    set_tests_properties(pano_cli_plan_layer_rename_rejects_empty_name PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_layer_menu_merge_smoke
        COMMAND pano_cli plan-layer-menu --command merge --current-index 2 --current-name Ink --lower-name Paint)
    set_tests_properties(pano_cli_plan_layer_menu_merge_smoke PROPERTIES
        LABELS "app;document;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-layer-menu\".*\"command\":\"merge\".*\"action\":\"merge-with-lower-layer\".*\"label\":\"Merge with Paint\".*\"fromIndex\":2.*\"toIndex\":1")

    add_test(NAME pano_cli_plan_layer_menu_clear_smoke
        COMMAND pano_cli plan-layer-menu --command clear --current-index 1 --current-name Paint)
    set_tests_properties(pano_cli_plan_layer_menu_clear_smoke PROPERTIES
        LABELS "app;document;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-layer-menu\".*\"command\":\"clear\".*\"action\":\"clear-current-layer\".*\"label\":\"Clear Layer Paint\"")

    add_test(NAME pano_cli_plan_layer_menu_merge_animated_blocked_smoke
        COMMAND pano_cli plan-layer-menu --command merge --current-index 2 --current-name Ink --lower-name Paint --animation-duration 3)
    set_tests_properties(pano_cli_plan_layer_menu_merge_animated_blocked_smoke PROPERTIES
        LABELS "app;document;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-layer-menu\".*\"animationDuration\":3.*\"action\":\"show-merge-animated-not-supported\"")

    add_test(NAME pano_cli_plan_layer_menu_missing_selection_smoke
        COMMAND pano_cli plan-layer-menu --command rename --no-current-layer)
    set_tests_properties(pano_cli_plan_layer_menu_missing_selection_smoke PROPERTIES
        LABELS "app;document;integration;desktop-fast;fuzz"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-layer-menu\".*\"hasCurrentLayer\":false.*\"action\":\"no-op-select-layer\".*\"label\":\"Rename Layer \\(Select a layer\\)\"")

    add_test(NAME pano_cli_plan_layer_menu_rejects_bad_state
        COMMAND pano_cli plan-layer-menu --command merge --current-index -1)
    set_tests_properties(pano_cli_plan_layer_menu_rejects_bad_state PROPERTIES
        LABELS "app;document;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_layer_panel_view_smoke
        COMMAND pano_cli plan-layer-panel-view --layer-count 3 --current-index 1 --hidden-index 2 --locked-index 1 --current-opacity 0.25 --current-blend-mode 4)
    set_tests_properties(pano_cli_plan_layer_panel_view_smoke PROPERTIES
        LABELS "app;document;ui;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-layer-panel-view\".*\"layers\":3.*\"currentIndex\":1.*\"currentName\":\"Layer 1\".*\"currentOpacity\":0.25.*\"currentAlphaLocked\":true.*\"currentBlendMode\":4.*\"visibleLayers\":2.*\"lockedLayers\":1")

    add_test(NAME pano_cli_plan_layer_panel_view_rejects_bad_opacity
        COMMAND pano_cli plan-layer-panel-view --layer-count 2 --current-index 1 --current-opacity 1.5)
    set_tests_properties(pano_cli_plan_layer_panel_view_rejects_bad_opacity PROPERTIES
        LABELS "app;document;ui;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_layer_panel_view_rejects_bad_current
        COMMAND pano_cli plan-layer-panel-view --layer-count 2 --current-index 2)
    set_tests_properties(pano_cli_plan_layer_panel_view_rejects_bad_current PROPERTIES
        LABELS "app;document;ui;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_layer_merge_smoke
        COMMAND pano_cli plan-layer-merge --layer-count 3 --from-index 2 --to-index 1)
    set_tests_properties(pano_cli_plan_layer_merge_smoke PROPERTIES
        LABELS "app;document;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-layer-merge\".*\"layerCount\":3.*\"fromIndex\":2.*\"toIndex\":1.*\"createHistory\":true")

    add_test(NAME pano_cli_plan_layer_merge_animated_rejected
        COMMAND pano_cli plan-layer-merge --layer-count 3 --from-index 2 --to-index 1 --animation-duration 3)
    set_tests_properties(pano_cli_plan_layer_merge_animated_rejected PROPERTIES
        LABELS "app;document;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_layer_operation_add_smoke
        COMMAND pano_cli plan-layer-operation --kind add --layer-count 2 --index 1 --name Paint)
    set_tests_properties(pano_cli_plan_layer_operation_add_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-layer-operation\".*\"operation\":\"add\".*\"insertIndex\":1.*\"name\":\"Paint\".*\"marksUnsaved\":true.*\"reloadsAnimationLayers\":true")

    add_test(NAME pano_cli_plan_layer_operation_reorder_no_op_smoke
        COMMAND pano_cli plan-layer-operation --kind reorder --layer-count 3 --from-index 1 --to-index 1)
    set_tests_properties(pano_cli_plan_layer_operation_reorder_no_op_smoke PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-layer-operation\".*\"operation\":\"reorder\".*\"fromIndex\":1.*\"toIndex\":1.*\"mutatesDocument\":false.*\"marksUnsaved\":false")

    add_test(NAME pano_cli_plan_layer_operation_highlight_smoke
        COMMAND pano_cli plan-layer-operation --kind highlight --layer-count 2 --index 1 --enabled)
    set_tests_properties(pano_cli_plan_layer_operation_highlight_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-layer-operation\".*\"operation\":\"set-highlight\".*\"index\":1.*\"flag\":true.*\"mutatesDocument\":false.*\"updatesTitle\":false")

    add_test(NAME pano_cli_plan_layer_operation_rejects_bad_opacity
        COMMAND pano_cli plan-layer-operation --kind opacity --layer-count 2 --index 1 --opacity 1.5)
    set_tests_properties(pano_cli_plan_layer_operation_rejects_bad_opacity PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_animation_operation_add_smoke
        COMMAND pano_cli plan-animation-operation --kind add --frame-count 2 --current-frame 0)
    set_tests_properties(pano_cli_plan_animation_operation_add_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-animation-operation\".*\"operation\":\"add-frame\".*\"selectedFrame\":2.*\"mutatesDocument\":true.*\"updatesCanvasAnimation\":true.*\"marksUnsaved\":true")

    add_test(NAME pano_cli_plan_animation_operation_duration_floor_smoke
        COMMAND pano_cli plan-animation-operation --kind duration --frame-count 2 --selected-frame 1 --current-duration 1 --delta -1)
    set_tests_properties(pano_cli_plan_animation_operation_duration_floor_smoke PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-animation-operation\".*\"operation\":\"adjust-duration\".*\"selectedFrame\":1.*\"frameDuration\":1.*\"mutatesDocument\":false.*\"marksUnsaved\":false")

    add_test(NAME pano_cli_plan_animation_operation_next_wrap_smoke
        COMMAND pano_cli plan-animation-operation --kind next --total-duration 5 --current-frame 4)
    set_tests_properties(pano_cli_plan_animation_operation_next_wrap_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-animation-operation\".*\"operation\":\"goto-next\".*\"currentFrame\":4.*\"targetFrame\":0.*\"updatesCanvasAnimation\":true")

    add_test(NAME pano_cli_plan_animation_operation_select_smoke
        COMMAND pano_cli plan-animation-operation --kind select --frame-count 3 --selected-frame 1 --layer-index 2 --layer-id 42)
    set_tests_properties(pano_cli_plan_animation_operation_select_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-animation-operation\".*\"operation\":\"select-frame\".*\"selectedFrame\":1.*\"targetFrame\":1.*\"layerIndex\":2.*\"layerId\":42.*\"reloadsAnimationLayers\":false.*\"updatesCanvasAnimation\":true")

    add_test(NAME pano_cli_plan_animation_operation_playback_smoke
        COMMAND pano_cli plan-animation-operation --kind playback --total-duration 5 --current-frame 4 --offset 1)
    set_tests_properties(pano_cli_plan_animation_operation_playback_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-animation-operation\".*\"operation\":\"playback-step\".*\"currentFrame\":4.*\"targetFrame\":0.*\"reloadsAnimationLayers\":false.*\"updatesCanvasAnimation\":true")

    add_test(NAME pano_cli_plan_animation_operation_toggle_playback_start_smoke
        COMMAND pano_cli plan-animation-operation --kind toggle-playback)
    set_tests_properties(pano_cli_plan_animation_operation_toggle_playback_start_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-animation-operation\".*\"operation\":\"toggle-playback\".*\"playbackIdleMs\":10.*\"playbackWasActive\":false.*\"playbackActive\":true.*\"resetsPlaybackTimer\":true")

    add_test(NAME pano_cli_plan_animation_operation_toggle_playback_stop_smoke
        COMMAND pano_cli plan-animation-operation --kind toggle-playback --playing)
    set_tests_properties(pano_cli_plan_animation_operation_toggle_playback_stop_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-animation-operation\".*\"operation\":\"toggle-playback\".*\"playbackIdleMs\":100.*\"playbackWasActive\":true.*\"playbackActive\":false.*\"resetsPlaybackTimer\":false")

    add_test(NAME pano_cli_plan_animation_panel_action_next_smoke
        COMMAND pano_cli plan-animation-panel-action --action next --total-duration 5 --current-frame 4)
    set_tests_properties(pano_cli_plan_animation_panel_action_next_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-animation-panel-action\".*\"action\":\"next-frame\".*\"operation\":\"goto-next\".*\"targetFrame\":0")

    add_test(NAME pano_cli_plan_animation_panel_action_toggle_stop_smoke
        COMMAND pano_cli plan-animation-panel-action --action toggle-playback --playing)
    set_tests_properties(pano_cli_plan_animation_panel_action_toggle_stop_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-animation-panel-action\".*\"action\":\"toggle-playback\".*\"operation\":\"toggle-playback\".*\"playbackIdleMs\":100.*\"playbackWasActive\":true.*\"playbackActive\":false")

    add_test(NAME pano_cli_plan_animation_panel_action_rejects_bad_timeline
        COMMAND pano_cli plan-animation-panel-action --action next --total-duration 0 --current-frame 0)
    set_tests_properties(pano_cli_plan_animation_panel_action_rejects_bad_timeline PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_animation_panel_view_smoke
        COMMAND pano_cli plan-animation-panel-view --layer-count 2 --frame-count 3 --frame-duration 2 --total-duration 6 --current-layer 1 --current-frame 4 --selected-layer-id 10 --selected-frame 2 --onion-size 2 --hidden-layer 1)
    set_tests_properties(pano_cli_plan_animation_panel_view_smoke PROPERTIES
        LABELS "app;ui;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-animation-panel-view\".*\"layers\":2.*\"visibleLayers\":1.*\"selectedFrames\":1.*\"hasSelectedFrame\":true.*\"currentLayerId\":20.*\"firstLayerFrames\":3")

    add_test(NAME pano_cli_plan_animation_panel_view_allows_stale_selection
        COMMAND pano_cli plan-animation-panel-view --layer-count 1 --frame-count 1 --total-duration 1 --current-layer 0 --current-frame 0 --selected-layer-id 999 --selected-frame 42)
    set_tests_properties(pano_cli_plan_animation_panel_view_allows_stale_selection PROPERTIES
        LABELS "app;ui;integration;desktop-fast;fuzz"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-animation-panel-view\".*\"layers\":1.*\"selectedFrames\":0.*\"hasSelectedFrame\":false")

    add_test(NAME pano_cli_plan_animation_panel_view_rejects_empty_frames
        COMMAND pano_cli plan-animation-panel-view --layer-count 1 --frame-count 0 --total-duration 1)
    set_tests_properties(pano_cli_plan_animation_panel_view_rejects_empty_frames PROPERTIES
        LABELS "app;ui;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_animation_timeline_scrub_smoke
        COMMAND pano_cli plan-animation-timeline-scrub --total-duration 5 --cursor-x 174.99)
    set_tests_properties(pano_cli_plan_animation_timeline_scrub_smoke PROPERTIES
        LABELS "app;ui;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-animation-timeline-scrub\".*\"totalDuration\":5.*\"cursorX\":174.99.*\"frameWidth\":35.*\"targetFrame\":4")

    add_test(NAME pano_cli_plan_animation_timeline_scrub_clamps_left
        COMMAND pano_cli plan-animation-timeline-scrub --total-duration 5 --cursor-x -1)
    set_tests_properties(pano_cli_plan_animation_timeline_scrub_clamps_left PROPERTIES
        LABELS "app;ui;integration;desktop-fast;fuzz"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-animation-timeline-scrub\".*\"cursorX\":-1.*\"targetFrame\":0")

    add_test(NAME pano_cli_plan_animation_timeline_scrub_rejects_bad_duration
        COMMAND pano_cli plan-animation-timeline-scrub --total-duration 0 --cursor-x 0)
    set_tests_properties(pano_cli_plan_animation_timeline_scrub_rejects_bad_duration PROPERTIES
        LABELS "app;ui;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_animation_operation_rejects_remove_last_frame
        COMMAND pano_cli plan-animation-operation --kind remove --frame-count 1 --selected-frame 0)
    set_tests_properties(pano_cli_plan_animation_operation_rejects_remove_last_frame PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_animation_operation_rejects_bad_selection
        COMMAND pano_cli plan-animation-operation --kind select --frame-count 2 --selected-frame 2 --layer-index 0 --layer-id 42)
    set_tests_properties(pano_cli_plan_animation_operation_rejects_bad_selection PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_brush_operation_color_smoke
        COMMAND pano_cli plan-brush-operation --kind color --r 0.25 --g 0.5 --b 0.75 --a 1)
    set_tests_properties(pano_cli_plan_brush_operation_color_smoke PROPERTIES
        LABELS "app;paint;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-brush-operation\".*\"operation\":\"set-tip-color\".*\"r\":0.25.*\"g\":0.5.*\"b\":0.75.*\"updateColorUi\":true.*\"updateBrushUi\":false")

    add_test(NAME pano_cli_plan_brush_operation_texture_smoke
        COMMAND pano_cli plan-brush-operation --kind pattern --path data/patterns/noise.png --thumb data/patterns/thumbs/noise.png)
    set_tests_properties(pano_cli_plan_brush_operation_texture_smoke PROPERTIES
        LABELS "app;paint;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-brush-operation\".*\"operation\":\"set-texture\".*\"textureSlot\":\"pattern\".*\"path\":\"data/patterns/noise.png\".*\"loadsBrushResources\":true.*\"updateBrushUi\":true")

    add_test(NAME pano_cli_plan_brush_operation_preset_smoke
        COMMAND pano_cli plan-brush-operation --kind preset)
    set_tests_properties(pano_cli_plan_brush_operation_preset_smoke PROPERTIES
        LABELS "app;paint;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-brush-operation\".*\"operation\":\"replace-brush-from-preset\".*\"preservesExistingColor\":true.*\"loadsBrushResources\":true")

    add_test(NAME pano_cli_plan_brush_operation_rejects_bad_color
        COMMAND pano_cli plan-brush-operation --kind color --r 1.5)
    set_tests_properties(pano_cli_plan_brush_operation_rejects_bad_color PROPERTIES
        LABELS "app;paint;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_brush_operation_rejects_empty_texture
        COMMAND pano_cli plan-brush-operation --kind tip)
    set_tests_properties(pano_cli_plan_brush_operation_rejects_empty_texture PROPERTIES
        LABELS "app;paint;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_brush_refresh_smoke
        COMMAND pano_cli plan-brush-refresh --floating-picker --tip-flow 0.8 --tip-size 48 --r 0.2 --g 0.3 --b 0.4 --a 1)
    set_tests_properties(pano_cli_plan_brush_refresh_smoke PROPERTIES
        LABELS "app;paint;ui;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-brush-refresh\".*\"updatesStrokeControls\":true.*\"updatesQuickFlow\":true.*\"updatesQuickSize\":true.*\"updatesQuickBrushPreview\":true.*\"updatesQuickColor\":true.*\"updatesFloatingPicker\":true.*\"updatesFloatingColorPanel\":false.*\"tipFlow\":0.8.*\"tipSize\":48.*\"r\":0.2.*\"g\":0.3.*\"b\":0.4.*\"a\":1")

    add_test(NAME pano_cli_plan_brush_refresh_noop_smoke
        COMMAND pano_cli plan-brush-refresh --no-color --no-brush-update --no-brush)
    set_tests_properties(pano_cli_plan_brush_refresh_noop_smoke PROPERTIES
        LABELS "app;paint;ui;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-brush-refresh\".*\"updatesQuickBrushPreview\":false.*\"updatesQuickColor\":false.*\"noOp\":true")

    add_test(NAME pano_cli_plan_brush_refresh_rejects_missing_brush
        COMMAND pano_cli plan-brush-refresh --no-brush)
    set_tests_properties(pano_cli_plan_brush_refresh_rejects_missing_brush PROPERTIES
        LABELS "app;paint;ui;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_brush_refresh_rejects_bad_float
        COMMAND pano_cli plan-brush-refresh --bad-float)
    set_tests_properties(pano_cli_plan_brush_refresh_rejects_bad_float PROPERTIES
        LABELS "app;paint;ui;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_brush_texture_list_add_smoke
        COMMAND pano_cli plan-brush-texture-list --kind add --dir brushes --data-path data --source C:/Temp/soft.png)
    set_tests_properties(pano_cli_plan_brush_texture_list_add_smoke PROPERTIES
        LABELS "app;paint;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-brush-texture-list\".*\"operation\":\"add-texture\".*\"source\":\"C:/Temp/soft.png\".*\"path\":\"data/brushes/soft.png\".*\"thumb\":\"data/brushes/thumbs/soft.png\".*\"brushName\":\"soft\".*\"userTexture\":true.*\"convertsBrushAlpha\":true")

    add_test(NAME pano_cli_plan_brush_texture_list_remove_user_smoke
        COMMAND pano_cli plan-brush-texture-list --kind remove --item-count 3 --current-index 2 --user-texture)
    set_tests_properties(pano_cli_plan_brush_texture_list_remove_user_smoke PROPERTIES
        LABELS "app;paint;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-brush-texture-list\".*\"operation\":\"remove-texture\".*\"itemCount\":3.*\"currentIndex\":2.*\"targetIndex\":1.*\"deletesTextureFiles\":true.*\"notifiesSelection\":true")

    add_test(NAME pano_cli_plan_brush_texture_list_move_edge_smoke
        COMMAND pano_cli plan-brush-texture-list --kind move --item-count 3 --current-index 0 --offset -1)
    set_tests_properties(pano_cli_plan_brush_texture_list_move_edge_smoke PROPERTIES
        LABELS "app;paint;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-brush-texture-list\".*\"operation\":\"move-texture\".*\"currentIndex\":0.*\"targetIndex\":0.*\"moveOffset\":-1.*\"noOp\":true")

    add_test(NAME pano_cli_plan_brush_texture_list_rejects_bad_source
        COMMAND pano_cli plan-brush-texture-list --kind add --source no-extension)
    set_tests_properties(pano_cli_plan_brush_texture_list_rejects_bad_source PROPERTIES
        LABELS "app;paint;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_brush_preset_list_add_smoke
        COMMAND pano_cli plan-brush-preset-list --kind add --item-count 2)
    set_tests_properties(pano_cli_plan_brush_preset_list_add_smoke PROPERTIES
        LABELS "app;paint;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-brush-preset-list\".*\"operation\":\"add-current-brush\".*\"itemCount\":2.*\"targetIndex\":2.*\"savesList\":true.*\"updatesEmptyNotification\":true")

    add_test(NAME pano_cli_plan_brush_preset_list_remove_only_smoke
        COMMAND pano_cli plan-brush-preset-list --kind remove --item-count 1 --current-index 0)
    set_tests_properties(pano_cli_plan_brush_preset_list_remove_only_smoke PROPERTIES
        LABELS "app;paint;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-brush-preset-list\".*\"operation\":\"remove-preset\".*\"itemCount\":1.*\"targetIndex\":-1.*\"selectsTarget\":false.*\"clearsSelection\":true")

    add_test(NAME pano_cli_plan_brush_preset_list_move_edge_smoke
        COMMAND pano_cli plan-brush-preset-list --kind up --item-count 3 --current-index 0)
    set_tests_properties(pano_cli_plan_brush_preset_list_move_edge_smoke PROPERTIES
        LABELS "app;paint;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-brush-preset-list\".*\"operation\":\"move-preset\".*\"currentIndex\":0.*\"targetIndex\":0.*\"moveOffset\":-1.*\"noOp\":true")

    add_test(NAME pano_cli_plan_brush_preset_list_select_smoke
        COMMAND pano_cli plan-brush-preset-list --kind select --item-count 3 --current-index 2)
    set_tests_properties(pano_cli_plan_brush_preset_list_select_smoke PROPERTIES
        LABELS "app;paint;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-brush-preset-list\".*\"operation\":\"select-preset\".*\"targetIndex\":2.*\"savesList\":false.*\"notifiesBrushChanged\":true")

    add_test(NAME pano_cli_plan_brush_stroke_control_float_smoke
        COMMAND pano_cli plan-brush-stroke-control --kind float --setting tip-size --value 42.5)
    set_tests_properties(pano_cli_plan_brush_stroke_control_float_smoke PROPERTIES
        LABELS "app;paint;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-brush-stroke-control\".*\"operation\":\"set-float\".*\"floatSetting\":\"tip-size\".*\"floatValue\":42.5.*\"mutatesBrush\":true.*\"notifiesStrokeChange\":true")

    add_test(NAME pano_cli_plan_brush_stroke_control_toggle_smoke
        COMMAND pano_cli plan-brush-stroke-control --kind bool --setting dual-enabled --enabled)
    set_tests_properties(pano_cli_plan_brush_stroke_control_toggle_smoke PROPERTIES
        LABELS "app;paint;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-brush-stroke-control\".*\"operation\":\"set-bool\".*\"boolSetting\":\"dual-enabled\".*\"boolValue\":true.*\"refreshesPreview\":true")

    add_test(NAME pano_cli_plan_brush_stroke_control_blend_smoke
        COMMAND pano_cli plan-brush-stroke-control --kind blend --setting pattern --blend-mode 3)
    set_tests_properties(pano_cli_plan_brush_stroke_control_blend_smoke PROPERTIES
        LABELS "app;paint;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-brush-stroke-control\".*\"operation\":\"set-blend-mode\".*\"blendSetting\":\"pattern\".*\"blendMode\":3")

    add_test(NAME pano_cli_plan_brush_stroke_control_reset_smoke
        COMMAND pano_cli plan-brush-stroke-control --kind default-reset)
    set_tests_properties(pano_cli_plan_brush_stroke_control_reset_smoke PROPERTIES
        LABELS "app;paint;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-brush-stroke-control\".*\"operation\":\"reset-default-brush\".*\"updatesControls\":true.*\"notifiesStrokeChange\":true")

    add_test(NAME pano_cli_plan_brush_stroke_control_rejects_bad_setting
        COMMAND pano_cli plan-brush-stroke-control --kind float --setting imaginary --value 1)
    set_tests_properties(pano_cli_plan_brush_stroke_control_rejects_bad_setting PROPERTIES
        LABELS "app;paint;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_brush_stroke_control_rejects_bad_blend
        COMMAND pano_cli plan-brush-stroke-control --kind blend --setting tip --blend-mode 99)
    set_tests_properties(pano_cli_plan_brush_stroke_control_rejects_bad_blend PROPERTIES
        LABELS "app;paint;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_brush_stroke_panel_view_smoke
        COMMAND pano_cli plan-brush-stroke-panel-view --tip-size 64 --jitter-scatter 0.4 --dual-disabled --tip-blend-mode 2 --pattern-blend-mode 5 --tip-thumb data/brushes/thumbs/ink.png)
    set_tests_properties(pano_cli_plan_brush_stroke_panel_view_smoke PROPERTIES
        LABELS "app;paint;ui;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-brush-stroke-panel-view\".*\"floatValues\":2.*\"boolValues\":1.*\"blendValues\":2.*\"tipSize\":64.*\"jitterScatter\":0.4.*\"dualEnabled\":false.*\"tipBlendMode\":2.*\"patternBlendMode\":5.*\"tipThumb\":\"data/brushes/thumbs/ink.png\".*\"updatesPreview\":true.*\"updatesThumbnails\":true")

    add_test(NAME pano_cli_plan_brush_stroke_panel_view_rejects_bad_float
        COMMAND pano_cli plan-brush-stroke-panel-view --bad-float)
    set_tests_properties(pano_cli_plan_brush_stroke_panel_view_rejects_bad_float PROPERTIES
        LABELS "app;paint;ui;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_brush_stroke_panel_view_rejects_bad_blend
        COMMAND pano_cli plan-brush-stroke-panel-view --bad-blend)
    set_tests_properties(pano_cli_plan_brush_stroke_panel_view_rejects_bad_blend PROPERTIES
        LABELS "app;paint;ui;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_paint_feedback_framebuffer_fetch_smoke
        COMMAND pano_cli plan-paint-feedback --framebuffer-fetch --explicit-transitions --render-only)
    set_tests_properties(pano_cli_plan_paint_feedback_framebuffer_fetch_smoke PROPERTIES
        LABELS "renderer;paint;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-paint-feedback\".*\"path\":\"framebuffer_fetch\".*\"readsDestinationColor\":true.*\"requiresAuxiliaryTexture\":false.*\"requiresExplicitTransition\":true")

    add_test(NAME pano_cli_plan_paint_feedback_ping_pong_copy_smoke
        COMMAND pano_cli plan-paint-feedback --texture-copy)
    set_tests_properties(pano_cli_plan_paint_feedback_ping_pong_copy_smoke PROPERTIES
        LABELS "renderer;paint;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-paint-feedback\".*\"path\":\"ping_pong_textures\".*\"requiresAuxiliaryTexture\":true.*\"requiresTextureCopy\":true.*\"requiresRenderTargetBlit\":false")

    add_test(NAME pano_cli_plan_paint_feedback_simple_smoke
        COMMAND pano_cli plan-paint-feedback --simple --render-only)
    set_tests_properties(pano_cli_plan_paint_feedback_simple_smoke PROPERTIES
        LABELS "renderer;paint;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-paint-feedback\".*\"path\":\"none\".*\"complexBlend\":false.*\"readsDestinationColor\":false")

    add_test(NAME pano_cli_plan_paint_feedback_rejects_unsupported
        COMMAND pano_cli plan-paint-feedback)
    set_tests_properties(pano_cli_plan_paint_feedback_rejects_unsupported PROPERTIES
        LABELS "renderer;paint;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_paint_feedback_rejects_depth
        COMMAND pano_cli plan-paint-feedback --texture-copy --depth)
    set_tests_properties(pano_cli_plan_paint_feedback_rejects_depth PROPERTIES
        LABELS "renderer;paint;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_stroke_composite_fixed_smoke
        COMMAND pano_cli plan-stroke-composite --render-only)
    set_tests_properties(pano_cli_plan_stroke_composite_fixed_smoke PROPERTIES
        LABELS "renderer;paint;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-stroke-composite\".*\"path\":\"fixed_function_blend\".*\"feedbackPath\":\"none\".*\"complexBlend\":false.*\"readsDestinationColor\":false")

    add_test(NAME pano_cli_plan_stroke_composite_framebuffer_fetch_smoke
        COMMAND pano_cli plan-stroke-composite --stroke-blend 10 --framebuffer-fetch --explicit-transitions --render-only)
    set_tests_properties(pano_cli_plan_stroke_composite_framebuffer_fetch_smoke PROPERTIES
        LABELS "renderer;paint;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-stroke-composite\".*\"strokeBlend\":\"height\".*\"path\":\"framebuffer_fetch\".*\"feedbackPath\":\"framebuffer_fetch\".*\"complexBlend\":true.*\"requiresExplicitTransition\":true")

    add_test(NAME pano_cli_plan_stroke_composite_ping_pong_copy_smoke
        COMMAND pano_cli plan-stroke-composite --layer-blend 4 --dual-blend --texture-copy)
    set_tests_properties(pano_cli_plan_stroke_composite_ping_pong_copy_smoke PROPERTIES
        LABELS "renderer;paint;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-stroke-composite\".*\"layerBlend\":\"overlay\".*\"path\":\"ping_pong_textures\".*\"estimatedWorkingBytes\":16384.*\"requiresAuxiliaryTexture\":true.*\"requiresTextureCopy\":true")

    add_test(NAME pano_cli_plan_stroke_composite_rejects_unsupported
        COMMAND pano_cli plan-stroke-composite --layer-blend 1)
    set_tests_properties(pano_cli_plan_stroke_composite_rejects_unsupported PROPERTIES
        LABELS "renderer;paint;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_stroke_composite_rejects_bad_stroke_blend
        COMMAND pano_cli plan-stroke-composite --stroke-blend 99 --texture-copy)
    set_tests_properties(pano_cli_plan_stroke_composite_rejects_bad_stroke_blend PROPERTIES
        LABELS "renderer;paint;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_canvas_hotkey_ctrl_z_smoke
        COMMAND pano_cli plan-canvas-hotkey --event key-up --key z --ctrl --undo-count 2)
    set_tests_properties(pano_cli_plan_canvas_hotkey_ctrl_z_smoke PROPERTIES
        LABELS "app;document;ui;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-canvas-hotkey\".*\"key\":\"z\".*\"ctrl\":true.*\"action\":\"history\".*\"historyOperation\":\"undo\".*\"historyNoOp\":false")

    add_test(NAME pano_cli_plan_canvas_hotkey_save_dirty_version_smoke
        COMMAND pano_cli plan-canvas-hotkey --event key-up --key s --ctrl --shift)
    set_tests_properties(pano_cli_plan_canvas_hotkey_save_dirty_version_smoke PROPERTIES
        LABELS "app;document;ui;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-canvas-hotkey\".*\"key\":\"s\".*\"shift\":true.*\"action\":\"save-document\".*\"saveIntent\":\"save-dirty-version\"")

    add_test(NAME pano_cli_plan_canvas_hotkey_erase_smoke
        COMMAND pano_cli plan-canvas-hotkey --event key-down --key e)
    set_tests_properties(pano_cli_plan_canvas_hotkey_erase_smoke PROPERTIES
        LABELS "app;paint;ui;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-canvas-hotkey\".*\"event\":\"key-down\".*\"key\":\"e\".*\"action\":\"select-tool\".*\"toolMode\":\"erase\"")

    add_test(NAME pano_cli_plan_canvas_hotkey_two_finger_undo_smoke
        COMMAND pano_cli plan-canvas-hotkey --event touch-tap --key other --touch-fingers 2 --undo-count 1)
    set_tests_properties(pano_cli_plan_canvas_hotkey_two_finger_undo_smoke PROPERTIES
        LABELS "app;document;ui;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-canvas-hotkey\".*\"event\":\"touch-tap\".*\"touchFingers\":2.*\"action\":\"history\".*\"historyOperation\":\"undo\"")

    add_test(NAME pano_cli_plan_canvas_hotkey_rejects_bad_count
        COMMAND pano_cli plan-canvas-hotkey --event key-down --key android-back --undo-count -1)
    set_tests_properties(pano_cli_plan_canvas_hotkey_rejects_bad_count PROPERTIES
        LABELS "app;document;ui;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_canvas_tool_draw_smoke
        COMMAND pano_cli plan-canvas-tool --kind draw)
    set_tests_properties(pano_cli_plan_canvas_tool_draw_smoke PROPERTIES
        LABELS "app;ui;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-canvas-tool\".*\"operation\":\"select-mode\".*\"mode\":\"draw\".*\"selectsToolbarButton\":true.*\"updatesCanvasMode\":true")

    add_test(NAME pano_cli_plan_canvas_tool_copy_smoke
        COMMAND pano_cli plan-canvas-tool --kind copy)
    set_tests_properties(pano_cli_plan_canvas_tool_copy_smoke PROPERTIES
        LABELS "app;ui;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-canvas-tool\".*\"mode\":\"copy\".*\"transformAction\":\"copy\".*\"updatesCanvasMode\":true")

    add_test(NAME pano_cli_plan_canvas_tool_pick_noop_smoke
        COMMAND pano_cli plan-canvas-tool --kind pick)
    set_tests_properties(pano_cli_plan_canvas_tool_pick_noop_smoke PROPERTIES
        LABELS "app;ui;integration;desktop-fast;fuzz"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-canvas-tool\".*\"operation\":\"toggle-picking\".*\"togglesPicking\":false.*\"requiresDrawMode\":true.*\"noOp\":true")

    add_test(NAME pano_cli_plan_canvas_tool_touch_lock_smoke
        COMMAND pano_cli plan-canvas-tool --kind touch-lock)
    set_tests_properties(pano_cli_plan_canvas_tool_touch_lock_smoke PROPERTIES
        LABELS "app;ui;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-canvas-tool\".*\"operation\":\"toggle-touch-lock\".*\"togglesTouchLock\":true.*\"noOp\":false")

    add_test(NAME pano_cli_plan_canvas_tool_rejects_unknown
        COMMAND pano_cli plan-canvas-tool --kind warp)
    set_tests_properties(pano_cli_plan_canvas_tool_rejects_unknown PROPERTIES
        LABELS "app;ui;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_canvas_tool_toolbar_smoke
        COMMAND pano_cli plan-canvas-tool-toolbar)
    set_tests_properties(pano_cli_plan_canvas_tool_toolbar_smoke PROPERTIES
        LABELS "app;ui;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-canvas-tool-toolbar\".*\"defaultMode\":\"draw\".*\"bindingCount\":13.*\"id\":\"btn-pen\".*\"defaultOnInit\":true.*\"id\":\"btn-pick\".*\"action\":\"toggle-picking\".*\"id\":\"btn-bucket\".*\"mode\":\"bucket\"")

    add_test(NAME pano_cli_plan_canvas_tool_toolbar_rejects_unknown
        COMMAND pano_cli plan-canvas-tool-toolbar --unexpected)
    set_tests_properties(pano_cli_plan_canvas_tool_toolbar_rejects_unknown PROPERTIES
        LABELS "app;ui;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-canvas-tool-toolbar\".*\"message\":\"unknown option\"")

    add_test(NAME pano_cli_plan_canvas_tool_state_draw_smoke
        COMMAND pano_cli plan-canvas-tool-state --mode draw --picking --touch-lock)
    set_tests_properties(pano_cli_plan_canvas_tool_state_draw_smoke PROPERTIES
        LABELS "app;ui;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-canvas-tool-state\".*\"mode\":\"draw\".*\"pickActive\":true.*\"touchLockActive\":true.*\"penActive\":true")

    add_test(NAME pano_cli_plan_canvas_tool_state_copy_smoke
        COMMAND pano_cli plan-canvas-tool-state --mode copy --picking)
    set_tests_properties(pano_cli_plan_canvas_tool_state_copy_smoke PROPERTIES
        LABELS "app;ui;integration;desktop-fast;fuzz"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-canvas-tool-state\".*\"mode\":\"copy\".*\"pickActive\":false.*\"penActive\":false.*\"copyActive\":true")

    add_test(NAME pano_cli_plan_canvas_tool_state_rejects_unknown
        COMMAND pano_cli plan-canvas-tool-state --mode warp)
    set_tests_properties(pano_cli_plan_canvas_tool_state_rejects_unknown PROPERTIES
        LABELS "app;ui;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_canvas_camera_reset_smoke
        COMMAND pano_cli plan-canvas-camera-reset)
    set_tests_properties(pano_cli_plan_canvas_camera_reset_smoke PROPERTIES
        LABELS "app;ui;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-canvas-camera-reset\".*\"rotation\":\\[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1\\].*\"position\":\\[0,0,0\\].*\"fieldOfViewDegrees\":85.*\"pan\":\\[0,0\\]")

    add_test(NAME pano_cli_plan_canvas_camera_reset_rejects_options
        COMMAND pano_cli plan-canvas-camera-reset --unexpected)
    set_tests_properties(pano_cli_plan_canvas_camera_reset_rejects_options PROPERTIES
        LABELS "app;ui;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_canvas_view_density_smoke
        COMMAND pano_cli plan-canvas-view-density --density 1.5)
    set_tests_properties(pano_cli_plan_canvas_view_density_smoke PROPERTIES
        LABELS "app;ui;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-canvas-view-density\".*\"density\":1.5.*\"recreatesBuffers\":true")

    add_test(NAME pano_cli_plan_canvas_view_density_rejects_bad_float
        COMMAND pano_cli plan-canvas-view-density --bad-float)
    set_tests_properties(pano_cli_plan_canvas_view_density_rejects_bad_float PROPERTIES
        LABELS "app;ui;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_canvas_view_cursor_mode_smoke
        COMMAND pano_cli plan-canvas-view-cursor-mode --mode 3)
    set_tests_properties(pano_cli_plan_canvas_view_cursor_mode_smoke PROPERTIES
        LABELS "app;ui;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-canvas-view-cursor-mode\".*\"mode\":3")

    add_test(NAME pano_cli_plan_canvas_view_cursor_mode_rejects_invalid
        COMMAND pano_cli plan-canvas-view-cursor-mode --mode 4)
    set_tests_properties(pano_cli_plan_canvas_view_cursor_mode_rejects_invalid PROPERTIES
        LABELS "app;ui;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_canvas_cursor_small_brush_smoke
        COMMAND pano_cli plan-canvas-cursor --mode draw --visibility small-brush --brush-size 9.5)
    set_tests_properties(pano_cli_plan_canvas_cursor_small_brush_smoke PROPERTIES
        LABELS "app;ui;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-canvas-cursor\".*\"mode\":\"draw\".*\"visibility\":\"small-brush\".*\"visible\":true.*\"paintMode\":true.*\"usesBrushSize\":true")

    add_test(NAME pano_cli_plan_canvas_cursor_not_painting_hidden_smoke
        COMMAND pano_cli plan-canvas-cursor --mode erase --visibility not-painting --drawing)
    set_tests_properties(pano_cli_plan_canvas_cursor_not_painting_hidden_smoke PROPERTIES
        LABELS "app;ui;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-canvas-cursor\".*\"mode\":\"erase\".*\"visibility\":\"not-painting\".*\"drawing\":true.*\"visible\":false.*\"usesPenState\":true")

    add_test(NAME pano_cli_plan_canvas_cursor_alt_forces_visible_smoke
        COMMAND pano_cli plan-canvas-cursor --mode draw --visibility never --alt)
    set_tests_properties(pano_cli_plan_canvas_cursor_alt_forces_visible_smoke PROPERTIES
        LABELS "app;ui;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-canvas-cursor\".*\"visibility\":\"never\".*\"visible\":true.*\"forcedVisibleByModifierOrTool\":true")

    add_test(NAME pano_cli_plan_canvas_cursor_non_paint_smoke
        COMMAND pano_cli plan-canvas-cursor --mode camera --visibility never)
    set_tests_properties(pano_cli_plan_canvas_cursor_non_paint_smoke PROPERTIES
        LABELS "app;ui;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-canvas-cursor\".*\"mode\":\"camera\".*\"visible\":true.*\"paintMode\":false")

    add_test(NAME pano_cli_plan_canvas_cursor_rejects_missing_brush
        COMMAND pano_cli plan-canvas-cursor --visibility small-brush --no-brush)
    set_tests_properties(pano_cli_plan_canvas_cursor_rejects_missing_brush PROPERTIES
        LABELS "app;ui;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_canvas_cursor_rejects_bad_size
        COMMAND pano_cli plan-canvas-cursor --visibility small-brush --bad-size)
    set_tests_properties(pano_cli_plan_canvas_cursor_rejects_bad_size PROPERTIES
        LABELS "app;ui;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_grid_operation_pick_smoke
        COMMAND pano_cli plan-grid-operation --kind pick)
    set_tests_properties(pano_cli_plan_grid_operation_pick_smoke PROPERTIES
        LABELS "app;ui;renderer;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-grid-operation\".*\"operation\":\"request-heightmap-pick\".*\"opensPicker\":true.*\"mutatesGridState\":false")

    add_test(NAME pano_cli_plan_grid_operation_load_smoke
        COMMAND pano_cli plan-grid-operation --kind load --path D:/Paint/height.png)
    set_tests_properties(pano_cli_plan_grid_operation_load_smoke PROPERTIES
        LABELS "app;ui;renderer;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-grid-operation\".*\"operation\":\"load-heightmap\".*\"path\":\"D:/Paint/height.png\".*\"loadsHeightmap\":true.*\"updatesPreview\":true.*\"updatesGroundOpacity\":true")

    add_test(NAME pano_cli_plan_grid_operation_render_supported_smoke
        COMMAND pano_cli plan-grid-operation --kind render --float32 --texture-resolution 1024 --samples 32)
    set_tests_properties(pano_cli_plan_grid_operation_render_supported_smoke PROPERTIES
        LABELS "app;ui;renderer;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-grid-operation\".*\"operation\":\"render-lightmap\".*\"textureResolution\":1024.*\"sampleCount\":32.*\"rendersLightmap\":true.*\"updatesShadingMode\":true.*\"showsProgress\":true")

    add_test(NAME pano_cli_plan_grid_operation_render_unsupported_smoke
        COMMAND pano_cli plan-grid-operation --kind render)
    set_tests_properties(pano_cli_plan_grid_operation_render_unsupported_smoke PROPERTIES
        LABELS "app;ui;renderer;integration;desktop-fast;fuzz"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-grid-operation\".*\"operation\":\"render-lightmap\".*\"rendersLightmap\":false.*\"showsUnsupportedMessage\":true")

    add_test(NAME pano_cli_plan_grid_operation_rejects_empty_reload
        COMMAND pano_cli plan-grid-operation --kind reload)
    set_tests_properties(pano_cli_plan_grid_operation_rejects_empty_reload PROPERTIES
        LABELS "app;ui;renderer;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_grid_operation_rejects_bad_samples
        COMMAND pano_cli plan-grid-operation --kind render --float32 --samples 0)
    set_tests_properties(pano_cli_plan_grid_operation_rejects_bad_samples PROPERTIES
        LABELS "app;ui;renderer;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_history_operation_undo_smoke
        COMMAND pano_cli plan-history-operation --kind undo --undo-count 2)
    set_tests_properties(pano_cli_plan_history_operation_undo_smoke PROPERTIES
        LABELS "app;document;ui;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-history-operation\".*\"operation\":\"undo\".*\"undoCount\":2.*\"invokesUndo\":true.*\"updatesMemoryLabel\":true.*\"updatesTitle\":true")

    add_test(NAME pano_cli_plan_history_operation_redo_empty_smoke
        COMMAND pano_cli plan-history-operation --kind redo)
    set_tests_properties(pano_cli_plan_history_operation_redo_empty_smoke PROPERTIES
        LABELS "app;document;ui;integration;desktop-fast;fuzz"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-history-operation\".*\"operation\":\"redo\".*\"redoCount\":0.*\"invokesRedo\":false.*\"noOp\":true")

    add_test(NAME pano_cli_plan_history_operation_clear_smoke
        COMMAND pano_cli plan-history-operation --kind clear --undo-count 2 --redo-count 1 --memory-bytes 4096)
    set_tests_properties(pano_cli_plan_history_operation_clear_smoke PROPERTIES
        LABELS "app;document;ui;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-history-operation\".*\"operation\":\"clear\".*\"undoCount\":2.*\"redoCount\":1.*\"memoryBytes\":4096.*\"clearsHistory\":true.*\"updatesMemoryLabel\":true")

    add_test(NAME pano_cli_plan_history_operation_rejects_negative_count
        COMMAND pano_cli plan-history-operation --kind undo --undo-count -1)
    set_tests_properties(pano_cli_plan_history_operation_rejects_negative_count PROPERTIES
        LABELS "app;document;ui;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_main_toolbar_undo_smoke
        COMMAND pano_cli plan-main-toolbar --command undo --undo-count 2)
    set_tests_properties(pano_cli_plan_main_toolbar_undo_smoke PROPERTIES
        LABELS "app;document;ui;integration;desktop-fast;fuzz"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-main-toolbar\".*\"command\":\"undo\".*\"action\":\"invoke-undo\".*\"updatesMemoryLabel\":true.*\"updatesTitle\":true.*\"noOp\":false")

    add_test(NAME pano_cli_plan_main_toolbar_redo_empty_smoke
        COMMAND pano_cli plan-main-toolbar --command redo)
    set_tests_properties(pano_cli_plan_main_toolbar_redo_empty_smoke PROPERTIES
        LABELS "app;document;ui;integration;desktop-fast;fuzz"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-main-toolbar\".*\"command\":\"redo\".*\"action\":\"no-op-unavailable\".*\"label\":\"Redo \\(No history\\)\".*\"noOp\":true")

    add_test(NAME pano_cli_plan_main_toolbar_clear_canvas_no_canvas_smoke
        COMMAND pano_cli plan-main-toolbar --command clear-canvas --no-canvas)
    set_tests_properties(pano_cli_plan_main_toolbar_clear_canvas_no_canvas_smoke PROPERTIES
        LABELS "app;document;ui;integration;desktop-fast;fuzz"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-main-toolbar\".*\"hasCanvas\":false.*\"action\":\"no-op-unavailable\".*\"label\":\"Clear Canvas \\(No canvas\\)\".*\"requiresCanvas\":true.*\"recordsUndo\":false.*\"marksUnsaved\":false.*\"noOp\":true")

    add_test(NAME pano_cli_plan_main_toolbar_message_box_smoke
        COMMAND pano_cli plan-main-toolbar --command message-box)
    set_tests_properties(pano_cli_plan_main_toolbar_message_box_smoke PROPERTIES
        LABELS "app;document;ui;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-main-toolbar\".*\"action\":\"show-message-box\".*\"messageDialog\":\\{\"title\":\"Just a test message\",\"message\":\"Longer description for the error or the message\\.\",\"okCaption\":\"Ok\",\"cancelCaption\":\"Cancel\",\"showCancel\":true\\}")

    add_test(NAME pano_cli_plan_main_toolbar_rejects_negative_count
        COMMAND pano_cli plan-main-toolbar --command undo --undo-count -1)
    set_tests_properties(pano_cli_plan_main_toolbar_rejects_negative_count PROPERTIES
        LABELS "app;document;ui;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_quick_operation_select_brush_smoke
        COMMAND pano_cli plan-quick-operation --kind brush --current-index 0 --slot-index 2)
    set_tests_properties(pano_cli_plan_quick_operation_select_brush_smoke PROPERTIES
        LABELS "app;ui;paint;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-quick-operation\".*\"operation\":\"select-slot\".*\"slotKind\":\"brush\".*\"slotIndex\":2.*\"updatesSelection\":true.*\"invokesChangeCallback\":true")

    add_test(NAME pano_cli_plan_quick_operation_open_color_smoke
        COMMAND pano_cli plan-quick-operation --kind color --current-index 1 --slot-index 1)
    set_tests_properties(pano_cli_plan_quick_operation_open_color_smoke PROPERTIES
        LABELS "app;ui;paint;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-quick-operation\".*\"operation\":\"open-slot-popup\".*\"slotKind\":\"color\".*\"opensColorPicker\":true.*\"mutatesQuickState\":false")

    add_test(NAME pano_cli_plan_quick_operation_restore_smoke
        COMMAND pano_cli plan-quick-operation --kind restore --brush-index 2 --color-index 1 --fire-event)
    set_tests_properties(pano_cli_plan_quick_operation_restore_smoke PROPERTIES
        LABELS "app;ui;paint;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-quick-operation\".*\"operation\":\"restore-state\".*\"fireEvent\":true.*\"invokesChangeCallback\":true.*\"restoresSlots\":true.*\"redrawsBrushPreviews\":true")

    add_test(NAME pano_cli_plan_quick_operation_reset_smoke
        COMMAND pano_cli plan-quick-operation --kind reset)
    set_tests_properties(pano_cli_plan_quick_operation_reset_smoke PROPERTIES
        LABELS "app;ui;paint;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-quick-operation\".*\"operation\":\"reset-state\".*\"invokesChangeCallback\":false.*\"resetsSlots\":true.*\"redrawsBrushPreviews\":true")

    add_test(NAME pano_cli_plan_quick_operation_rejects_bad_slot
        COMMAND pano_cli plan-quick-operation --kind brush --current-index 0 --slot-index 3)
    set_tests_properties(pano_cli_plan_quick_operation_rejects_bad_slot PROPERTIES
        LABELS "app;ui;paint;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_quick_operation_rejects_bad_restore
        COMMAND pano_cli plan-quick-operation --kind restore --brush-index -1 --color-index 0)
    set_tests_properties(pano_cli_plan_quick_operation_rejects_bad_restore PROPERTIES
        LABELS "app;ui;paint;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_quick_slider_preview_pen_smoke
        COMMAND pano_cli plan-quick-slider-preview --slider-x 10 --slider-y 20 --slider-height 40 --zoom 2 --pen-mode --no-line-mode)
    set_tests_properties(pano_cli_plan_quick_slider_preview_pen_smoke PROPERTIES
        LABELS "app;ui;paint;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-quick-slider-preview\".*\"cursorX\":220.*\"cursorY\":80.*\"updatesPenMode\":true.*\"updatesLineMode\":false.*\"drawsTip\":true.*\"disablesPenOutline\":true.*\"redrawsBrushPreview\":true")

    add_test(NAME pano_cli_plan_quick_slider_preview_rtl_line_smoke
        COMMAND pano_cli plan-quick-slider-preview --rtl --slider-x 50 --slider-y 10 --slider-height 20 --zoom 1.5 --no-pen-mode --line-mode)
    set_tests_properties(pano_cli_plan_quick_slider_preview_rtl_line_smoke PROPERTIES
        LABELS "app;ui;paint;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-quick-slider-preview\".*\"rtl\":true.*\"cursorX\":-75.*\"cursorY\":30.*\"updatesPenMode\":false.*\"updatesLineMode\":true.*\"drawsTip\":true.*\"disablesPenOutline\":false")

    add_test(NAME pano_cli_plan_quick_slider_preview_rejects_bad_float
        COMMAND pano_cli plan-quick-slider-preview --bad-float)
    set_tests_properties(pano_cli_plan_quick_slider_preview_rejects_bad_float PROPERTIES
        LABELS "app;ui;paint;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_quick_slider_preview_rejects_zero_zoom
        COMMAND pano_cli plan-quick-slider-preview --zoom 0)
    set_tests_properties(pano_cli_plan_quick_slider_preview_rejects_zero_zoom PROPERTIES
        LABELS "app;ui;paint;integration;desktop-fast;fuzz"
        WILL_FAIL TRUE)

    add_test(NAME pano_cli_plan_share_file_unsaved_smoke
        COMMAND pano_cli plan-share-file)
    set_tests_properties(pano_cli_plan_share_file_unsaved_smoke PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-share-file\".*\"path\":\"\".*\"decision\":\"show-save-required-warning\"")

    add_test(NAME pano_cli_plan_share_file_saved_smoke
        COMMAND pano_cli plan-share-file --path D:/Paint/demo.ppi)
    set_tests_properties(pano_cli_plan_share_file_saved_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-share-file\".*\"path\":\"D:/Paint/demo.ppi\".*\"decision\":\"share-now\"")

    add_test(NAME pano_cli_plan_picked_path_empty_smoke
        COMMAND pano_cli plan-picked-path)
    set_tests_properties(pano_cli_plan_picked_path_empty_smoke PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-picked-path\".*\"path\":\"\".*\"decision\":\"ignore-empty-path\"")

    add_test(NAME pano_cli_plan_picked_path_selected_smoke
        COMMAND pano_cli plan-picked-path --path D:/Paint/demo.ppi)
    set_tests_properties(pano_cli_plan_picked_path_selected_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-picked-path\".*\"path\":\"D:/Paint/demo.ppi\".*\"decision\":\"invoke-callback\"")

    add_test(NAME pano_cli_plan_display_file_empty_smoke
        COMMAND pano_cli plan-display-file)
    set_tests_properties(pano_cli_plan_display_file_empty_smoke PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-display-file\".*\"path\":\"\".*\"decision\":\"ignore-empty-path\"")

    add_test(NAME pano_cli_plan_display_file_selected_smoke
        COMMAND pano_cli plan-display-file --path D:/Paint/export.png)
    set_tests_properties(pano_cli_plan_display_file_selected_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-display-file\".*\"path\":\"D:/Paint/export.png\".*\"decision\":\"open-external-file\"")

    add_test(NAME pano_cli_plan_keyboard_visibility_hidden_smoke
        COMMAND pano_cli plan-keyboard-visibility)
    set_tests_properties(pano_cli_plan_keyboard_visibility_hidden_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-keyboard-visibility\".*\"visible\":false.*\"decision\":\"hide-keyboard\"")

    add_test(NAME pano_cli_plan_keyboard_visibility_visible_smoke
        COMMAND pano_cli plan-keyboard-visibility --visible)
    set_tests_properties(pano_cli_plan_keyboard_visibility_visible_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-keyboard-visibility\".*\"visible\":true.*\"decision\":\"show-keyboard\"")

    add_test(NAME pano_cli_plan_cursor_visibility_hidden_smoke
        COMMAND pano_cli plan-cursor-visibility)
    set_tests_properties(pano_cli_plan_cursor_visibility_hidden_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-cursor-visibility\".*\"visible\":false.*\"decision\":\"hide-cursor\"")

    add_test(NAME pano_cli_plan_cursor_visibility_visible_smoke
        COMMAND pano_cli plan-cursor-visibility --visible)
    set_tests_properties(pano_cli_plan_cursor_visibility_visible_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-cursor-visibility\".*\"visible\":true.*\"decision\":\"show-cursor\"")

    add_test(NAME pano_cli_plan_clipboard_read_smoke
        COMMAND pano_cli plan-clipboard-read)
    set_tests_properties(pano_cli_plan_clipboard_read_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-clipboard-read\".*\"decision\":\"read-text\"")

    add_test(NAME pano_cli_plan_clipboard_write_smoke
        COMMAND pano_cli plan-clipboard-write --text "#ff00aa")
    set_tests_properties(pano_cli_plan_clipboard_write_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-clipboard-write\".*\"text\":\"#ff00aa\".*\"decision\":\"write-text\"")

    add_test(NAME pano_cli_plan_clipboard_write_empty_smoke
        COMMAND pano_cli plan-clipboard-write)
    set_tests_properties(pano_cli_plan_clipboard_write_empty_smoke PROPERTIES
        LABELS "app;integration;desktop-fast;fuzz"
        PASS_REGULAR_EXPRESSION "\"command\":\"plan-clipboard-write\".*\"text\":\"\".*\"decision\":\"write-text\"")

    add_test(NAME pano_cli_simulate_app_session_clean_smoke
        COMMAND pano_cli simulate-app-session)
    set_tests_properties(pano_cli_simulate_app_session_clean_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"simulate-app-session\".*\"hasCanvas\":true.*\"newDocument\":false.*\"unsaved\":false.*\"closePromptOpen\":false.*\"projectOpen\":\"open-now\".*\"closeRequest\":\"close-now\".*\"saveIntent\":\"save\".*\"saveRequest\":\"no-op\".*\"workflowStart\":\"continue-now\"")

    add_test(NAME pano_cli_simulate_app_session_unsaved_smoke
        COMMAND pano_cli simulate-app-session --unsaved)
    set_tests_properties(pano_cli_simulate_app_session_unsaved_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"simulate-app-session\".*\"hasCanvas\":true.*\"newDocument\":false.*\"unsaved\":true.*\"closePromptOpen\":false.*\"projectOpen\":\"prompt-discard-unsaved\".*\"closeRequest\":\"show-unsaved-prompt\".*\"saveRequest\":\"save-existing\".*\"workflowStart\":\"prompt-save-before-continue\"")

    add_test(NAME pano_cli_simulate_app_session_existing_prompt_smoke
        COMMAND pano_cli simulate-app-session --unsaved --close-prompt-open)
    set_tests_properties(pano_cli_simulate_app_session_existing_prompt_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"simulate-app-session\".*\"newDocument\":false.*\"unsaved\":true.*\"closePromptOpen\":true.*\"projectOpen\":\"prompt-discard-unsaved\".*\"closeRequest\":\"wait-for-existing-prompt\"")

    add_test(NAME pano_cli_simulate_app_session_new_document_save_smoke
        COMMAND pano_cli simulate-app-session --new-document)
    set_tests_properties(pano_cli_simulate_app_session_new_document_save_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"simulate-app-session\".*\"newDocument\":true.*\"saveIntent\":\"save\".*\"saveRequest\":\"show-save-dialog\"")

    add_test(NAME pano_cli_simulate_app_session_save_as_smoke
        COMMAND pano_cli simulate-app-session --save-intent save-as)
    set_tests_properties(pano_cli_simulate_app_session_save_as_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"simulate-app-session\".*\"saveIntent\":\"save-as\".*\"saveRequest\":\"show-save-dialog\"")

    add_test(NAME pano_cli_simulate_app_session_save_version_smoke
        COMMAND pano_cli simulate-app-session --save-intent save-version)
    set_tests_properties(pano_cli_simulate_app_session_save_version_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"simulate-app-session\".*\"saveIntent\":\"save-version\".*\"saveRequest\":\"save-version\"")

    add_test(NAME pano_cli_simulate_app_session_save_dirty_version_clean_smoke
        COMMAND pano_cli simulate-app-session --save-intent save-dirty-version)
    set_tests_properties(pano_cli_simulate_app_session_save_dirty_version_clean_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"simulate-app-session\".*\"saveIntent\":\"save-dirty-version\".*\"saveRequest\":\"no-op\"")

    add_test(NAME pano_cli_simulate_app_session_no_canvas_smoke
        COMMAND pano_cli simulate-app-session --no-canvas)
    set_tests_properties(pano_cli_simulate_app_session_no_canvas_smoke PROPERTIES
        LABELS "app;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"simulate-app-session\".*\"hasCanvas\":false.*\"workflowStart\":\"unavailable\"")

    add_test(NAME pano_cli_save_project_roundtrip_smoke
        COMMAND "${CMAKE_COMMAND}"
            -DPANO_CLI=$<TARGET_FILE:pano_cli>
            -DOUTPUT_PATH=${CMAKE_CURRENT_BINARY_DIR}/data/generated/roundtrip.ppi
            -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/pano_cli_save_project_roundtrip.cmake")
    set_tests_properties(pano_cli_save_project_roundtrip_smoke PROPERTIES
        LABELS "assets;document;integration;desktop-fast")

    add_test(NAME pano_cli_save_project_payload_roundtrip_smoke
        COMMAND "${CMAKE_COMMAND}"
            -DPANO_CLI=$<TARGET_FILE:pano_cli>
            -DOUTPUT_PATH=${CMAKE_CURRENT_BINARY_DIR}/data/generated/payload-roundtrip.ppi
            -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/pano_cli_save_project_payload_roundtrip.cmake")
    set_tests_properties(pano_cli_save_project_payload_roundtrip_smoke PROPERTIES
        LABELS "assets;document;integration;desktop-fast")

    add_test(NAME pano_cli_save_project_rejects_non_finite_opacity
        COMMAND "${CMAKE_COMMAND}"
            -DPANO_CLI=$<TARGET_FILE:pano_cli>
            -DOUTPUT_PATH=${CMAKE_CURRENT_BINARY_DIR}/data/generated/rejected-non-finite-opacity.ppi
            "-DEXPECTED_OUTPUT=floating-point value must be finite"
            -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/expect_pano_cli_save_project_failure.cmake")
    set_tests_properties(pano_cli_save_project_rejects_non_finite_opacity PROPERTIES
        LABELS "assets;document;integration;desktop-fast;fuzz")

    add_test(NAME pano_cli_save_document_project_roundtrip_smoke
        COMMAND "${CMAKE_COMMAND}"
            -DPANO_CLI=$<TARGET_FILE:pano_cli>
            -DOUTPUT_PATH=${CMAKE_CURRENT_BINARY_DIR}/data/generated/document-export-roundtrip.ppi
            -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/pano_cli_save_document_project_roundtrip.cmake")
    set_tests_properties(pano_cli_save_document_project_roundtrip_smoke PROPERTIES
        LABELS "assets;document;integration;desktop-fast")

    add_test(NAME pano_cli_apply_stroke_script_roundtrip_smoke
        COMMAND "${CMAKE_COMMAND}"
            -DPANO_CLI=$<TARGET_FILE:pano_cli>
            -DSTROKE_SCRIPT=${CMAKE_CURRENT_SOURCE_DIR}/data/strokes/two-strokes.ppstroke
            -DOUTPUT_PATH=${CMAKE_CURRENT_BINARY_DIR}/data/generated/applied-stroke-script.ppi
            -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/pano_cli_apply_stroke_script_roundtrip.cmake")
    set_tests_properties(pano_cli_apply_stroke_script_roundtrip_smoke PROPERTIES
        LABELS "assets;document;paint;integration;desktop-fast")

    add_test(NAME pano_cli_apply_stroke_script_rejects_tiny_canvas
        COMMAND "${CMAKE_COMMAND}"
            -DPANO_CLI=$<TARGET_FILE:pano_cli>
            -DSTROKE_SCRIPT=${CMAKE_CURRENT_SOURCE_DIR}/data/strokes/two-strokes.ppstroke
            -DOUTPUT_PATH=${CMAKE_CURRENT_BINARY_DIR}/data/generated/rejected-applied-stroke-script.ppi
            "-DEXPECTED_OUTPUT=width and height must be between 8 and 4096"
            -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/expect_pano_cli_apply_stroke_script_failure.cmake")
    set_tests_properties(pano_cli_apply_stroke_script_rejects_tiny_canvas PROPERTIES
        LABELS "document;paint;integration;desktop-fast")

    add_test(NAME pano_cli_parse_layout_smoke
        COMMAND pano_cli parse-layout --path "${CMAKE_CURRENT_SOURCE_DIR}/data/layouts/simple-layout.xml")
    set_tests_properties(pano_cli_parse_layout_smoke PROPERTIES
        LABELS "ui;integration;desktop-fast")

    add_test(NAME pano_cli_record_render_smoke
        COMMAND pano_cli record-render --width 32 --height 16)
    set_tests_properties(pano_cli_record_render_smoke PROPERTIES
        LABELS "renderer;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"backend\":\"recording\".*\"framebufferFetch\":false.*\"explicitTextureTransitions\":true.*\"textureCopy\":true.*\"renderTargetBlit\":true.*\"frameCapture\":true.*\"float16RenderTargets\":false.*\"float32RenderTargets\":false.*\"width\":32.*\"height\":16.*\"createdResources\":7.*\"exercisedClearReset\":false.*\"clearRejectedOrphanedTraceEnd\":false.*\"clearReusedRenderPass\":false.*\"labeledCommandDescriptors\":16.*\"commands\":25.*\"openGlPlan\":.*\"available\":true.*\"supported\":true.*\"commands\":25.*\"renderPasses\":1.*\"drawCommands\":1.*\"shaderBindCommands\":1.*\"uniformCommands\":1.*\"textureBindCommands\":1.*\"samplerBindCommands\":1.*\"uploadCommands\":1.*\"mipmapCommands\":1.*\"transitionCommands\":4.*\"copyCommands\":1.*\"readbackCommands\":1.*\"captureCommands\":1.*\"passthroughCommands\":0.*\"traceCommands\":3.*\"unsupportedCommands\":0.*\"renderPassOrderErrors\":0.*\"dependencyErrors\":0.*\"endedInRenderPass\":false.*\"renderPasses\":1.*\"depthClears\":1.*\"stencilClears\":0.*\"drawCommands\":1.*\"drawVertices\":3.*\"drawIndices\":3.*\"scissorCommands\":1.*\"blendCommands\":1.*\"depthCommands\":1.*\"uniformCommands\":1.*\"uniformBytes\":64.*\"bindTextureCommands\":1.*\"bindSamplerCommands\":1.*\"boundTextureBytes\":2048.*\"uploadCommands\":1.*\"uploadBytes\":4.*\"mipmapCommands\":1.*\"mipmapLevels\":3.*\"mipmapBytes\":84.*\"transitionCommands\":4.*\"transitionToUpload\":1.*\"transitionToShaderRead\":2.*\"copyCommands\":1.*\"copySourceBytes\":2048.*\"copyDestinationBytes\":2048.*\"readbackCommands\":1.*\"readbackBytes\":2048.*\"captureCommands\":1.*\"captureBytes\":2048.*\"blitCommands\":1.*\"blitSourceBytes\":2048.*\"blitDestinationBytes\":2048.*\"traceMarkers\":1.*\"traceBeginScopes\":1.*\"traceEndScopes\":1")

    add_test(NAME pano_cli_record_render_exercises_clear_reset
        COMMAND pano_cli record-render --width 32 --height 16 --exercise-clear)
    set_tests_properties(pano_cli_record_render_exercises_clear_reset PROPERTIES
        LABELS "renderer;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"record-render\".*\"exercisedClearReset\":true.*\"clearRejectedOrphanedTraceEnd\":true.*\"clearReusedRenderPass\":true.*\"commands\":25.*\"renderPasses\":1.*\"traceBeginScopes\":1.*\"traceEndScopes\":1")

    add_test(NAME pano_cli_record_render_rejects_oversized_target
        COMMAND "${CMAKE_COMMAND}"
            -DPANO_CLI=$<TARGET_FILE:pano_cli>
            "-DEXPECTED_OUTPUT=texture byte size exceeds the configured limit"
            -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/expect_pano_cli_record_render_failure.cmake")
    set_tests_properties(pano_cli_record_render_rejects_oversized_target PROPERTIES
        LABELS "renderer;integration;desktop-fast")

    add_test(NAME pano_cli_simulate_document_edits_smoke
        COMMAND pano_cli simulate-document-edits --width 128 --height 64)
    set_tests_properties(pano_cli_simulate_document_edits_smoke PROPERTIES
        LABELS "document;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"simulate-document-edits\".*\"document\":\\{\"width\":128,\"height\":64,\"layers\":2,\"frames\":3,\"activeLayer\":0,\"activeFrame\":0,\"animationDurationMs\":683,\"facePayloads\":1,\"selectionMasks\":1\\}.*\"activeLayer\":\\{\"name\":\"Ink\",\"visible\":false,\"alphaLocked\":true,\"opacity\":0.625,\"blendMode\":\"overlay\",\"frames\":3\\}.*\"frames\":\\[250,100,333\\].*\"activeLayerFrameDurations\":\\[250,100,333\\].*\"selectionMask\":\\{\"face\":4,\"x\":3,\"y\":5,\"width\":2,\"height\":2,\"bytes\":4,\"maxAlpha\":255\\}")

    add_test(NAME pano_cli_simulate_document_history_smoke
        COMMAND pano_cli simulate-document-history --width 64 --height 32 --history 4)
    set_tests_properties(pano_cli_simulate_document_history_smoke PROPERTIES
        LABELS "document;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"simulate-document-history\".*\"history\":\\{\"size\":3,\"currentIndex\":2,\"canUndo\":true,\"canRedo\":false\\}.*\"undo\":\\{\"layers\":2,\"frames\":1,\"currentIndex\":1,\"canRedo\":true\\}.*\"current\":\\{\"width\":64,\"height\":32,\"layers\":2,\"frames\":2,\"activeLayer\":1,\"activeFrame\":1,\"animationDurationMs\":350\\}")

    add_test(NAME pano_cli_simulate_document_export_smoke
        COMMAND pano_cli simulate-document-export --width 64 --height 32)
    set_tests_properties(pano_cli_simulate_document_export_smoke PROPERTIES
        LABELS "assets;document;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"simulate-document-export\".*\"source\":\\{\"width\":64,\"height\":32,\"layers\":2,\"frames\":2,\"facePayloads\":2\\}.*\"export\":\\{\"bytes\":[0-9]+,\"dirtyFaces\":2,\"rgbaFacePayloads\":2,\"compressedBytes\":[0-9]+\\}.*\"roundtrip\":\\{\"layers\":2,\"frames\":2,\"facePayloads\":2,\"layerNames\":\\[\"Base\",\"Paint\"\\],\"layerFrameCounts\":\\[2,1\\],\"layerDurationsMs\":\\[350,333\\]\\}.*\"payloads\":\\[\\{\"layer\":0,\"frame\":0,\"face\":0,\"x\":2,\"y\":3,\"bytes\":4,\"alpha\":255\\},\\{\"layer\":1,\"frame\":0,\"face\":5,\"x\":4,\"y\":5,\"bytes\":4,\"alpha\":128\\}\\]")

    add_test(NAME pano_cli_simulate_document_render_smoke
        COMMAND pano_cli simulate-document-render --width 64 --height 32)
    set_tests_properties(pano_cli_simulate_document_render_smoke PROPERTIES
        LABELS "document;renderer;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"simulate-document-render\".*\"source\":\\{\"width\":64,\"height\":32,\"layers\":2,\"frames\":2,\"facePayloads\":2\\}.*\"render\":\\{\"frame\":0,\"width\":64,\"height\":32,\"faces\":6,\"visitedLayers\":2,\"compositedLayerFaces\":1,\"facePayloads\":1.*\\{\"face\":0,\"pixels\":2048,\"payloads\":1,\"nonClearPixels\":1,\"firstNonClear\":\\{\"index\":194,\"x\":2,\"y\":3,\"r\":1,\"g\":0,\"b\":0,\"a\":1\\}\\}.*\\{\"face\":5,\"pixels\":2048,\"payloads\":0,\"nonClearPixels\":0\\}.*\"upload\":\\{\"backend\":\"recording\",\"textures\":6,\"bytes\":49152,\"commands\":12,\"uploadCommands\":6,\"transitionCommands\":6,\"transitions\":6,\"openGlPlan\":\\{\"available\":true,\"supported\":true,\"commands\":12,\"uploadCommands\":6,\"transitionCommands\":6,\"unsupportedCommands\":0,\"renderPassOrderErrors\":0,\"dependencyErrors\":0\\}")

    add_test(NAME pano_cli_simulate_image_import_smoke
        COMMAND pano_cli simulate-image-import --width 64 --height 32)
    set_tests_properties(pano_cli_simulate_image_import_smoke PROPERTIES
        LABELS "assets;document;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"simulate-image-import\".*\"image\":\\{\"format\":\"png\",\"width\":1,\"height\":1,\"bytes\":4,\"alpha\":0\\}.*\"document\":\\{\"width\":64,\"height\":32,\"layers\":1,\"frames\":1,\"facePayloads\":1\\}.*\"payload\":\\{\"face\":0,\"x\":0,\"y\":0,\"width\":1,\"height\":1,\"bytes\":4\\}")

    add_test(NAME pano_cli_simulate_blend_smoke
        COMMAND pano_cli simulate-blend)
    set_tests_properties(pano_cli_simulate_blend_smoke PROPERTIES
        LABELS "paint;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"command\":\"simulate-blend\".*\"finalBlendModes\":5.*\"strokeBlendModes\":11.*\"normal\":\\{\"r\":0.44,\"g\":0.32,\"b\":0.4,\"a\":0.625\\}.*\"multiply\":\\{\"r\":0.125,\"g\":0.25,\"b\":0.375,\"a\":1\\}.*\"stroke\":\\{\"normal\":0.35,\"linearHeight\":0.637171,\"height\":0.228217,\"unknown\":1\\}")

    add_test(NAME pano_cli_simulate_stroke_smoke
        COMMAND pano_cli simulate-stroke --x1 0 --y1 0 --x2 10 --y2 0 --spacing 2)
    set_tests_properties(pano_cli_simulate_stroke_smoke PROPERTIES
        LABELS "paint;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"samples\":6.*\"distance\":10")

    add_test(NAME pano_cli_simulate_stroke_script_smoke
        COMMAND pano_cli simulate-stroke-script --path "${CMAKE_CURRENT_SOURCE_DIR}/data/strokes/two-strokes.ppstroke")
    set_tests_properties(pano_cli_simulate_stroke_script_smoke PROPERTIES
        LABELS "paint;integration;desktop-fast"
        PASS_REGULAR_EXPRESSION "\"strokes\":2.*\"samples\":9.*\"distance\":20")
endif()
