NavisworksTransport/scripts/start-navisworks.ps1
tian 44214baa00 feat: 集成测试补 T05/T06 + 动画加速与多项基础设施修复
测试新增:
- T05 Free 自由路径(FreePathAutomationTests:完整动画 + 逐帧位置=路径点)
- T06 碰撞报告内容断言(CollisionReportAssertions 接入虚拟/真实物体测试)

服务端增强:
- list-model-items 端点(枚举物体:DisplayName/PathId/包围盒中心/祖先链)
- run-virtual-collision-test 支持 frameRate/durationSeconds(测试动画加速:15fps/5s)
- 测试执行串行锁(SemaphoreSlim,防客户端超时后任务占用 UI 线程并发污染)
- 标准路径清单/XML 增加自动测试_Free

Bug 修复:
- AnimationControlViewModel.InvalidateLastGeneratedReport(跨测试碰撞报告残留)
- 真实物体身份校验 ReferenceEquals→InstanceGuid(NW ModelItem 实例不保证同引用)
- 真实物体动态解析(ModelPath 跨会话不稳定,禁止硬编码 PathId)
- PathImportValidity 测试点 Id 随机化(PathPoints.Id 全局主键,p1/p2 固定会冲突)
- start-navisworks.ps1:启动前清理 AutoSave(避免恢复弹窗拦截)、文件关联打开模型、dismiss 兜底、启动 15s→4.4s

验证:集成测试 13/13 通过,完整集 6min→59.6s(动画 15fps/5s)
2026-08-04 18:13:26 +08:00

