Skip to content

Commit

Permalink
[skip ci] testing feature flags
Browse files Browse the repository at this point in the history
  • Loading branch information
tom2drum committed Jan 30, 2024
1 parent 4374a6f commit 037499a
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 21 deletions.
3 changes: 2 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ NEXT_PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID=UA-XXXXXX-X
NEXT_PUBLIC_MIXPANEL_PROJECT_TOKEN=xxx
NEXT_PUBLIC_GROWTH_BOOK_CLIENT_KEY=xxx
NEXT_PUBLIC_AUTH0_CLIENT_ID=xxx
FAVICON_GENERATOR_API_KEY=xxx
FAVICON_GENERATOR_API_KEY=xxx
NEXT_PUBLIC_GROWTH_BOOK_CLIENT_KEY=xxx
3 changes: 3 additions & 0 deletions playwright-ct.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ const config: PlaywrightTestConfig = defineConfig({
// so for now we just mock these modules in tests
'@metamask/post-message-stream': './playwright/mocks/modules/@metamask/post-message-stream.js',
'@metamask/providers': './playwright/mocks/modules/@metamask/providers.js',

// Mock for growthbook to test feature flags
'lib/growthbook/useFeatureValue': './playwright/mocks/lib/growthbook/useFeatureValue.js',
},
},
define: {
Expand Down
16 changes: 2 additions & 14 deletions playwright/fixtures/contextWithEnvs.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { test } from '@playwright/experimental-ct-react';
import type { Browser } from '@playwright/test';

import * as app from 'playwright/utils/app';
import createContextWithStorage from './createContextWithStorage';

interface Env {
name: string;
Expand All @@ -11,20 +10,9 @@ interface Env {
// keep in mind that all passed variables here should be present in env config files (.env.pw or .env.poa)
export default function contextWithEnvsFixture(envs: Array<Env>): Parameters<typeof test.extend>[0]['context'] {
return async({ browser }, use) => {
const context = await createContextWithEnvs(browser, envs);
const context = await createContextWithStorage(browser, envs);

await use(context);
await context.close();
};
}

export async function createContextWithEnvs(browser: Browser, envs: Array<Env>) {
return browser.newContext({
storageState: {
origins: [
{ origin: app.url, localStorage: envs },
],
cookies: [],
},
});
}
18 changes: 18 additions & 0 deletions playwright/fixtures/contextWithFeatures.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { test } from '@playwright/experimental-ct-react';

import createContextWithStorage from './createContextWithStorage';

interface Feature {
id: string;
value: unknown;
}

export default function contextWithFeaturesFixture(envs: Array<Feature>): Parameters<typeof test.extend>[0]['context'] {
return async({ browser }, use) => {
const storageItems = envs.map(({ id, value }) => ({ name: `pw_feature:${ id }`, value: JSON.stringify({ value, type: typeof value }) }));
const context = await createContextWithStorage(browser, storageItems);

await use(context);
await context.close();
};
}
14 changes: 14 additions & 0 deletions playwright/fixtures/createContextWithStorage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type { Browser } from '@playwright/test';

import * as app from 'playwright/utils/app';

export default async function createContextWithEnvs(browser: Browser, localStorage: Array<{ name: string; value: string }>) {
return browser.newContext({
storageState: {
origins: [
{ origin: app.url, localStorage },
],
cookies: [],
},
});
}
25 changes: 25 additions & 0 deletions playwright/mocks/lib/growthbook/useFeatureValue.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const useFeatureValue = (name, fallback) => {
try {
const { value, type } = JSON.parse(localStorage.getItem(`pw_feature:${ name }`));

const formattedValue = (() => {
switch (type) {
case 'boolean': {
return value === 'true';
}
case 'number': {
return Number(value);
}
default:
return value;
}
})();

return { isLoading: false, value: formattedValue };

} catch (error) {
return { isLoading: false, value: fallback };
}
};

export default useFeatureValue;
25 changes: 25 additions & 0 deletions ui/pages/Login.pw.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { test as base, expect } from '@playwright/experimental-ct-react';
import React from 'react';

import contextWithFeatures from 'playwright/fixtures/contextWithFeatures';
import TestApp from 'playwright/TestApp';

import Login from './Login';

const testWithFeature = base.extend({
context: contextWithFeatures([
{ id: 'test_value', value: 'kitty' },
// eslint-disable-next-line @typescript-eslint/no-explicit-any
]) as any,
});

testWithFeature('has feature text', async({ mount }) => {
const component = await mount(
<TestApp>
<Login/>
</TestApp>,
);

const featureText = component.getByText('kitty');
await expect(featureText).toBeVisible();
});
5 changes: 3 additions & 2 deletions ui/snippets/header/Burger.pw.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import React from 'react';
import { buildExternalAssetFilePath } from 'configs/app/utils';
import { FEATURED_NETWORKS_MOCK } from 'mocks/config/network';
import authFixture from 'playwright/fixtures/auth';
import contextWithEnvs, { createContextWithEnvs } from 'playwright/fixtures/contextWithEnvs';
import contextWithEnvs from 'playwright/fixtures/contextWithEnvs';
import createContextWithStorage from 'playwright/fixtures/createContextWithStorage';
import TestApp from 'playwright/TestApp';
import * as app from 'playwright/utils/app';

Expand Down Expand Up @@ -104,7 +105,7 @@ test('submenu', async({ mount, page }) => {
test.describe('auth', () => {
const extendedTest = base.extend({
context: async({ browser }, use) => {
const context = await createContextWithEnvs(browser, [
const context = await createContextWithStorage(browser, [
{ name: 'NEXT_PUBLIC_FEATURED_NETWORKS', value: FEATURED_NETWORKS_URL },
]);
authFixture(context);
Expand Down
9 changes: 5 additions & 4 deletions ui/snippets/navigation/NavigationDesktop.pw.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import React from 'react';
import { buildExternalAssetFilePath } from 'configs/app/utils';
import * as cookies from 'lib/cookies';
import authFixture from 'playwright/fixtures/auth';
import contextWithEnvs, { createContextWithEnvs } from 'playwright/fixtures/contextWithEnvs';
import contextWithEnvs from 'playwright/fixtures/contextWithEnvs';
import createContextWithStorage from 'playwright/fixtures/createContextWithStorage';
import TestApp from 'playwright/TestApp';
import * as app from 'playwright/utils/app';
import * as configs from 'playwright/utils/configs';
Expand Down Expand Up @@ -61,7 +62,7 @@ test.describe('no auth', () => {
base.describe('auth', () => {
const test = base.extend({
context: async({ browser }, use) => {
const context = await createContextWithEnvs(browser, [
const context = await createContextWithStorage(browser, [
{ name: 'NEXT_PUBLIC_FEATURED_NETWORKS', value: FEATURED_NETWORKS_URL },
]);
authFixture(context);
Expand Down Expand Up @@ -150,7 +151,7 @@ test.describe('with submenu', () => {
base.describe('cookie set to false', () => {
const test = base.extend({
context: async({ browser }, use) => {
const context = await createContextWithEnvs(browser, [
const context = await createContextWithStorage(browser, [
{ name: 'NEXT_PUBLIC_FEATURED_NETWORKS', value: FEATURED_NETWORKS_URL },
]);
context.addCookies([ { name: cookies.NAMES.NAV_BAR_COLLAPSED, value: 'false', domain: app.domain, path: '/' } ]);
Expand Down Expand Up @@ -190,7 +191,7 @@ base.describe('cookie set to false', () => {
base.describe('cookie set to true', () => {
const test = base.extend({
context: async({ browser }, use) => {
const context = await createContextWithEnvs(browser, [
const context = await createContextWithStorage(browser, [
{ name: 'NEXT_PUBLIC_FEATURED_NETWORKS', value: FEATURED_NETWORKS_URL },
]);
context.addCookies([ { name: cookies.NAMES.NAV_BAR_COLLAPSED, value: 'true', domain: 'localhost', path: '/' } ]);
Expand Down

0 comments on commit 037499a

Please sign in to comment.