All notable changes to this project will be documented in this file.
- AutoCAD-family discovery reads
HKLM\SOFTWARE\Autodesk\AutoCAD\*\InstalledProducts. The default value is the install directory. The subkey is the product code (ACAD,C3D,PLNT3D,ACA,ACADM,MEP,ACADE,MAP). The year is the last token of the folder name (AutoCAD 2026,Civil 3D 2026), at or above 2022. The filesystem fallback applies only toautocad. - Revit discovery lives in its own resolver:
Autodesk Revit {version}in the registry, thenRevit {version}on disk. host_nameis the only key. The names are the lowercaseHostAppvalues (Civil3D→civil3d) and are declared once inconstants.py.HOST_REGISTRYand the AutoCAD product-code map both use those constants.HostConfigkeepspipe_prefix,exe_name, andlaunch_args. Install paths stay in the resolver for that host.- Requires
pytest>=9.1.1,<10andpywin32>=312, matching the host pixi runtime.
find_host_executable(). Callers usefind_executable(host_name, version).HostConfig.acad_product_codeandis_acad_family().- Registry product-id lookup (
ACAD-XXNN,UPIRELEASE,GlobUPILocation,AcadLocation).
- A local plugin test run no longer swallows pytest's own test loop when the session has no remote results.
- IronPython tests: files named
test_*_ipy.pyrun on the host viaipytests/run(unittest). CPythontest_*.pystill usestests/run. - CPython and IronPython suites in the same workspace reuse one host instance.
- Pipe name is
DevTools_{Host}_{Version}_{PID}(was{Host}_{Version}_{PID}). Pytest does not use the MCP pipeDevToolsMcp_*. - CLI/INI names match RevitDevTool.TestAdapter (breaking vs 0.3.0):
--host-launch→--force-launch,--host-timeout→--per-test-timeout,--host-launch-timeout→--launch-timeout.--host/--host-versionunchanged. - PEP 723
# /// scriptis installed only for CPythontests/run. IronPython tests cannot use CPython wheels.
- Multi-host support: plugin now supports Revit, AutoCAD, Civil3D, Plant3D, Navisworks, Rhino, Tekla, and any host exposing a DevToolsPipeServer Named Pipe.
--hostoption: new CLI flag andhost_nameINI key to select the target host application (default:revit).HostConfigdataclass: centralized executable discovery and launch configuration per host product, stored inHOST_REGISTRY.- AutoCAD-family executable discovery: registry-based resolver mirrors C#
AcadPathResolver— enumeratesHKLM\SOFTWARE\Autodesk\AutoCADreleases, matches product IDs (ACAD-XXNN), resolves install path viaGlobUPILocation/AcadLocation. - Open host registry:
get_host_config()returns a fallbackHostConfig(pipe_prefix=host_name)for unknown host names — any host with a DevToolsPipeServer pipe works without pre-registration. - Multi-host dialog resolver:
StartupDialogResolverkeywords expanded to cover AutoCAD, Civil, and Plant startup dialogs.
- CLI/INI options renamed: all
--revit-*/revit_*options replaced with--host-*/host_*equivalents (--host-version,--host-timeout,--host-pipe,--host-launch,--host-launch-timeout). - Flexible pipe pattern:
PIPE_PATTERNchanged from^\w+_\d{4}_\d+$to^\w+_[^_]+_\d+$— version segment accepts any non-underscore string (year, semver, dotted), matching C#InstanceManager. HostInstance.versiontype: changed frominttostrto support non-year version formats (e.g.8.0,2024.1,v3.2.1).--host-versionaccepts string: no longer restricted to 4-digit year integers.RevitBridge→HostBridge: bridge class renamed for host-agnostic semantics.RevitInstance→HostInstance: discovery dataclass renamed.find_revit_pipes()→find_host_pipes(): accepts optionalhost_namefilter; returns all matching pipes including unregistered prefixes.find_revit_path()→find_host_executable(): dispatches to Revit registry, AutoCAD-family registry, or returnsNonefor hosts without exe discovery.start_revit()→start_host(): usesHostConfig.launch_argsper host.wait_for_revit_pipe()→wait_for_host_pipe(): host-agnostic pipe polling.HostConfig.exe_nameoptional: hosts without a known executable (Rhino, Tekla, etc.) connect via pipe auto-discovery or--host-pipeonly.is_process_alive(): handlesexe_name=Nonegracefully — checks PID liveness without executable name verification.
_opt_int()helper: version is now parsed as string, no integer conversion needed.
0.3.0is a breaking change from0.2.x: all CLI flags and INI keys are renamed. Existingrevit_*/--revit-*options are no longer recognized.- The pipe pattern is now aligned with the C#
InstanceManager.HostPipePatternregex (^\w+_[^_]+_\d+$). - Revit users: add
host_name = "revit"topyproject.toml(or rely on the default).
- Auto print capture: plugin automatically enables
-rPbehavior — capturedprint()output is shown for both passing and failing tests without any user configuration. - PID-aware pipe discovery:
wait_for_revit_pipecan now wait for a specific process ID, ensuringforce_launchconnects to the newly spawned instance only.
revit_launch→ force_launch semantics: renamed internal parameter fromprefer_freshtoforce_launch. When enabled, the plugin disconnects any existing bridge, spawns a new Revit instance, and waits for that exact PID's pipe — never reuses existing instances._opt_boolfix: corrected boolean option parsing sorevit_launch = trueinpyproject.tomlis properly respected when no CLI flag is explicitly passed.- Type annotations refactor: resolved false-positive IDE warnings across
bridge.py,connection.py,suite_leasing.py, anddialog_resolver.py. SetupRevit.py(Revit-side): I/O hijacking is now conditional onsys.__pytest_running__flag — prevents conflict with pytest capture during test execution.PytestRunner.py(Revit-side): setssys.__pytest_running__ = Trueduring execution; top-level error handling wraps entire_run()to always return structured JSON.
discover_tests()method frombridge.py(client-side dead code; server endpoint remains).DiscoverRequest/DiscoverResponseclasses frommodels.py(unused by client).BRIDGE_METHOD_TESTS_DISCOVERconstant (no longer referenced).resolve_existing()/get_suite_process_id()/_prune_stale()fromsuite_leasing.py(unused).launch_revit()fromdiscovery.py(replaced bystart_revit+ PID tracking).addopts = "-rP"frompyproject.toml(now automatic via plugin).
revit_launch = truein INI ignored:_opt_boolnow correctly reads INI value when CLI flag is not explicitly set.
- Real-time streaming: test progress notifications streamed from Revit to the pytest client during execution.
- Suite leasing: Windows Mutex-based exclusive access prevents multiple pytest processes from connecting to the same Revit instance.
- Test discovery:
PytestRunRequest+_BridgePluginintegration enables--collect-onlydiscovery without executing tests. - Reporting module: remote
CaseResult[]mapping back to pytestTestReport, withrun_remote_sessionorchestrating discover + run. - Connection module: centralized
ensure_bridge()with auto-connect, lease management, and Revit auto-launch flow. - Schedule API tests: comprehensive test suite for Revit schedule operations (copy, field mapping, header, template, custom workflow).
- Image export tests:
test_image_export.pycoveringRevitImageExporter. - Document & transaction tests:
test_revit_document.py,test_revit_transactions.py. - Session cleanliness tests:
test_session_cleanliness.py,test_active_state.pyverifying state isolation between runs. - Streaming tests:
test_streaming.pyvalidating progress notification flow. - Dependencies tests:
test_dependencies.pyverifying package resolution. - GitNexus integration: AGENTS.md, CLAUDE.md, and CLI skills for graph-based code intelligence.
- Project setup guide: recommended
uvandpixiworkflows in README.
- Architecture rewrite:
plugin.pyrestructured — execution now intercepted viapytest_runtestloopinstead ofpytest_pyfunc_call. Remote session orchestrates discover + run in a single round-trip. - Configuration: primary config via
[tool.pytest.ini_options]inpyproject.toml— CLI flags remain as overrides. bridge.py: expanded withdiscover_tests(),run_tests(), notification dispatch, frame protocol hardening.models.py: newDiscoverRequest,RunRequest,RunResponse,CaseResult,CollectionErrorcontracts.constants.py: centralized all bridge methods, option names, timeouts, pipe patterns.pyproject.toml: bumpedrevit_launch_timeoutto 180s, addedrevit_timeoutdefault.
serializer.py: deprecated — test code serialization replaced by structured discovery + run flow..vscode/settings.json: removed from repo; config lives inpyproject.toml.
0.1.0represents a major architectural shift from single-test relay to session-oriented orchestration. The plugin now discovers tests remotely, runs them in batch, and streams progress back in real-time.- Suite leasing ensures safe concurrent usage across multiple test suits targeting the same Revit year.
- Fixed Revit auto-launch dialog handling by starting the startup dialog resolver immediately after spawning Revit, before waiting for the named pipe.
- Fixed startup dialog button selection to prefer safe allow-list actions such as
Always LoadandLoad Once. - Prevented accidental clicks on destructive dialog actions such as
Do Not Load,Cancel, andNo.
- This release focuses on reliable auto-launch behavior when Revit shows unsigned add-in security dialogs during startup.
- Fixed pytest plugin auto-loading via the
pytest11entry point. - Fixed the
pytest_unconfigurehook signature inrevitdevtool_pytest.pluginso Pluggy accepts the plugin during pytest startup. - Restored the expected standalone package behavior so
RevitDevTool.PyTestcan be discovered and activated by a normal Python/pytest environment before connecting to Revit.
- Aligned the published package metadata name with the recommended normalized package name
revitdevtool_pytest.
- This release is intended as a bugfix release for the
0.0.1package. - No user-facing CLI options are changed in this release.
- This name alignment is intended to remain compatible with existing PyPI installs because Python package indexes and installers normalize
.,-, and_in distribution names.
- Initial standalone
pytestplugin package for running Revit API tests through the RevitDevTool Named Pipe bridge. - Automatic discovery of running Revit instances through named pipes.
- Optional Revit auto-launch flow via
--revit-launchand--revit-version. - Remote test execution by intercepting
pytest_pyfunc_calland forwarding serialized test code to Revit. - Support for explicit pipe targeting with
--revit-pipe. - Per-test timeout and launch timeout configuration.
- Revit startup dialog resolver integration.
- Example test suite and VS Code integration guidance in the project documentation.
0.0.1introduced the core test bridge workflow, but the published package contains a plugin loading issue fixed in0.0.2.