182 lines
6.6 KiB
PowerShell
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[CmdletBinding()]
param(
[Parameter(Position = 0)]
[string]$ModelPath
)
$ErrorActionPreference = 'Stop'
$scriptDirectory = Split-Path -Parent $MyInvocation.MyCommand.Path
$repoRoot = Split-Path -Parent $scriptDirectory
$defaultsFilePath = Join-Path $scriptDirectory 'test-automation.defaults.json'
function Resolve-RoamerPath {
$candidates = New-Object System.Collections.Generic.List[string]
$appPathKeys = @(
'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\Roamer.exe',
'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\App Paths\Roamer.exe'
)
foreach ($key in $appPathKeys) {
try {
$value = (Get-ItemProperty -Path $key -ErrorAction Stop).'(default)'
if (-not [string]::IsNullOrWhiteSpace($value)) {
$candidates.Add($value)
}
}
catch {
}
}
$wellKnownPaths = @(
(Join-Path ${env:ProgramFiles} 'Autodesk\Navisworks Manage 2026\Roamer.exe'),
(Join-Path ${env:ProgramFiles(x86)} 'Autodesk\Navisworks Manage 2026\Roamer.exe'),
(Join-Path ${env:ProgramFiles} 'Autodesk\Navisworks Simulate 2026\Roamer.exe'),
(Join-Path ${env:ProgramFiles(x86)} 'Autodesk\Navisworks Simulate 2026\Roamer.exe')
) | Where-Object { $_ }
foreach ($path in $wellKnownPaths) {
$candidates.Add($path)
}
foreach ($candidate in $candidates | Select-Object -Unique) {
if (-not [string]::IsNullOrWhiteSpace($candidate) -and (Test-Path $candidate)) {
return [System.IO.Path]::GetFullPath($candidate)
}
}
throw '找不到 Roamer.exe。请确认 Navisworks Manage 2026 已安装。'
}
function Resolve-DefaultModelPath {
if (-not (Test-Path $defaultsFilePath)) {
return $null
}
try {
$defaults = Get-Content $defaultsFilePath -Raw | ConvertFrom-Json
$defaultModelPath = [string]$defaults.defaultModelPath
if ([string]::IsNullOrWhiteSpace($defaultModelPath)) {
return $null
}
$resolvedPath = [System.IO.Path]::GetFullPath($defaultModelPath)
if (-not (Test-Path $resolvedPath)) {
throw "默认模型文件不存在: $resolvedPath"
}
return $resolvedPath
}
catch {
throw "读取默认测试配置失败: $($_.Exception.Message)"
}
}
function Dismiss-RecoveryPromptIfPresent {
param(
[int]$TimeoutSeconds = 20
)
Add-Type -AssemblyName System.Windows.Forms | Out-Null
$shell = New-Object -ComObject WScript.Shell
# NW 启动恢复提示框标题关键词(覆盖“从自动保存重新载入”“是否打开之前保存的模型”等变体)
$windowTitleKeywords = @(
'自动保存',
'保存的模型',
'重新载入',
'恢复'
)
$deadline = (Get-Date).AddSeconds($TimeoutSeconds)
while ((Get-Date) -lt $deadline) {
foreach ($keyword in $windowTitleKeywords) {
try {
# AppActivate 支持子串匹配,激活标题包含关键词的窗口
if ($shell.AppActivate($keyword)) {
Start-Sleep -Milliseconds 300
[System.Windows.Forms.SendKeys]::SendWait('%N')
Write-Host "已自动选择“否”以跳过恢复提示框(关键词: $keyword)。"
return
}
}
catch {
}
}
Start-Sleep -Milliseconds 300
}
}
function Clear-NavisworksAutoSave {
# 清理 NW 自动保存文件NW 启动时检测到 AutoSave 残留会弹“是否打开之前保存的模型”
# 提示框并拦截命令行打开请求。测试环境提前清理可彻底避免弹窗(测试前先正常退出 NW 以保存用户数据)。
$autoSaveDir = Join-Path $env:APPDATA 'Autodesk\Navisworks Manage 2026\AutoSave'
if (Test-Path $autoSaveDir) {
$removedCount = (Get-ChildItem $autoSaveDir -File -ErrorAction SilentlyContinue | Remove-Item -Force -ErrorAction SilentlyContinue | Measure-Object).Count
Write-Host "已清理 Navisworks 自动保存文件(避免恢复提示框): $autoSaveDir"
}
}
if ([string]::IsNullOrWhiteSpace($ModelPath)) {
$ModelPath = Resolve-DefaultModelPath
}
if (-not [string]::IsNullOrWhiteSpace($ModelPath)) {
$ModelPath = [System.IO.Path]::GetFullPath($ModelPath)
if (-not (Test-Path $ModelPath)) {
throw "模型文件不存在: $ModelPath"
}
}
$roamerPath = Resolve-RoamerPath
$existingProcess = Get-Process Roamer -ErrorAction SilentlyContinue | Select-Object -First 1
$env:TRANSPORTPLUGIN_TEST_AUTOMATION = '1'
if ($existingProcess) {
Write-Host ("Navisworks 已在运行PID={0}" -f $existingProcess.Id)
if (-not [string]::IsNullOrWhiteSpace($ModelPath)) {
# 通过文件关联请求打开模型Start-Process 传参对 NW 2026 不可靠)
Start-Process -FilePath $ModelPath | Out-Null
Write-Host ("已请求 Navisworks 打开模型: {0}" -f $ModelPath)
}
Dismiss-RecoveryPromptIfPresent -TimeoutSeconds 30
Write-Host '提示: 当前测试 HTTP 服务在插件 DockPane OnLoaded 中启动,首次测试前请确保插件面板已打开。'
exit 0
}
# 启动前清理自动保存文件,避免 NW 弹出恢复提示框(弹窗会拦截命令行打开模型)
Clear-NavisworksAutoSave
if (-not [string]::IsNullOrWhiteSpace($ModelPath)) {
# 直接通过文件关联启动并打开模型NW 2026 命令行传参打开文件不可靠)
$startProcess = Start-Process -FilePath $ModelPath -PassThru
$processId = $startProcess.Id
Write-Host ("Navisworks 启动中文件关联PID={0}" -f $processId)
}
else {
$process = Start-Process -FilePath $roamerPath -PassThru
$processId = $process.Id
Write-Host ("Navisworks 启动中PID={0}" -f $processId)
}
$deadline = (Get-Date).AddSeconds(30)
do {
Start-Sleep -Milliseconds 500
$running = Get-Process -Id $processId -ErrorAction SilentlyContinue
} while (-not $running -and (Get-Date) -lt $deadline)
if (-not $running) {
throw 'Navisworks 启动超时30 秒内未检测到 Roamer.exe 进程。'
}
# 兜底:清理 AutoSave 后通常无恢复弹窗;短超时单次处理可能出现的其他提示框
Dismiss-RecoveryPromptIfPresent -TimeoutSeconds 3
Write-Host ("Navisworks 已启动: {0}" -f $roamerPath)
if (-not [string]::IsNullOrWhiteSpace($ModelPath)) {
Write-Host ("已打开模型参数: {0}" -f $ModelPath)
}
Write-Host '提示: 当前测试 HTTP 服务在插件 DockPane OnLoaded 中启动,首次测试前请确保插件面板已打开。'