diff --git a/.github/workflows/test-run-android.yml b/.github/workflows/test-run-android.yml
index b73168f32..6f86b1216 100644
--- a/.github/workflows/test-run-android.yml
+++ b/.github/workflows/test-run-android.yml
@@ -95,7 +95,7 @@ jobs:
adb wait-for-device
adb shell input keyevent 82
adb devices -l
- pwsh -Command '$env:SENTRY_TEST_APK = "samples/IntegrationTest/Build/test.apk"; Invoke-Pester -Path test/IntegrationTest/Integration.Tests.ps1 -CI'
+ pwsh -Command '$env:SENTRY_TEST_PLATFORM = "Android"; $env:SENTRY_TEST_APP = "samples/IntegrationTest/Build/test.apk"; Invoke-Pester -Path test/IntegrationTest/Integration.Tests.ps1 -CI'
- name: Upload test results on failure
if: ${{ failure() }}
diff --git a/.github/workflows/test-run-desktop.yml b/.github/workflows/test-run-desktop.yml
index 283312350..a9da553d2 100644
--- a/.github/workflows/test-run-desktop.yml
+++ b/.github/workflows/test-run-desktop.yml
@@ -48,16 +48,18 @@ jobs:
timeout-minutes: 20
run: |
xvfb-run pwsh -Command '
+ $env:SENTRY_TEST_PLATFORM = "Desktop";
$env:SENTRY_TEST_APP = "samples/IntegrationTest/Build/test";
- Invoke-Pester -Path test/IntegrationTest/Integration.Tests.Desktop.ps1 -CI'
+ Invoke-Pester -Path test/IntegrationTest/Integration.Tests.ps1 -CI'
shell: bash
- name: Run Integration Tests (Windows)
if: inputs.platform == 'windows'
timeout-minutes: 20
run: |
+ $env:SENTRY_TEST_PLATFORM = "Desktop"
$env:SENTRY_TEST_APP = "samples/IntegrationTest/Build/test.exe"
- Invoke-Pester -Path test/IntegrationTest/Integration.Tests.Desktop.ps1 -CI
+ Invoke-Pester -Path test/IntegrationTest/Integration.Tests.ps1 -CI
- name: Upload test results on failure
if: ${{ failure() }}
diff --git a/.github/workflows/test-run-ios.yml b/.github/workflows/test-run-ios.yml
index e3e320c4f..83d639d9d 100644
--- a/.github/workflows/test-run-ios.yml
+++ b/.github/workflows/test-run-ios.yml
@@ -64,9 +64,10 @@ jobs:
id: integration-test
timeout-minutes: 20
run: |
+ $env:SENTRY_TEST_PLATFORM = "iOS"
$env:SENTRY_TEST_APP = "samples/IntegrationTest/Build/IntegrationTest.app"
$env:SENTRY_IOS_VERSION = "${{ inputs.ios-version }}"
- Invoke-Pester -Path test/IntegrationTest/Integration.Tests.iOS.ps1 -CI
+ Invoke-Pester -Path test/IntegrationTest/Integration.Tests.ps1 -CI
echo "status=success" >> $env:GITHUB_OUTPUT
- name: Upload test results on failure
diff --git a/.github/workflows/test-run-webgl.yml b/.github/workflows/test-run-webgl.yml
index 5afc4fc9c..78d82e806 100644
--- a/.github/workflows/test-run-webgl.yml
+++ b/.github/workflows/test-run-webgl.yml
@@ -41,8 +41,9 @@ jobs:
- name: Run Integration Tests
timeout-minutes: 20
run: |
- $env:SENTRY_WEBGL_BUILD_PATH = "samples/IntegrationTest/Build"
- Invoke-Pester -Path test/IntegrationTest/Integration.Tests.WebGL.ps1 -CI
+ $env:SENTRY_TEST_PLATFORM = "WebGL"
+ $env:SENTRY_TEST_APP = "samples/IntegrationTest/Build"
+ Invoke-Pester -Path test/IntegrationTest/Integration.Tests.ps1 -CI
- name: Upload test results on failure
if: ${{ failure() }}
diff --git a/Directory.Build.targets b/Directory.Build.targets
index f9cad2841..9375f617a 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -379,7 +379,7 @@ Related: https://forum.unity.com/threads/6572-debugger-agent-unable-to-listen-on
-
+
diff --git a/test/IntegrationTest/Integration.Tests.Desktop.ps1 b/test/IntegrationTest/Integration.Tests.Desktop.ps1
deleted file mode 100644
index 11b3e82e6..000000000
--- a/test/IntegrationTest/Integration.Tests.Desktop.ps1
+++ /dev/null
@@ -1,208 +0,0 @@
-#!/usr/bin/env pwsh
-#
-# Integration tests for Sentry Unity SDK (Desktop: Windows, Linux)
-#
-# Environment variables:
-# SENTRY_TEST_APP: path to the test executable
-# SENTRY_TEST_DSN: test DSN
-# SENTRY_AUTH_TOKEN: authentication token for Sentry API
-
-Set-StrictMode -Version latest
-$ErrorActionPreference = "Stop"
-
-# Import app-runner modules
-. $PSScriptRoot/../../modules/app-runner/import-modules.ps1
-
-# Import shared test cases and utility functions
-. $PSScriptRoot/CommonTestCases.ps1
-
-BeforeAll {
- # Run integration test action on device
- function Invoke-TestAction {
- param (
- [Parameter(Mandatory=$true)]
- [string]$Action
- )
-
- Write-Host "Running $Action..."
-
- $appArgs = @("--test", $Action, "-logFile", "-")
-
- $runResult = Invoke-DeviceApp -ExecutablePath $env:SENTRY_TEST_APP -Arguments $appArgs
-
- # Save result to JSON file
- $runResult | ConvertTo-Json -Depth 5 | Out-File -FilePath (Get-OutputFilePath "${Action}-result.json")
-
- # Launch app again to ensure crash report is sent
- if ($Action -eq "crash-capture") {
- Write-Host "Running crash-send to ensure crash report is sent..."
-
- $sendArgs = @("--test", "crash-send", "-logFile", "-")
- $sendResult = Invoke-DeviceApp -ExecutablePath $env:SENTRY_TEST_APP -Arguments $sendArgs
-
- # Save crash-send result to JSON for debugging
- $sendResult | ConvertTo-Json -Depth 5 | Out-File -FilePath (Get-OutputFilePath "crash-send-result.json")
-
- # Print crash-send output
- Write-Host "::group::App output (crash-send)"
- $sendResult.Output | ForEach-Object { Write-Host $_ }
- Write-Host "::endgroup::"
-
- # Attach to runResult for test access
- $runResult | Add-Member -NotePropertyName "CrashSendOutput" -NotePropertyValue $sendResult.Output
- }
-
- # Print app output so it's visible in CI logs
- Write-Host "::group::App output ($Action)"
- $runResult.Output | ForEach-Object { Write-Host $_ }
- Write-Host "::endgroup::"
-
- return $runResult
- }
-
- # Create directory for the test results
- New-Item -ItemType Directory -Path "$PSScriptRoot/results/" -ErrorAction Continue 2>&1 | Out-Null
- Set-OutputDir -Path "$PSScriptRoot/results/"
-
- # Initialize test parameters
- $script:TestSetup = [PSCustomObject]@{
- Platform = "Desktop"
- AppPath = $env:SENTRY_TEST_APP
- Dsn = $env:SENTRY_TEST_DSN
- AuthToken = $env:SENTRY_AUTH_TOKEN
- }
-
- # Validate environment
- if ([string]::IsNullOrEmpty($script:TestSetup.AppPath)) {
- throw "SENTRY_TEST_APP environment variable is not set."
- }
- if (-not (Test-Path $script:TestSetup.AppPath)) {
- throw "App not found at: $($script:TestSetup.AppPath)"
- }
- if ([string]::IsNullOrEmpty($script:TestSetup.Dsn)) {
- throw "SENTRY_TEST_DSN environment variable is not set."
- }
- if ([string]::IsNullOrEmpty($script:TestSetup.AuthToken)) {
- throw "SENTRY_AUTH_TOKEN environment variable is not set."
- }
-
- Connect-SentryApi `
- -ApiToken $script:TestSetup.AuthToken `
- -DSN $script:TestSetup.Dsn
-
- Connect-Device -Platform "Local"
-}
-
-
-AfterAll {
- Disconnect-SentryApi
- Disconnect-Device
-}
-
-
-Describe "Unity Desktop Integration Tests" {
-
- Context "Message Capture" {
- BeforeAll {
- $script:runEvent = $null
- $script:runResult = Invoke-TestAction -Action "message-capture"
-
- $eventId = Get-EventIds -AppOutput $script:runResult.Output -ExpectedCount 1
- if ($eventId) {
- Write-Host "::group::Getting event content"
- $script:runEvent = Get-SentryTestEvent -EventId "$eventId"
- Write-Host "::endgroup::"
- }
- }
-
- It "" -ForEach $CommonTestCases {
- & $testBlock -SentryEvent $runEvent -TestType "message-capture" -RunResult $runResult -TestSetup $script:TestSetup
- }
-
- It "Has message level info" {
- ($runEvent.tags | Where-Object { $_.key -eq "level" }).value | Should -Be "info"
- }
-
- It "Has message content" {
- $runEvent.title | Should -Not -BeNullOrEmpty
- }
- }
-
- Context "Exception Capture" {
- BeforeAll {
- $script:runEvent = $null
- $script:runResult = Invoke-TestAction -Action "exception-capture"
-
- $eventId = Get-EventIds -AppOutput $script:runResult.Output -ExpectedCount 1
- if ($eventId) {
- Write-Host "::group::Getting event content"
- $script:runEvent = Get-SentryTestEvent -EventId "$eventId"
- Write-Host "::endgroup::"
- }
- }
-
- It "" -ForEach $CommonTestCases {
- & $testBlock -SentryEvent $runEvent -TestType "exception-capture" -RunResult $runResult -TestSetup $script:TestSetup
- }
-
- It "Has exception information" {
- $runEvent.exception | Should -Not -BeNullOrEmpty
- $runEvent.exception.values | Should -Not -BeNullOrEmpty
- }
-
- It "Has exception with stacktrace" {
- $exception = $runEvent.exception.values[0]
- $exception | Should -Not -BeNullOrEmpty
- $exception.type | Should -Not -BeNullOrEmpty
- $exception.stacktrace | Should -Not -BeNullOrEmpty
- }
-
- It "Has error level" {
- ($runEvent.tags | Where-Object { $_.key -eq "level" }).value | Should -Be "error"
- }
- }
-
- Context "Crash Capture" {
- BeforeAll {
- $script:runEvent = $null
- $script:runResult = Invoke-TestAction -Action "crash-capture"
-
- $eventId = Get-EventIds -AppOutput $script:runResult.Output -ExpectedCount 1
- if ($eventId) {
- Write-Host "::group::Getting event content"
- $script:runEvent = Get-SentryTestEvent -TagName "test.crash_id" -TagValue "$eventId" -TimeoutSeconds 120
- Write-Host "::endgroup::"
- }
- }
-
- It "" -ForEach $CommonTestCases {
- & $testBlock -SentryEvent $runEvent -TestType "crash-capture" -RunResult $runResult -TestSetup $script:TestSetup
- }
-
- It "Has fatal level" {
- ($runEvent.tags | Where-Object { $_.key -eq "level" }).value | Should -Be "fatal"
- }
-
- It "Has exception with stacktrace" {
- $runEvent.exception | Should -Not -BeNullOrEmpty
- $runEvent.exception.values | Should -Not -BeNullOrEmpty
- $exception = $runEvent.exception.values[0]
- $exception | Should -Not -BeNullOrEmpty
- $exception.stacktrace | Should -Not -BeNullOrEmpty
- }
-
- It "Reports crashedLastRun as Crashed on relaunch" {
- $crashedLastRunLine = $runResult.CrashSendOutput | Where-Object {
- $_ -match "crashedLastRun=Crashed"
- }
- $crashedLastRunLine | Should -Not -BeNullOrEmpty -Because "Native SDK should report crashedLastRun=Crashed after a native crash"
- }
-
- It "Crash-send completes flush successfully" {
- $flushLine = $runResult.CrashSendOutput | Where-Object {
- $_ -match "Flush complete"
- }
- $flushLine | Should -Not -BeNullOrEmpty -Because "crash-send should complete its flush before quitting"
- }
- }
-}
diff --git a/test/IntegrationTest/Integration.Tests.WebGL.ps1 b/test/IntegrationTest/Integration.Tests.WebGL.ps1
deleted file mode 100644
index b1a207586..000000000
--- a/test/IntegrationTest/Integration.Tests.WebGL.ps1
+++ /dev/null
@@ -1,181 +0,0 @@
-#!/usr/bin/env pwsh
-#
-# Integration tests for Sentry Unity SDK (WebGL)
-#
-# Environment variables:
-# SENTRY_WEBGL_BUILD_PATH: path to the WebGL build directory
-# SENTRY_TEST_DSN: test DSN
-# SENTRY_AUTH_TOKEN: authentication token for Sentry API
-
-Set-StrictMode -Version latest
-$ErrorActionPreference = "Stop"
-
-# Import app-runner modules
-. $PSScriptRoot/../../modules/app-runner/import-modules.ps1
-
-# Import shared test cases and utility functions
-. $PSScriptRoot/CommonTestCases.ps1
-
-BeforeAll {
- # Run integration test action via WebGL (HTTP server + headless Chrome)
- function Invoke-TestAction {
- param (
- [Parameter(Mandatory=$true)]
- [string]$Action
- )
-
- Write-Host "Running $Action..."
-
- $serverScript = Join-Path $PSScriptRoot "webgl-server.py"
- $buildPath = $env:SENTRY_WEBGL_BUILD_PATH
- $timeoutSeconds = 120
-
- $process = Start-Process -FilePath "python3" `
- -ArgumentList @($serverScript, $buildPath, $Action, $timeoutSeconds) `
- -NoNewWindow -PassThru -RedirectStandardOutput "$PSScriptRoot/results/${Action}-stdout.txt" `
- -RedirectStandardError "$PSScriptRoot/results/${Action}-stderr.txt"
-
- $process | Wait-Process -Timeout ($timeoutSeconds + 30)
-
- $exitCode = $process.ExitCode
- $stdoutContent = Get-Content "$PSScriptRoot/results/${Action}-stdout.txt" -Raw -ErrorAction SilentlyContinue
- $stderrContent = Get-Content "$PSScriptRoot/results/${Action}-stderr.txt" -Raw -ErrorAction SilentlyContinue
-
- # Parse the JSON array of console lines from stdout
- $output = @()
- if ($stdoutContent) {
- try {
- $output = $stdoutContent | ConvertFrom-Json
- }
- catch {
- Write-Host "Failed to parse webgl-server.py output as JSON: $_"
- Write-Host "Raw stdout: $stdoutContent"
- $output = @($stdoutContent)
- }
- }
-
- if ($stderrContent) {
- Write-Host "::group::Server stderr ($Action)"
- Write-Host $stderrContent
- Write-Host "::endgroup::"
- }
-
- $runResult = [PSCustomObject]@{
- Output = $output
- ExitCode = $exitCode
- }
-
- # Save result to JSON file
- $runResult | ConvertTo-Json -Depth 5 | Out-File -FilePath (Get-OutputFilePath "${Action}-result.json")
-
- # Print app output so it's visible in CI logs
- Write-Host "::group::Browser console output ($Action)"
- $runResult.Output | ForEach-Object { Write-Host $_ }
- Write-Host "::endgroup::"
-
- if ($exitCode -ne 0) {
- Write-Warning "WebGL test action '$Action' did not complete (exit code: $exitCode)"
- }
-
- return $runResult
- }
-
- # Create directory for the test results
- New-Item -ItemType Directory -Path "$PSScriptRoot/results/" -ErrorAction Continue 2>&1 | Out-Null
- Set-OutputDir -Path "$PSScriptRoot/results/"
-
- # Initialize test parameters
- $script:TestSetup = [PSCustomObject]@{
- Platform = "WebGL"
- BuildPath = $env:SENTRY_WEBGL_BUILD_PATH
- Dsn = $env:SENTRY_TEST_DSN
- AuthToken = $env:SENTRY_AUTH_TOKEN
- }
-
- # Validate environment
- if ([string]::IsNullOrEmpty($script:TestSetup.BuildPath)) {
- throw "SENTRY_WEBGL_BUILD_PATH environment variable is not set."
- }
- if (-not (Test-Path $script:TestSetup.BuildPath)) {
- throw "WebGL build not found at: $($script:TestSetup.BuildPath)"
- }
- if ([string]::IsNullOrEmpty($script:TestSetup.Dsn)) {
- throw "SENTRY_TEST_DSN environment variable is not set."
- }
- if ([string]::IsNullOrEmpty($script:TestSetup.AuthToken)) {
- throw "SENTRY_AUTH_TOKEN environment variable is not set."
- }
-
- Connect-SentryApi `
- -ApiToken $script:TestSetup.AuthToken `
- -DSN $script:TestSetup.Dsn
-}
-
-
-AfterAll {
- Disconnect-SentryApi
-}
-
-
-Describe "Unity WebGL Integration Tests" {
-
- Context "Message Capture" {
- BeforeAll {
- $script:runEvent = $null
- $script:runResult = Invoke-TestAction -Action "message-capture"
-
- $eventId = Get-EventIds -AppOutput $script:runResult.Output -ExpectedCount 1
- if ($eventId) {
- Write-Host "::group::Getting event content"
- $script:runEvent = Get-SentryTestEvent -EventId "$eventId"
- Write-Host "::endgroup::"
- }
- }
-
- It "" -ForEach $CommonTestCases {
- & $testBlock -SentryEvent $runEvent -TestType "message-capture" -RunResult $runResult -TestSetup $script:TestSetup
- }
-
- It "Has message level info" {
- ($runEvent.tags | Where-Object { $_.key -eq "level" }).value | Should -Be "info"
- }
-
- It "Has message content" {
- $runEvent.title | Should -Not -BeNullOrEmpty
- }
- }
-
- Context "Exception Capture" {
- BeforeAll {
- $script:runEvent = $null
- $script:runResult = Invoke-TestAction -Action "exception-capture"
-
- $eventId = Get-EventIds -AppOutput $script:runResult.Output -ExpectedCount 1
- if ($eventId) {
- Write-Host "::group::Getting event content"
- $script:runEvent = Get-SentryTestEvent -EventId "$eventId"
- Write-Host "::endgroup::"
- }
- }
-
- It "" -ForEach $CommonTestCases {
- & $testBlock -SentryEvent $runEvent -TestType "exception-capture" -RunResult $runResult -TestSetup $script:TestSetup
- }
-
- It "Has exception information" {
- $runEvent.exception | Should -Not -BeNullOrEmpty
- $runEvent.exception.values | Should -Not -BeNullOrEmpty
- }
-
- It "Has exception with stacktrace" {
- $exception = $runEvent.exception.values[0]
- $exception | Should -Not -BeNullOrEmpty
- $exception.type | Should -Not -BeNullOrEmpty
- $exception.stacktrace | Should -Not -BeNullOrEmpty
- }
-
- It "Has error level" {
- ($runEvent.tags | Where-Object { $_.key -eq "level" }).value | Should -Be "error"
- }
- }
-}
diff --git a/test/IntegrationTest/Integration.Tests.iOS.ps1 b/test/IntegrationTest/Integration.Tests.iOS.ps1
deleted file mode 100644
index b1d52a451..000000000
--- a/test/IntegrationTest/Integration.Tests.iOS.ps1
+++ /dev/null
@@ -1,222 +0,0 @@
-#!/usr/bin/env pwsh
-#
-# Integration tests for Sentry Unity SDK (iOS Simulator)
-#
-# Environment variables:
-# SENTRY_TEST_APP: path to the test .app bundle
-# SENTRY_IOS_VERSION: iOS simulator version (e.g. "17.0" or "latest")
-# SENTRY_TEST_DSN: test DSN
-# SENTRY_AUTH_TOKEN: authentication token for Sentry API
-
-Set-StrictMode -Version latest
-$ErrorActionPreference = "Stop"
-
-# Import app-runner modules
-. $PSScriptRoot/../../modules/app-runner/import-modules.ps1
-
-# Import shared test cases and utility functions
-. $PSScriptRoot/CommonTestCases.ps1
-
-
-BeforeAll {
- $script:BundleId = "com.DefaultCompany.IntegrationTest"
-
- # Run integration test action on device
- function Invoke-TestAction {
- param (
- [Parameter(Mandatory=$true)]
- [string]$Action
- )
-
- Write-Host "Running $Action..."
-
- $appArgs = @("--test", $Action)
-
- $runResult = Invoke-DeviceApp -ExecutablePath $script:BundleId -Arguments $appArgs
-
- # Save result to JSON file
- $runResult | ConvertTo-Json -Depth 5 | Out-File -FilePath (Get-OutputFilePath "${Action}-result.json")
-
- # Launch app again to ensure crash report is sent
- if ($Action -eq "crash-capture") {
- Write-Host "Running crash-send to ensure crash report is sent..."
-
- $sendArgs = @("--test", "crash-send")
- $sendResult = Invoke-DeviceApp -ExecutablePath $script:BundleId -Arguments $sendArgs
-
- # Save crash-send result to JSON for debugging
- $sendResult | ConvertTo-Json -Depth 5 | Out-File -FilePath (Get-OutputFilePath "crash-send-result.json")
-
- # Print crash-send output
- Write-Host "::group::App output (crash-send)"
- $sendResult.Output | ForEach-Object { Write-Host $_ }
- Write-Host "::endgroup::"
-
- # Attach to runResult for test access
- $runResult | Add-Member -NotePropertyName "CrashSendOutput" -NotePropertyValue $sendResult.Output
- }
-
- # Print app output so it's visible in CI logs
- Write-Host "::group::App output ($Action)"
- $runResult.Output | ForEach-Object { Write-Host $_ }
- Write-Host "::endgroup::"
-
- return $runResult
- }
-
- # Create directory for the test results
- New-Item -ItemType Directory -Path "$PSScriptRoot/results/" -ErrorAction Continue 2>&1 | Out-Null
- Set-OutputDir -Path "$PSScriptRoot/results/"
-
- # Initialize test parameters
- $script:TestSetup = [PSCustomObject]@{
- Platform = "iOS"
- AppPath = $env:SENTRY_TEST_APP
- iOSVersion = $env:SENTRY_IOS_VERSION
- Dsn = $env:SENTRY_TEST_DSN
- AuthToken = $env:SENTRY_AUTH_TOKEN
- }
-
- # Validate environment
- if ([string]::IsNullOrEmpty($script:TestSetup.AppPath)) {
- throw "SENTRY_TEST_APP environment variable is not set."
- }
- if (-not (Test-Path $script:TestSetup.AppPath)) {
- throw "App not found at: $($script:TestSetup.AppPath)"
- }
- if ([string]::IsNullOrEmpty($script:TestSetup.iOSVersion)) {
- throw "SENTRY_IOS_VERSION environment variable is not set."
- }
- if ([string]::IsNullOrEmpty($script:TestSetup.Dsn)) {
- throw "SENTRY_TEST_DSN environment variable is not set."
- }
- if ([string]::IsNullOrEmpty($script:TestSetup.AuthToken)) {
- throw "SENTRY_AUTH_TOKEN environment variable is not set."
- }
-
- Connect-SentryApi `
- -ApiToken $script:TestSetup.AuthToken `
- -DSN $script:TestSetup.Dsn
-
- $target = $script:TestSetup.iOSVersion
- # Convert bare version numbers (e.g. "17.0") to "iOS 17.0" format expected by iOSSimulatorProvider
- if ($target -match '^\d+\.\d+$') {
- $target = "iOS $target"
- }
- Connect-Device -Platform "iOSSimulator" -Target $target
- Install-DeviceApp -Path $script:TestSetup.AppPath
-}
-
-
-AfterAll {
- Disconnect-SentryApi
- Disconnect-Device
-}
-
-
-Describe "Unity iOS Integration Tests" {
-
- Context "Message Capture" {
- BeforeAll {
- $script:runEvent = $null
- $script:runResult = Invoke-TestAction -Action "message-capture"
-
- $eventId = Get-EventIds -AppOutput $script:runResult.Output -ExpectedCount 1
- if ($eventId) {
- Write-Host "::group::Getting event content"
- $script:runEvent = Get-SentryTestEvent -EventId "$eventId"
- Write-Host "::endgroup::"
- }
- }
-
- It "" -ForEach $CommonTestCases {
- & $testBlock -SentryEvent $runEvent -TestType "message-capture" -RunResult $runResult -TestSetup $script:TestSetup
- }
-
- It "Has message level info" {
- ($runEvent.tags | Where-Object { $_.key -eq "level" }).value | Should -Be "info"
- }
-
- It "Has message content" {
- $runEvent.title | Should -Not -BeNullOrEmpty
- }
- }
-
- Context "Exception Capture" {
- BeforeAll {
- $script:runEvent = $null
- $script:runResult = Invoke-TestAction -Action "exception-capture"
-
- $eventId = Get-EventIds -AppOutput $script:runResult.Output -ExpectedCount 1
- if ($eventId) {
- Write-Host "::group::Getting event content"
- $script:runEvent = Get-SentryTestEvent -EventId "$eventId"
- Write-Host "::endgroup::"
- }
- }
-
- It "" -ForEach $CommonTestCases {
- & $testBlock -SentryEvent $runEvent -TestType "exception-capture" -RunResult $runResult -TestSetup $script:TestSetup
- }
-
- It "Has exception information" {
- $runEvent.exception | Should -Not -BeNullOrEmpty
- $runEvent.exception.values | Should -Not -BeNullOrEmpty
- }
-
- It "Has exception with stacktrace" {
- $exception = $runEvent.exception.values[0]
- $exception | Should -Not -BeNullOrEmpty
- $exception.type | Should -Not -BeNullOrEmpty
- $exception.stacktrace | Should -Not -BeNullOrEmpty
- }
-
- It "Has error level" {
- ($runEvent.tags | Where-Object { $_.key -eq "level" }).value | Should -Be "error"
- }
- }
-
- Context "Crash Capture" {
- BeforeAll {
- $script:runEvent = $null
- $script:runResult = Invoke-TestAction -Action "crash-capture"
-
- $eventId = Get-EventIds -AppOutput $script:runResult.Output -ExpectedCount 1
- if ($eventId) {
- Write-Host "::group::Getting event content"
- $script:runEvent = Get-SentryTestEvent -TagName "test.crash_id" -TagValue "$eventId" -TimeoutSeconds 120
- Write-Host "::endgroup::"
- }
- }
-
- It "" -ForEach $CommonTestCases {
- & $testBlock -SentryEvent $runEvent -TestType "crash-capture" -RunResult $runResult -TestSetup $script:TestSetup
- }
-
- It "Has fatal level" {
- ($runEvent.tags | Where-Object { $_.key -eq "level" }).value | Should -Be "fatal"
- }
-
- It "Has exception with stacktrace" {
- $runEvent.exception | Should -Not -BeNullOrEmpty
- $runEvent.exception.values | Should -Not -BeNullOrEmpty
- $exception = $runEvent.exception.values[0]
- $exception | Should -Not -BeNullOrEmpty
- $exception.stacktrace | Should -Not -BeNullOrEmpty
- }
-
- It "Reports crashedLastRun as Crashed on relaunch" {
- $crashedLastRunLine = $runResult.CrashSendOutput | Where-Object {
- $_ -match "crashedLastRun=Crashed"
- }
- $crashedLastRunLine | Should -Not -BeNullOrEmpty -Because "Native SDK should report crashedLastRun=Crashed after a native crash"
- }
-
- It "Crash-send completes flush successfully" {
- $flushLine = $runResult.CrashSendOutput | Where-Object {
- $_ -match "Flush complete"
- }
- $flushLine | Should -Not -BeNullOrEmpty -Because "crash-send should complete its flush before quitting"
- }
- }
-}
diff --git a/test/IntegrationTest/Integration.Tests.ps1 b/test/IntegrationTest/Integration.Tests.ps1
index 3b4d32be4..e547dc59a 100644
--- a/test/IntegrationTest/Integration.Tests.ps1
+++ b/test/IntegrationTest/Integration.Tests.ps1
@@ -1,11 +1,16 @@
#!/usr/bin/env pwsh
#
-# Integration tests for Sentry Unity SDK (Android)
+# Integration tests for Sentry Unity SDK
#
# Environment variables:
-# SENTRY_TEST_APK: path to the test APK file
+# SENTRY_TEST_PLATFORM: target platform (Android, Desktop, iOS, WebGL)
# SENTRY_TEST_DSN: test DSN
# SENTRY_AUTH_TOKEN: authentication token for Sentry API
+#
+# SENTRY_TEST_APP: path to the test app (APK, executable, .app bundle, or WebGL build directory)
+#
+# Platform-specific environment variables:
+# iOS: SENTRY_IOS_VERSION - iOS simulator version (e.g. "17.0" or "latest")
Set-StrictMode -Version latest
$ErrorActionPreference = "Stop"
@@ -16,11 +21,80 @@ $ErrorActionPreference = "Stop"
# Import shared test cases and utility functions
. $PSScriptRoot/CommonTestCases.ps1
-
BeforeAll {
- $script:PackageName = "io.sentry.unity.integrationtest"
+ # Build app arguments for a given test action
+ function Get-AppArguments {
+ param([string]$Action)
+
+ switch ($script:Platform) {
+ "Android" { return @("-e", "test", $Action) }
+ "Desktop" { return @("--test", $Action, "-logFile", "-") }
+ "iOS" { return @("--test", $Action) }
+ }
+ }
+
+ # Run a WebGL test action via headless Chrome
+ function Invoke-WebGLTestAction {
+ param (
+ [Parameter(Mandatory=$true)]
+ [string]$Action
+ )
+
+ $serverScript = Join-Path $PSScriptRoot "webgl-server.py"
+ $buildPath = $env:SENTRY_TEST_APP
+ $timeoutSeconds = 120
+
+ $process = Start-Process -FilePath "python3" `
+ -ArgumentList @($serverScript, $buildPath, $Action, $timeoutSeconds) `
+ -NoNewWindow -PassThru -RedirectStandardOutput "$PSScriptRoot/results/${Action}-stdout.txt" `
+ -RedirectStandardError "$PSScriptRoot/results/${Action}-stderr.txt"
- # Run integration test action on device
+ $process | Wait-Process -Timeout ($timeoutSeconds + 30) -ErrorAction SilentlyContinue
+
+ $exitCode = $process.ExitCode
+ $stdoutContent = Get-Content "$PSScriptRoot/results/${Action}-stdout.txt" -Raw -ErrorAction SilentlyContinue
+ $stderrContent = Get-Content "$PSScriptRoot/results/${Action}-stderr.txt" -Raw -ErrorAction SilentlyContinue
+
+ # Parse the JSON array of console lines from stdout
+ $output = @()
+ if ($stdoutContent) {
+ try {
+ $output = $stdoutContent | ConvertFrom-Json
+ }
+ catch {
+ Write-Host "Failed to parse webgl-server.py output as JSON: $_"
+ Write-Host "Raw stdout: $stdoutContent"
+ $output = @($stdoutContent)
+ }
+ }
+
+ if ($stderrContent) {
+ Write-Host "::group::Server stderr ($Action)"
+ Write-Host $stderrContent
+ Write-Host "::endgroup::"
+ }
+
+ $runResult = [PSCustomObject]@{
+ Output = $output
+ ExitCode = $exitCode
+ }
+
+ # Save result to JSON file
+ $runResult | ConvertTo-Json -Depth 5 | Out-File -FilePath (Get-OutputFilePath "${Action}-result.json")
+
+ # Print app output so it's visible in CI logs
+ Write-Host "::group::Browser console output ($Action)"
+ $runResult.Output | ForEach-Object { Write-Host $_ }
+ Write-Host "::endgroup::"
+
+ if ($exitCode -ne 0) {
+ Write-Warning "WebGL test action '$Action' did not complete (exit code: $exitCode)"
+ }
+
+ return $runResult
+ }
+
+ # Run integration test action
function Invoke-TestAction {
param (
[Parameter(Mandatory=$true)]
@@ -29,9 +103,12 @@ BeforeAll {
Write-Host "Running $Action..."
- $extras = @("-e", "test", $Action)
+ if ($script:Platform -eq "WebGL") {
+ return Invoke-WebGLTestAction -Action $Action
+ }
- $runResult = Invoke-DeviceApp -ExecutablePath $script:AndroidComponent -Arguments $extras
+ $appArgs = Get-AppArguments -Action $Action
+ $runResult = Invoke-DeviceApp -ExecutablePath $script:ExecutablePath -Arguments $appArgs
# Save result to JSON file
$runResult | ConvertTo-Json -Depth 5 | Out-File -FilePath (Get-OutputFilePath "${Action}-result.json")
@@ -40,8 +117,8 @@ BeforeAll {
if ($Action -eq "crash-capture") {
Write-Host "Running crash-send to ensure crash report is sent..."
- $sendExtras = @("-e", "test", "crash-send")
- $sendResult = Invoke-DeviceApp -ExecutablePath $script:AndroidComponent -Arguments $sendExtras
+ $sendArgs = Get-AppArguments -Action "crash-send"
+ $sendResult = Invoke-DeviceApp -ExecutablePath $script:ExecutablePath -Arguments $sendArgs
# Save crash-send result to JSON for debugging
$sendResult | ConvertTo-Json -Depth 5 | Out-File -FilePath (Get-OutputFilePath "crash-send-result.json")
@@ -63,57 +140,94 @@ BeforeAll {
return $runResult
}
+ $script:Platform = $env:SENTRY_TEST_PLATFORM
+ if ([string]::IsNullOrEmpty($script:Platform)) {
+ throw "SENTRY_TEST_PLATFORM environment variable is not set. Expected: Android, Desktop, iOS, or WebGL"
+ }
+
+ # Validate common environment
+ if ([string]::IsNullOrEmpty($env:SENTRY_TEST_DSN)) {
+ throw "SENTRY_TEST_DSN environment variable is not set."
+ }
+ if ([string]::IsNullOrEmpty($env:SENTRY_AUTH_TOKEN)) {
+ throw "SENTRY_AUTH_TOKEN environment variable is not set."
+ }
+ if ([string]::IsNullOrEmpty($env:SENTRY_TEST_APP)) {
+ throw "SENTRY_TEST_APP environment variable is not set."
+ }
+ if (-not (Test-Path $env:SENTRY_TEST_APP)) {
+ throw "App not found at: $env:SENTRY_TEST_APP"
+ }
+
+ # Platform-specific device setup
+ switch ($script:Platform) {
+ "Android" {
+ $script:PackageName = "io.sentry.unity.integrationtest"
+
+ Connect-Device -Platform "Adb"
+ Install-DeviceApp -Path $env:SENTRY_TEST_APP
+
+ # Detect the launcher activity from the installed package
+ $dumpOutput = & adb shell dumpsys package $script:PackageName 2>&1 | Out-String
+ if ($dumpOutput -match "com.unity3d.player.UnityPlayerGameActivity") {
+ $script:ExecutablePath = "$($script:PackageName)/com.unity3d.player.UnityPlayerGameActivity"
+ } else {
+ $script:ExecutablePath = "$($script:PackageName)/com.unity3d.player.UnityPlayerActivity"
+ }
+ Write-Host "Detected activity: $($script:ExecutablePath)"
+ }
+ "Desktop" {
+ $script:ExecutablePath = $env:SENTRY_TEST_APP
+ Connect-Device -Platform "Local"
+ }
+ "iOS" {
+ if ([string]::IsNullOrEmpty($env:SENTRY_IOS_VERSION)) {
+ throw "SENTRY_IOS_VERSION environment variable is not set."
+ }
+
+ $script:ExecutablePath = "com.DefaultCompany.IntegrationTest"
+
+ $target = $env:SENTRY_IOS_VERSION
+ # Convert bare version numbers (e.g. "17.0") to "iOS 17.0" format expected by iOSSimulatorProvider
+ if ($target -match '^\d+\.\d+$') {
+ $target = "iOS $target"
+ }
+ Connect-Device -Platform "iOSSimulator" -Target $target
+ Install-DeviceApp -Path $env:SENTRY_TEST_APP
+ }
+ "WebGL" {
+ }
+ default {
+ throw "Unknown platform: $($script:Platform). Expected: Android, Desktop, iOS, or WebGL"
+ }
+ }
+
# Create directory for the test results
New-Item -ItemType Directory -Path "$PSScriptRoot/results/" -ErrorAction Continue 2>&1 | Out-Null
Set-OutputDir -Path "$PSScriptRoot/results/"
# Initialize test parameters
$script:TestSetup = [PSCustomObject]@{
- Platform = "Android"
- ApkPath = $env:SENTRY_TEST_APK
+ Platform = $script:Platform
Dsn = $env:SENTRY_TEST_DSN
AuthToken = $env:SENTRY_AUTH_TOKEN
}
- # Validate environment
- if ([string]::IsNullOrEmpty($script:TestSetup.ApkPath)) {
- throw "SENTRY_TEST_APK environment variable is not set."
- }
- if (-not (Test-Path $script:TestSetup.ApkPath)) {
- throw "APK not found at: $($script:TestSetup.ApkPath)"
- }
- if ([string]::IsNullOrEmpty($script:TestSetup.Dsn)) {
- throw "SENTRY_TEST_DSN environment variable is not set."
- }
- if ([string]::IsNullOrEmpty($script:TestSetup.AuthToken)) {
- throw "SENTRY_AUTH_TOKEN environment variable is not set."
- }
-
Connect-SentryApi `
-ApiToken $script:TestSetup.AuthToken `
-DSN $script:TestSetup.Dsn
-
- Connect-Device -Platform "Adb"
- Install-DeviceApp -Path $script:TestSetup.ApkPath
-
- # Detect the launcher activity from the installed package
- $dumpOutput = & adb shell dumpsys package $script:PackageName 2>&1 | Out-String
- if ($dumpOutput -match "com.unity3d.player.UnityPlayerGameActivity") {
- $script:AndroidComponent = "$($script:PackageName)/com.unity3d.player.UnityPlayerGameActivity"
- } else {
- $script:AndroidComponent = "$($script:PackageName)/com.unity3d.player.UnityPlayerActivity"
- }
- Write-Host "Detected activity: $($script:AndroidComponent)"
}
AfterAll {
Disconnect-SentryApi
- Disconnect-Device
+ if ($script:Platform -ne "WebGL") {
+ Disconnect-Device
+ }
}
-Describe "Unity Android Integration Tests" {
+Describe "Unity $($env:SENTRY_TEST_PLATFORM) Integration Tests" {
Context "Message Capture" {
BeforeAll {
@@ -174,48 +288,60 @@ Describe "Unity Android Integration Tests" {
($runEvent.tags | Where-Object { $_.key -eq "level" }).value | Should -Be "error"
}
}
+}
- Context "Crash Capture" {
- BeforeAll {
- $script:runEvent = $null
- $script:runResult = Invoke-TestAction -Action "crash-capture"
-
- $eventId = Get-EventIds -AppOutput $script:runResult.Output -ExpectedCount 1
- if ($eventId) {
- Write-Host "::group::Getting event content"
- $script:runEvent = Get-SentryTestEvent -TagName "test.crash_id" -TagValue "$eventId" -TimeoutSeconds 120
- Write-Host "::endgroup::"
+if ($env:SENTRY_TEST_PLATFORM -ne "WebGL") {
+ Describe "Unity $($env:SENTRY_TEST_PLATFORM) Crash Tests" {
+
+ Context "Crash Capture" {
+ BeforeAll {
+ $script:runEvent = $null
+ $script:runResult = Invoke-TestAction -Action "crash-capture"
+
+ # Validate crash-send completed before polling Sentry (avoids a 300s blind wait)
+ $flushLine = $runResult.CrashSendOutput | Where-Object { $_ -match "Flush complete" }
+ if (-not $flushLine) {
+ $crashSendOutput = ($runResult.CrashSendOutput | Out-String)
+ throw "crash-send did not complete flush. The crash envelope was likely not sent. Output:`n$crashSendOutput"
+ }
+
+ $eventId = Get-EventIds -AppOutput $script:runResult.Output -ExpectedCount 1
+ if ($eventId) {
+ Write-Host "::group::Getting event content"
+ $script:runEvent = Get-SentryTestEvent -TagName "test.crash_id" -TagValue "$eventId" -TimeoutSeconds 300
+ Write-Host "::endgroup::"
+ }
}
- }
- It "" -ForEach $CommonTestCases {
- & $testBlock -SentryEvent $runEvent -TestType "crash-capture" -RunResult $runResult -TestSetup $script:TestSetup
- }
+ It "" -ForEach $CommonTestCases {
+ & $testBlock -SentryEvent $runEvent -TestType "crash-capture" -RunResult $runResult -TestSetup $script:TestSetup
+ }
- It "Has fatal level" {
- ($runEvent.tags | Where-Object { $_.key -eq "level" }).value | Should -Be "fatal"
- }
+ It "Has fatal level" {
+ ($runEvent.tags | Where-Object { $_.key -eq "level" }).value | Should -Be "fatal"
+ }
- It "Has exception with stacktrace" {
- $runEvent.exception | Should -Not -BeNullOrEmpty
- $runEvent.exception.values | Should -Not -BeNullOrEmpty
- $exception = $runEvent.exception.values[0]
- $exception | Should -Not -BeNullOrEmpty
- $exception.stacktrace | Should -Not -BeNullOrEmpty
- }
+ It "Has exception with stacktrace" {
+ $runEvent.exception | Should -Not -BeNullOrEmpty
+ $runEvent.exception.values | Should -Not -BeNullOrEmpty
+ $exception = $runEvent.exception.values[0]
+ $exception | Should -Not -BeNullOrEmpty
+ $exception.stacktrace | Should -Not -BeNullOrEmpty
+ }
- It "Reports crashedLastRun as Crashed on relaunch" {
- $crashedLastRunLine = $runResult.CrashSendOutput | Where-Object {
- $_ -match "crashedLastRun=Crashed"
+ It "Reports crashedLastRun as Crashed on relaunch" {
+ $crashedLastRunLine = $runResult.CrashSendOutput | Where-Object {
+ $_ -match "crashedLastRun=Crashed"
+ }
+ $crashedLastRunLine | Should -Not -BeNullOrEmpty -Because "Native SDK should report crashedLastRun=Crashed after a native crash"
}
- $crashedLastRunLine | Should -Not -BeNullOrEmpty -Because "Native SDK should report crashedLastRun=Crashed after a native crash"
- }
- It "Crash-send completes flush successfully" {
- $flushLine = $runResult.CrashSendOutput | Where-Object {
- $_ -match "Flush complete"
+ It "Crash-send completes flush successfully" {
+ $flushLine = $runResult.CrashSendOutput | Where-Object {
+ $_ -match "Flush complete"
+ }
+ $flushLine | Should -Not -BeNullOrEmpty -Because "crash-send should complete its flush before quitting"
}
- $flushLine | Should -Not -BeNullOrEmpty -Because "crash-send should complete its flush before quitting"
}
}
}
diff --git a/test/Scripts.Integration.Test/integration-test.ps1 b/test/Scripts.Integration.Test/integration-test.ps1
index 37c4a4783..06a0b2716 100644
--- a/test/Scripts.Integration.Test/integration-test.ps1
+++ b/test/Scripts.Integration.Test/integration-test.ps1
@@ -86,20 +86,24 @@ Else {
Switch -Regex ($Platform) {
"^(Windows|MacOS|Linux)$" {
+ $env:SENTRY_TEST_PLATFORM = "Desktop"
$env:SENTRY_TEST_APP = GetNewProjectBuildPath
- Invoke-Pester -Path test/IntegrationTest/Integration.Tests.Desktop.ps1 -CI
+ Invoke-Pester -Path test/IntegrationTest/Integration.Tests.ps1 -CI
}
"^(Android)$" {
- $env:SENTRY_TEST_APK = "$(GetNewProjectBuildPath)/test.apk"
+ $env:SENTRY_TEST_PLATFORM = "Android"
+ $env:SENTRY_TEST_APP = "$(GetNewProjectBuildPath)/test.apk"
Invoke-Pester -Path test/IntegrationTest/Integration.Tests.ps1 -CI
}
"^iOS$" {
+ $env:SENTRY_TEST_PLATFORM = "iOS"
$env:SENTRY_TEST_APP = "$(GetNewProjectBuildPath)/IntegrationTest.app"
- Invoke-Pester -Path test/IntegrationTest/Integration.Tests.iOS.ps1 -CI
+ Invoke-Pester -Path test/IntegrationTest/Integration.Tests.ps1 -CI
}
"^WebGL$" {
- $env:SENTRY_WEBGL_BUILD_PATH = GetNewProjectBuildPath
- Invoke-Pester -Path test/IntegrationTest/Integration.Tests.WebGL.ps1 -CI
+ $env:SENTRY_TEST_PLATFORM = "WebGL"
+ $env:SENTRY_TEST_APP = GetNewProjectBuildPath
+ Invoke-Pester -Path test/IntegrationTest/Integration.Tests.ps1 -CI
}
"^Switch$" {
Write-PhaseSuccess "Switch build completed - no automated test execution available"