Stabilize multi-tenant org switch in release E2E

This commit is contained in:
rcourtman 2026-07-09 14:34:46 +01:00
parent 1a05c715ac
commit 584aa10699
3 changed files with 22 additions and 0 deletions

View file

@ -481,6 +481,11 @@ TLS floor in the dynamic config.
connection failure, and release suites that run many scenarios against one
compose backend must prefer worker-scoped authenticated storage state over
repeated per-test password logins.
Multi-tenant release helpers must also treat organization switching as a
visible runtime-state contract: after persisting `pulse_org_id` and reloading,
the helper must wait for the Organization selector to hold the requested org
before a scenario navigates onward, so an interrupted org-list bootstrap
cannot fall back to `default` and mask the scoped UI under test.
6. Add or change governed release-promotion workflow inputs, operator-facing promotion metadata, the canonical version file, prerelease feedback intake prompts, artifact publication lineage enforcement, release note or changelog packet composition, or stable-promotion rehearsal summaries through `.github/workflows/create-release.yml`, `.github/workflows/helm-pages.yml`, `.github/workflows/publish-docker.yml`, `.github/workflows/publish-helm-chart.yml`, `.github/workflows/promote-floating-tags.yml`, `.github/workflows/release-dry-run.yml`, `.github/workflows/update-demo-server.yml`, `.github/ISSUE_TEMPLATE/v6_rc_feedback.yml`, `docs/RELEASE_NOTES.md`, `docs/releases/`, `docs/release-control/v6/internal/RELEASE_PROMOTION_POLICY.md`, `docs/release-control/v6/internal/PRE_RELEASE_CHECKLIST.md`, `docs/release-control/v6/internal/RC_TO_GA_REHEARSAL_TEMPLATE.md`, `scripts/check-workflow-dispatch-inputs.py`, `scripts/release_control/mobile_release_gate.py`, `scripts/release_control/mobile_release_gate_test.py`, `scripts/release_control/render_release_body.py`, `scripts/release_control/validate_artifact_release_line.py`, `scripts/release_control/record_rc_to_ga_rehearsal.py`, `scripts/release_control/internal/record_rc_to_ga_rehearsal.py`, `scripts/release_control/release_promotion_policy_support.py`, `scripts/trigger-release.sh`, and `scripts/trigger-release-dry-run.sh`
That release-promotion boundary also owns prerelease note packet lineage:
shipped RC notes must remain historically accurate, the top-level

View file

@ -167,6 +167,19 @@ test('multi-tenant release auth reuses storage state and classifies login rate l
assert.match(helpers, /\/too many\/i\.test\(lastOutcome\) \? 15_000/);
});
test('multi-tenant release org switching waits for selected org UI state', async () => {
const helpers = await fs.readFile(path.join(integrationRoot, 'tests', 'helpers.ts'), 'utf8');
assert.match(helpers, /export async function switchOrg\(page: Page, orgId: string\)/);
assert.match(helpers, /window\.sessionStorage\.setItem\("pulse_org_id", id\)/);
assert.match(helpers, /window\.localStorage\.setItem\("pulse_org_id", id\)/);
assert.match(helpers, /document\.cookie = `pulse_org_id=\$\{encodeURIComponent\(id\)\}; Path=\/; SameSite=Lax`/);
assert.match(helpers, /await page\.reload\(\{ waitUntil: "domcontentloaded" \}\)/);
assert.match(helpers, /await waitForAppShell\(page\)/);
assert.match(helpers, /getByRole\("combobox", \{ name: "Organization" \}\)/);
assert.match(helpers, /toHaveValue\(\s*orgId,\s*\{\s*timeout: 20_000\s*\},\s*\)/);
});
test('shouldBuildManagedLocalBackendBinary returns true when binary is missing', async () => {
const repoRoot = await fs.mkdtemp(path.join(os.tmpdir(), 'pulse-managed-backend-'));
const state = {

View file

@ -1515,6 +1515,10 @@ export async function switchOrg(page: Page, orgId: string): Promise<void> {
}, orgId);
await page.reload({ waitUntil: "domcontentloaded" });
await waitForAppShell(page);
await expect(page.getByRole("combobox", { name: "Organization" })).toHaveValue(
orgId,
{ timeout: 20_000 },
);
}
/**