fix: auto-seed preview features in E2E mock bridge

CI was failing 16 smoke tests (workflows.spec, channels.spec, smoke.spec,
file-attachment.spec) because preview-gated UI (workflows, forum, pulse,
projects) didn't render in mock-bridge tests. Tests clicked testIDs that
were behind <FeatureGate>, timing out.

- bridge.ts: seed sprout-feature-overrides-v1 in localStorage with all
  preview feature IDs enabled by default via addInitScript. New
  seedPreviewFeatures option (default true) opts out for specs that
  exercise the toggle UI itself.
- screenshot-feature-flags.ts: pass seedPreviewFeatures: false so the
  Experiments toggle flow still drives each feature on via the UI.

59/59 affected smoke tests passing locally.

Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
This commit is contained in:
npub1223z34hd7vtwc6qj4s7flsxkj644nlre2nthu7lrrmkumhu3xddsrx9r6w
2026-06-08 11:43:44 -07:00
committed by Taylor Ho
parent dcd558910d
commit 0c5c43d591
2 changed files with 40 additions and 3 deletions

View File

@@ -6,7 +6,9 @@ const WATERCOLOR_CHANNEL_ID = "a27e1ee9-76a6-5bdf-a5d5-1d85610dad11";
const FORUM_POST_ID = "mock-forum-release-thread";
test.beforeEach(async ({ page }) => {
await installMockBridge(page);
// This spec exercises the Experiments toggle flow itself (each preview
// feature is enabled via the settings UI), so don't pre-seed overrides.
await installMockBridge(page, undefined, { seedPreviewFeatures: false });
});
// Helper: enable a preview feature via settings, then close settings

View File

@@ -97,11 +97,24 @@ type BridgeOptions = {
relayHttpUrl?: string;
relayWsUrl?: string;
skipOnboardingSeed?: boolean;
/**
* When true (default), seed every preview feature in features.json as
* enabled in localStorage so E2E tests can interact with gated UI without
* clicking through the Experiments settings panel. Set to false in specs
* that test the toggle behavior itself (e.g.
* `screenshot-feature-flags.ts`).
*/
seedPreviewFeatures?: boolean;
user?: keyof typeof TEST_IDENTITIES;
};
const ONBOARDING_COMPLETION_STORAGE_KEY_PREFIX =
"sprout-onboarding-complete.v1:";
const FEATURE_OVERRIDES_STORAGE_KEY = "sprout-feature-overrides-v1";
// Keep in sync with `tier: "preview"` entries in `/features.json`. E2E
// tests opt into all preview features by default so gated UI is reachable
// without clicking through Settings → Experiments on every spec.
const PREVIEW_FEATURE_IDS = ["workflows", "projects", "pulse", "forum"];
const DEFAULT_MOCK_PUBKEY = "deadbeef".repeat(8);
const DEFAULT_RELAY_WS_URL = "ws://localhost:3000";
@@ -140,6 +153,17 @@ async function seedDefaultWorkspace(page: Page, relayWsUrl?: string) {
);
}
async function seedPreviewFeaturesEnabled(page: Page) {
await page.addInitScript(
({ key, ids }) => {
const overrides: Record<string, boolean> = {};
for (const id of ids) overrides[id] = true;
window.localStorage.setItem(key, JSON.stringify(overrides));
},
{ key: FEATURE_OVERRIDES_STORAGE_KEY, ids: PREVIEW_FEATURE_IDS },
);
}
export async function installBridge(page: Page, options: BridgeOptions) {
const identity =
options.mode === "relay"
@@ -152,6 +176,11 @@ export async function installBridge(page: Page, options: BridgeOptions) {
if (!options.skipOnboardingSeed) {
await seedOnboardingCompletionForKnownIdentities(page);
}
// Default to opting every preview feature in. Specs that exercise the
// Experiments toggle UI itself pass `seedPreviewFeatures: false`.
if (options.seedPreviewFeatures !== false) {
await seedPreviewFeaturesEnabled(page);
}
await page.addInitScript(
({ identity: bridgeIdentity, mock, mode, relayHttpUrl, relayWsUrl }) => {
@@ -240,18 +269,24 @@ export async function installBridge(page: Page, options: BridgeOptions) {
export async function installMockBridge(
page: Page,
mock?: MockBridgeOptions,
options?: { skipOnboardingSeed?: boolean },
options?: { skipOnboardingSeed?: boolean; seedPreviewFeatures?: boolean },
) {
await installBridge(page, {
mode: "mock",
mock,
skipOnboardingSeed: options?.skipOnboardingSeed,
seedPreviewFeatures: options?.seedPreviewFeatures,
});
}
export async function installRelayBridge(
page: Page,
user: keyof typeof TEST_IDENTITIES = "tyler",
options?: { seedPreviewFeatures?: boolean },
) {
await installBridge(page, { mode: "relay", user });
await installBridge(page, {
mode: "relay",
user,
seedPreviewFeatures: options?.seedPreviewFeatures,
});
}