Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/astro.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,12 @@ For scanners, use `//*[@id="c-uhff-footer_managecookies"]` after deploying this

Complete the initial banner choice before testing the footer's reopening action, especially on narrow screens where the banner can cover most of the viewport. Use the banner's own management action to inspect preferences before making an initial choice.

Analytics follows WCP's resolved `Analytics` value, including regional defaults. The analytics bootstrap rechecks this value before initializing, since the SDK may finish loading after the settings change.

When `Analytics` is false, the bridge removes only `MicrosoftApplicationsTelemetryDeviceId` at the root path, including host-only and current-domain variants. It disables SDK cookie writes and pauses the collection channel before reloading, rather than unloading and flushing queued events. Keep cleanup scoped to this identifier; preserve `MSCC`, `ai_session`, `MSFPC`, unrelated preferences, and cookies on other domains.

Keep both the deterministic consent UI tests and the real-SDK cookie cases in `tests/e2e/cookie-consent.spec.ts`. The latter route our local build through a synthetic production origin so the production-only guard is exercised, and intercept collection requests rather than sending test telemetry. A CDN failure must fail visibly, not silently skip cookie assertions. Run `pnpm test:unit:contracts` and `pnpm exec playwright test tests/e2e/cookie-consent.spec.ts tests/e2e/analytics-scripts.spec.ts` from `src/frontend`.

## Screenshots and Visual Verification with playwright-cli

When making visual changes or preparing PR screenshots, use the `playwright-cli` skill to automate browser interaction. This site _may_ show a WCP cookie banner on first visit, but it is **geo-gated** and usually absent in local/US runs — when it does appear (a fixed strip at the top of the viewport) **dismiss it before taking screenshots**.
Expand Down
6 changes: 6 additions & 0 deletions src/frontend/public/scripts/analytics/1ds.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@
}

try {
// Consent can change while the asynchronously loaded SDK is in flight.
const siteConsent = window.__aspireWcpSiteConsent;
if (!siteConsent || siteConsent.getConsent().Analytics !== true) {
return;
}

const analytics = new oneDS.ApplicationInsights();
analytics.initialize(
{
Expand Down
33 changes: 29 additions & 4 deletions src/frontend/src/components/starlight/Head.astro
Original file line number Diff line number Diff line change
Expand Up @@ -319,14 +319,36 @@ function computeSourceUrl() {
}
}

function applyConsentToScripts(siteConsent) {
function revokeAnalyticsConsent() {
if (window.analytics && window.analytics.__initialized) {
try {
window.analytics.getCookieMgr().setEnabled(false);
// Pause instead of unloading: unload can flush queued telemetry.
window.analytics.getPostChannel().pause();
} catch (e) {
console.warn('[consent] Failed to stop analytics:', e);
}
}

// Expire only the device identifier. Preserve MSCC, ai_session, MSFPC,
// and unrelated site preferences.
var expired = 'MicrosoftApplicationsTelemetryDeviceId=; Max-Age=0; Path=/; SameSite=Lax';
document.cookie = expired;
document.cookie = expired + '; Domain=' + window.location.hostname;
}

function applyConsentToScripts(siteConsent, allowActivation) {
try {
var consent =
typeof siteConsent.getConsent === 'function' ? siteConsent.getConsent() : null;
if (consent && consent.Analytics) {
activateAnalyticsScripts();
if (consent && consent.Analytics === true) {
if (allowActivation !== false) activateAnalyticsScripts();
} else {
revokeAnalyticsConsent();
}
} catch (e) {}
} catch (e) {
console.warn('[consent] Failed to apply analytics consent:', e);
}
}

function openManageConsent(event) {
Expand All @@ -347,6 +369,9 @@ function computeSourceUrl() {
}

function onConsentChanged() {
withSiteConsent(function (siteConsent) {
applyConsentToScripts(siteConsent, false);
});
// WCP fires this when the visitor changes their choices. Reload so the new
// consent is applied consistently across any consent-gated behavior.
window.setTimeout(function () {
Expand Down
Loading
Loading