[CmdletBinding()] param( [string]$ModelPath, [int]$ServiceStartupTimeoutSeconds = 90, [int]$TestTimeoutSeconds = 240 ) $ErrorActionPreference = 'Stop' $scriptDirectory = Split-Path -Parent $MyInvocation.MyCommand.Path $repoRoot = Split-Path -Parent $scriptDirectory $startScriptPath = Join-Path $scriptDirectory 'start-navisworks.ps1' $defaultsFilePath = Join-Path $scriptDirectory 'test-automation.defaults.json' $testApiBaseUrl = 'http://127.0.0.1:18777' function Resolve-DefaultModelPath { if (-not (Test-Path $defaultsFilePath)) { return $null } $defaults = Get-Content $defaultsFilePath -Raw | ConvertFrom-Json $defaultModelPath = [string]$defaults.defaultModelPath if ([string]::IsNullOrWhiteSpace($defaultModelPath)) { return $null } return [System.IO.Path]::GetFullPath($defaultModelPath) } function Wait-TestApiReady { param( [string]$BaseUrl, [int]$TimeoutSeconds ) $deadline = (Get-Date).AddSeconds($TimeoutSeconds) $lastError = $null while ((Get-Date) -lt $deadline) { try { $pingResponse = Invoke-RestMethod -Uri ($BaseUrl + '/api/test/ping') -TimeoutSec 10 if ($pingResponse.ok) { return } } catch { $lastError = $_.Exception.Message } Start-Sleep -Seconds 1 } if ([string]::IsNullOrWhiteSpace($lastError)) { throw "测试 HTTP 服务未在 $TimeoutSeconds 秒内就绪。" } throw "测试 HTTP 服务未在 $TimeoutSeconds 秒内就绪。最后错误: $lastError" } function Wait-GroundRouteReady { param( [string]$BaseUrl, [int]$TimeoutSeconds ) $deadline = (Get-Date).AddSeconds($TimeoutSeconds) $lastError = $null while ((Get-Date) -lt $deadline) { try { $routesResponse = Invoke-RestMethod -Uri ($BaseUrl + '/api/test/routes') -TimeoutSec 10 if ($routesResponse.ok -and $routesResponse.data -and $routesResponse.data.totalRouteCount -gt 0) { $groundRoute = $routesResponse.data.suggestedAutoTestRoutes.ground if (-not [string]::IsNullOrWhiteSpace([string]$groundRoute)) { return [string]$groundRoute } } } catch { $lastError = $_.Exception.Message } Start-Sleep -Seconds 1 } if ([string]::IsNullOrWhiteSpace($lastError)) { throw "默认地面测试路径未在 $TimeoutSeconds 秒内就绪。" } throw "默认地面测试路径未在 $TimeoutSeconds 秒内就绪。最后错误: $lastError" } function Save-JsonResult { param( [object]$Payload ) $logRoot = Join-Path $env:ProgramData 'Autodesk\Navisworks Manage 2026\plugins\TransportPlugin\logs\test-automation' New-Item -ItemType Directory -Path $logRoot -Force | Out-Null $fileName = 'ground-virtual-collision-test-' + (Get-Date -Format 'yyyyMMdd-HHmmss') + '.json' $outputPath = Join-Path $logRoot $fileName $json = $Payload | ConvertTo-Json -Depth 16 [System.IO.File]::WriteAllText($outputPath, $json, [System.Text.UTF8Encoding]::new($false)) return $outputPath } 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" } } Write-Host '启动 Navisworks...' if ([string]::IsNullOrWhiteSpace($ModelPath)) { & $startScriptPath } else { & $startScriptPath $ModelPath } Write-Host '等待测试 HTTP 服务就绪...' Wait-TestApiReady -BaseUrl $testApiBaseUrl -TimeoutSeconds $ServiceStartupTimeoutSeconds Write-Host '等待默认地面测试路径就绪...' $groundRouteName = Wait-GroundRouteReady -BaseUrl $testApiBaseUrl -TimeoutSeconds $ServiceStartupTimeoutSeconds Write-Host ('切换到默认地面测试路径: {0}' -f $groundRouteName) $selectRouteResponse = Invoke-RestMethod -Method Post -Uri ($testApiBaseUrl + '/api/test/select-default-route?pathType=Ground') -TimeoutSec 15 if (-not $selectRouteResponse.ok) { throw '切换默认地面测试路径失败。' } Write-Host '执行地面虚拟物体碰撞测试...' $requestUrl = $testApiBaseUrl + "/api/test/run-ground-collision-test?useVirtualObject=true&timeoutSeconds=$TestTimeoutSeconds" $testResult = Invoke-RestMethod -Method Post -Uri $requestUrl -TimeoutSec ($TestTimeoutSeconds + 30) $outputFilePath = Save-JsonResult -Payload $testResult Write-Host ('结果已保存: {0}' -f $outputFilePath) if ($testResult.ok -and $testResult.data) { Write-Host ('路径: {0}' -f $testResult.data.route.name) Write-Host ('动画状态: {0}' -f $testResult.data.animation.currentState) Write-Host ('检测记录ID: {0}' -f $testResult.data.animation.detectionRecordId) if ($testResult.data.report) { Write-Host ('碰撞数: {0}' -f $testResult.data.report.totalCollisions) Write-Host ('截图数: {0}' -f $testResult.data.report.screenshotCount) } }