diff --git a/cypress/README.md b/cypress/README.md index 0930a0ad7bcbf..f043f6f0546b4 100644 --- a/cypress/README.md +++ b/cypress/README.md @@ -2,17 +2,13 @@ The Cypress tests run with a PostHog instance that has no feature flags set up. -To test feature flags you can intercept the call to the `decide` endpoint +To test feature flags you can intercept the call to the `decide` endpoint using this helper ```javascript // sometimes the system under test calls `/decide` // and sometimes it calls https://app.posthog.com/decide -cy.intercept('**/decide/*', (req) => - req.reply( - decideResponse({ - // add feature flags here, for e.g. - // 'feature-flag-key': true, - }) - ) -) +setupFeatureFlags({ + // add feature flags here, for e.g. + 'feature-flag-key': true, +}) ``` diff --git a/cypress/e2e/alerts.cy.ts b/cypress/e2e/alerts.cy.ts index 82bd6bc10f4fb..91ecad1d24489 100644 --- a/cypress/e2e/alerts.cy.ts +++ b/cypress/e2e/alerts.cy.ts @@ -1,15 +1,11 @@ -import { decideResponse } from '../fixtures/api/decide' import { createInsight, createInsightWithBreakdown } from '../productAnalytics' +import { setupFeatureFlags } from '../support/decide' describe('Alerts', () => { beforeEach(() => { - cy.intercept('**/decide/*', (req) => - req.reply( - decideResponse({ - alerts: true, - }) - ) - ) + setupFeatureFlags({ + alerts: true, + }) createInsight('insight') }) diff --git a/cypress/e2e/experiments.cy.ts b/cypress/e2e/experiments.cy.ts index 5a7d92c3f49c1..a635cf7841cad 100644 --- a/cypress/e2e/experiments.cy.ts +++ b/cypress/e2e/experiments.cy.ts @@ -1,4 +1,4 @@ -import { decideResponse } from '../fixtures/api/decide' +import { setupFeatureFlags } from '../support/decide' describe('Experiments', () => { let randomNum @@ -47,13 +47,10 @@ describe('Experiments', () => { }) const createExperimentInNewUi = (): void => { - cy.intercept('**/decide/*', (req) => - req.reply( - decideResponse({ - 'new-experiments-ui': true, - }) - ) - ) + setupFeatureFlags({ + 'new-experiments-ui': true, + }) + cy.visit('/experiments') // Name, flag key, description diff --git a/cypress/e2e/exports.cy.ts b/cypress/e2e/exports.cy.ts index 7e96b0c56d454..8131a98425602 100644 --- a/cypress/e2e/exports.cy.ts +++ b/cypress/e2e/exports.cy.ts @@ -1,18 +1,14 @@ import { urls } from 'scenes/urls' -import { decideResponse } from '../fixtures/api/decide' +import { setupFeatureFlags } from '../support/decide' // NOTE: As the API data is randomly generated, we are only really testing here that the overall output is correct // The actual graph is not under test describe('Exporting Insights', () => { beforeEach(() => { - cy.intercept('https://us.i.posthog.com/decide/*', (req) => - req.reply( - decideResponse({ - 'export-dashboard-insights': true, - }) - ) - ) + setupFeatureFlags({ + 'export-dashboard-insights': true, + }) cy.visit(urls.insightNew()) // apply filter cy.get('[data-attr$=add-filter-group]').click() diff --git a/cypress/e2e/featureFlags.cy.ts b/cypress/e2e/featureFlags.cy.ts index 2dceb97af6b21..df4d740b8ec4b 100644 --- a/cypress/e2e/featureFlags.cy.ts +++ b/cypress/e2e/featureFlags.cy.ts @@ -1,10 +1,10 @@ -import { decideResponse } from '../fixtures/api/decide' +import { setupFeatureFlags } from '../support/decide' describe('Feature Flags', () => { let name beforeEach(() => { - cy.intercept('**/decide/*', (req) => req.reply(decideResponse({}))) + setupFeatureFlags({}) cy.intercept('/api/projects/*/property_definitions?type=person*', { fixture: 'api/feature-flags/property_definition', diff --git a/cypress/e2e/onboarding.cy.ts b/cypress/e2e/onboarding.cy.ts index b9453689a12aa..3ffd5ccc4bc27 100644 --- a/cypress/e2e/onboarding.cy.ts +++ b/cypress/e2e/onboarding.cy.ts @@ -1,16 +1,11 @@ -import { decideResponse } from '../fixtures/api/decide' +import { setupFeatureFlags } from '../support/decide' describe('Onboarding', () => { beforeEach(() => { cy.intercept('/api/billing/', { fixture: 'api/billing/billing-unsubscribed.json' }) - - cy.intercept('**/decide/*', (req) => - req.reply( - decideResponse({ - 'product-intro-pages': 'test', - }) - ) - ) + setupFeatureFlags({ + 'product-intro-pages': 'test', + }) }) it('Navigate between /products to /onboarding to a product intro page', () => { diff --git a/cypress/e2e/signup.cy.ts b/cypress/e2e/signup.cy.ts index 9774236ef81c4..76d7a694d8c50 100644 --- a/cypress/e2e/signup.cy.ts +++ b/cypress/e2e/signup.cy.ts @@ -1,4 +1,4 @@ -import { decideResponse } from '../fixtures/api/decide' +import { setupFeatureFlags } from '../support/decide' const VALID_PASSWORD = 'hedgE-hog-123%' @@ -171,13 +171,9 @@ describe('Signup', () => { }) it('Shows redirect notice if redirecting for maintenance', () => { - cy.intercept('**/decide/*', (req) => - req.reply( - decideResponse({ - 'redirect-signups-to-instance': 'us', - }) - ) - ) + setupFeatureFlags({ + 'redirect-signups-to-instance': 'us', + }) cy.visit('/logout') cy.location('pathname').should('include', '/login') diff --git a/cypress/fixtures/api/decide.js b/cypress/fixtures/api/decide.js index 102f1211152c1..7c03b11c6dc48 100644 --- a/cypress/fixtures/api/decide.js +++ b/cypress/fixtures/api/decide.js @@ -8,6 +8,7 @@ export function decideResponse(featureFlags) { }, isAuthenticated: true, supportedCompression: ['gzip', 'gzip-js', 'lz64'], + hasFeatureFlags: Object.keys(featureFlags).length > 0, featureFlags, sessionRecording: { endpoint: '/s/', diff --git a/cypress/support/decide.ts b/cypress/support/decide.ts new file mode 100644 index 0000000000000..a32e192f74d25 --- /dev/null +++ b/cypress/support/decide.ts @@ -0,0 +1,28 @@ +import { decideResponse } from '../fixtures/api/decide' + +export const setupFeatureFlags = (overrides: Record = {}): void => { + // Tricky - the new RemoteConfig endpoint is optimised to not load decide if there are no feature flags in the DB. + // We need to intercept both the RemoteConfig and the decide endpoint to ensure that the feature flags are always loaded. + + cy.intercept('**/array/*/config', (req) => + req.reply( + decideResponse({ + ...overrides, + }) + ) + ) + + cy.intercept('**/array/*/config.js', (req) => + req.continue((res) => { + res.send(res.body) + }) + ) + + cy.intercept('**/decide/*', (req) => + req.reply( + decideResponse({ + ...overrides, + }) + ) + ) +} diff --git a/cypress/support/e2e.ts b/cypress/support/e2e.ts index fe164bf074b3a..f05a549c9bf30 100644 --- a/cypress/support/e2e.ts +++ b/cypress/support/e2e.ts @@ -4,7 +4,7 @@ import 'cypress-axe' import { urls } from 'scenes/urls' -import { decideResponse } from '../fixtures/api/decide' +import { setupFeatureFlags } from './decide' try { // eslint-disable-next-line @typescript-eslint/no-var-requires @@ -86,14 +86,7 @@ beforeEach(() => { Cypress.env('POSTHOG_PROPERTY_GITHUB_ACTION_RUN_URL', process.env.GITHUB_ACTION_RUN_URL) cy.useSubscriptionStatus('subscribed') - cy.intercept('**/decide/*', (req) => - req.reply( - decideResponse({ - // Feature flag to be treated as rolled out in E2E tests, e.g.: - // 'toolbar-launch-side-action': true, - }) - ) - ) + setupFeatureFlags({}) // un-intercepted sometimes this doesn't work and the page gets stuck on the SpinnerOverlay cy.intercept(/app.posthog.com\/api\/projects\/@current\/feature_flags\/my_flags.*/, (req) => req.reply([])) diff --git a/frontend/src/loadPostHogJS.tsx b/frontend/src/loadPostHogJS.tsx index badabf1105246..4dfc4e30ee47f 100644 --- a/frontend/src/loadPostHogJS.tsx +++ b/frontend/src/loadPostHogJS.tsx @@ -67,6 +67,7 @@ export function loadPostHogJS(): void { capture_copied_text: true, }, person_profiles: 'always', + __preview_remote_config: true, // Helper to capture events for assertions in Cypress _onCapture: (window as any)._cypress_posthog_captures