# Phase 6 — Embedding & Cross-Browser Smoke Test _Date: 2026-05-24_ ## Iframe test files Created two host pages that load the built artifacts inside a sandboxed iframe: - `/home/user/polisci/results/119/_iframe_test.html` — loads `app.html` - `/home/user/polisci/results/119/_iframe_compare_test.html` — loads `compare.html?ids=M001184,K000389,O000172` Both use: ``` sandbox="allow-scripts allow-same-origin" referrerpolicy="no-referrer" ``` `allow-same-origin` is required because the app uses `fetch()` to load sibling JSON files via relative paths — without same-origin, the iframe would have an opaque origin and same-origin fetches would fail. `allow-scripts` is required to run the dashboard JS. No `allow-forms`, `allow-popups`, `allow-top-navigation`, etc. ## HTTP smoke results Served `results/119/` via `python3 -m http.server 8765`. All endpoints responded as expected: | Endpoint | Result | |---|---| | `app.html` | 200 OK | | `compare.html` | 200 OK | | `app.js` | 200 OK | | `compare.js` | 200 OK | | `app.css` | 200 OK | | `vendor/chart.umd.min.js` | 200 OK | | `vendor/sortable.min.js` | 200 OK | | `data/manifest.json` | parsed: 552 members, version=1.0.0+2026-05-24 | | `data/members/M001184.json` | parsed: Massie total=553 | | `data/members/INVALID.json` | 404 (expected) | Server cleanly shut down after the smoke run; port 8765 no longer listening. ## Headless browser smoke (if any) No headless browser available on this host. `chromium`, `chromium-browser`, `google-chrome`, and `firefox` are all absent from `PATH`. **Manual cross-browser smoke deferred to the user.** Recommended manual checks for the user: 1. Open `results/119/_iframe_test.html` in Chromium/Firefox/Safari from a local web server. Confirm dashboard renders inside the iframe and DevTools Network panel shows zero requests outside the directory. 2. Same for `_iframe_compare_test.html` (three members preloaded). 3. Verify console is clean (no CSP / mixed-content errors). ## External-URL grep audit Audited `template/` and `results/119/` for `https?://` URLs and inspected every runtime-code occurrence. **Runtime network calls in built JS** (`app.js`, `compare.js`): ``` compare.js:46 fetch(state.BASE + 'manifest.json', { credentials: 'omit' }) compare.js:251 fetch(url, { credentials: 'omit' }) compare.js:635 fetch(url, { credentials: 'omit' }) compare.js:671 fetch(url, { credentials: 'omit' }) app.js:56 fetch(url, { credentials: 'omit' }) app.js:243 fetch(url, { credentials: 'omit' }) ``` All `url` values are constructed from `state.BASE + relative_path`, where `BASE` is derived from the document's own location. **Zero absolute external URLs** in `app.js`, `compare.js`, `app.html`, `compare.html`, or `app.css`. The `https://*.senate.gov` / `http://history.house.gov` URLs found in the grep are **member website / photo URLs inside `data/members/*.json`** — these are rendered as `` links for the user to click, never auto-fetched. The `Image.src` / `` audit returned no hits assigning external URLs. The remaining `https://` strings in `vendor/chart.umd.min.js` and `vendor/sortable.min.js` are inside license / banner comments and do not trigger network activity. **Conclusion: no runtime external network calls.** Embedding contract satisfied.