Commit e429373
Fix wasm Playwright TargetClosedException caused by wrong Helix queue (#125548)
## Summary
Fixes #121195
Wasm Playwright browser tests fail intermittently with
`TargetClosedException`. Investigation revealed **two distinct failure
modes**:
### Root Cause 1: Wrong Helix queue for internal builds
In `eng/pipelines/libraries/helix-queues-setup.yml`, the Android queue
selection used an `or` condition:
```yaml
- ${{ if or(eq(variables['System.TeamProject'], 'internal'), in(parameters.platform, 'android_x86', ...)) }}:
- Ubuntu.2204.Amd64.Android.29.Open
```
For internal builds, `System.TeamProject == 'internal'` is always true,
so the Android queue was added for **all platforms** — including
`browser_wasm`. This caused wasm browser tests to run on both:
- ✅ `ubuntu-22.04-helix-webassembly` Docker container (has Chrome shared
lib deps → tests pass)
- ❌ `ubuntu.2204.amd64.android.29` bare metal (missing `libgbm.so.1` →
Chrome can't start → `TargetClosedException`)
**Evidence:** Internal build 2920781 log: `Using Queues:
ubuntu.2204.amd64.android.29+(ubuntu.2204.amd64)ubuntu.2204.amd64@mcr.microsoft.com/...ubuntu-22.04-helix-webassembly`
### Root Cause 2: Intermittent Chrome OOM crash on public builds
Public builds use only the correct Docker queue (with Chrome deps), but
Chrome still crashes intermittently. Investigation of build 1332440
showed:
- Chrome launches successfully, then silently dies during `GotoAsync`
navigation
- No missing library errors, no crash output — Chrome is OOM-killed
- xunit runs test classes **in parallel** (default behavior,
`CollectionPerAssembly` is commented out)
- Concurrent Chrome instances + `wasm-opt` builds exhaust Docker
container memory
- The existing retry in `SpawnBrowserAsync` only covers `LaunchAsync`,
not navigation
**Evidence:** Build 1332440, job ff40a660 — `SatelliteLoadingTests`
Chrome crashes while `AssetCachingTests` runs wasm-opt concurrently
(takes 132s total). 24 of 25 Chrome launches in the work item succeed;
the crash is timing-dependent.
### Changes
1. **`eng/pipelines/libraries/helix-queues-setup.yml`**: Fix the Android
queue condition to only add the queue for Android/bionic platforms (not
all internal builds).
2. **`src/mono/wasm/Wasm.Build.Tests/BrowserRunner.cs`**:
- Add `CheckBrowserDependencies()` — uses `ldd` on Linux to detect
missing Chrome shared libraries before launch, providing a clear error
message instead of cryptic `TargetClosedException`
- Add `PlaywrightException` to `SpawnBrowserAsync` retry (previously
only `TimeoutException`)
- **Add session-level retry in `RunAsync`** — wraps the full browser
session (launch + navigate) with retry logic, so when Chrome crashes
during `GotoAsync`, a fresh browser instance is created and navigation
is retried. This is the fix for the public build failures.
- Preserve `lastException` as `InnerException` when launch retry is
exhausted
### Reproduction
- **Internal build failure**: Reproduced 100% on codespace without
Chrome system deps. After installing deps, tests pass 100%.
- **Public build failure**: Observed in build 1332440 — Chrome crash
during GotoAsync with concurrent wasm-opt, no missing library errors.
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>1 parent 0d6db56 commit e429373
2 files changed
Lines changed: 53 additions & 9 deletions
File tree
- eng/pipelines/libraries
- src/mono/wasm/Wasm.Build.Tests
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
85 | 85 | | |
86 | 86 | | |
87 | 87 | | |
88 | | - | |
89 | | - | |
90 | | - | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
91 | 93 | | |
92 | 94 | | |
93 | 95 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
7 | | - | |
8 | | - | |
9 | 7 | | |
| 8 | + | |
10 | 9 | | |
| 10 | + | |
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
| |||
124 | 124 | | |
125 | 125 | | |
126 | 126 | | |
| 127 | + | |
127 | 128 | | |
128 | 129 | | |
129 | 130 | | |
| |||
143 | 144 | | |
144 | 145 | | |
145 | 146 | | |
| 147 | + | |
146 | 148 | | |
147 | 149 | | |
148 | 150 | | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
149 | 157 | | |
150 | 158 | | |
151 | | - | |
| 159 | + | |
152 | 160 | | |
153 | 161 | | |
154 | 162 | | |
| |||
164 | 172 | | |
165 | 173 | | |
166 | 174 | | |
167 | | - | |
168 | | - | |
169 | | - | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
170 | 212 | | |
171 | 213 | | |
172 | 214 | | |
| |||
0 commit comments