Skip to content

Commit

Permalink
refactor(tests/e2e): add toHaveStorage custom matcher & utils (#812)
Browse files Browse the repository at this point in the history
  • Loading branch information
sidvishnoi authored Jan 8, 2025
1 parent 5599884 commit 8c28d38
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 50 deletions.
4 changes: 4 additions & 0 deletions src/shared/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ export type DeepReadonly<T> = {
readonly [P in keyof T]: DeepReadonly<T[P]>;
};

export type DeepPartial<T> = T extends object
? { [P in keyof T]?: DeepPartial<T[P]> }
: T;

export type RequiredFields<T, K extends keyof T> = T & Required<Pick<T, K>>;

export type Tab = RequiredFields<Tabs.Tab, 'id' | 'url'>;
Expand Down
12 changes: 2 additions & 10 deletions tests/e2e/basic.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,7 @@ test.describe('should fail to connect if:', () => {
i18n.getMessage('connectWallet_error_urlInvalidUrl'),
);

expect(
await background.evaluate(() => {
return chrome.storage.local.get(['connected']);
}),
).toEqual({ connected: false });
await expect(background).toHaveStorage({ connected: false });
});

test('invalid wallet address provided', async ({
Expand All @@ -62,10 +58,6 @@ test.describe('should fail to connect if:', () => {
'not a valid wallet address',
);

expect(
await background.evaluate(() => {
return chrome.storage.local.get(['connected']);
}),
).toEqual({ connected: false });
await expect(background).toHaveStorage({ connected: false });
});
});
21 changes: 3 additions & 18 deletions tests/e2e/connect.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,7 @@ test('connects with correct details provided', async ({
expect(TEST_WALLET_PUBLIC_KEY).toBeDefined();
expect(TEST_WALLET_ADDRESS_URL).toBeDefined();

expect(
await background.evaluate(() => {
return chrome.storage.local.get(['connected']);
}),
).toEqual({ connected: false });
await expect(background).toHaveStorage({ connected: false });

const keyInfo = {
keyId: TEST_WALLET_KEY_ID,
Expand All @@ -45,14 +41,7 @@ test('connects with correct details provided', async ({
const settingsLink = popup.locator(`[href="/settings"]`).first();
await expect(settingsLink).toBeVisible();

const storage = await background.evaluate(() => {
return chrome.storage.local.get([
'connected',
'oneTimeGrant',
'recurringGrant',
]);
});
expect(storage).toMatchObject({
await expect(background).toHaveStorage({
connected: true,
recurringGrant: null,
oneTimeGrant: {
Expand All @@ -69,9 +58,5 @@ test('connects with correct details provided', async ({
);

await disconnectWallet(popup);
expect(
await background.evaluate(() => {
return chrome.storage.local.get(['connected']);
}),
).toEqual({ connected: false });
await expect(background).toHaveStorage({ connected: false });
});
5 changes: 2 additions & 3 deletions tests/e2e/connectAutoKeyChimoney.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
revokeKey,
waitForGrantConsentPage,
} from './helpers/chimoney';
import { getStorage } from './fixtures/helpers';

test('Connect to Chimoney wallet with automatic key addition when not logged-in to wallet', async ({
page,
Expand All @@ -28,9 +29,7 @@ test('Connect to Chimoney wallet with automatic key addition when not logged-in
test.slow(true, 'Some pages load slow');

const walletURL = new URL(walletUrl);
const { keyId } = await background.evaluate(() => {
return chrome.storage.local.get<{ keyId: string }>(['keyId']);
});
const { keyId } = await getStorage(background, ['keyId']);

const connectButton = await test.step('fill popup', async () => {
const connectButton = await fillPopup(popup, i18n, {
Expand Down
9 changes: 3 additions & 6 deletions tests/e2e/connectAutoKeyFynbos.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
revokeKey,
waitForGrantConsentPage,
} from './helpers/fynbos';
import { getStorage } from './fixtures/helpers';

test('Connect to Fynbos with automatic key addition when not logged-in to wallet', async ({
page,
Expand All @@ -23,9 +24,7 @@ test('Connect to Fynbos with automatic key addition when not logged-in to wallet

test.skip(!username || !password || !walletAddressUrl, 'Missing credentials');

const { keyId: kid } = await background.evaluate(() => {
return chrome.storage.local.get<{ keyId: string }>(['keyId']);
});
const { keyId: kid } = await getStorage(background, ['keyId']);

const connectButton = await test.step('fill popup', async () => {
const connectButton = await fillPopup(popup, i18n, {
Expand Down Expand Up @@ -119,9 +118,7 @@ test('Connect to Fynbos with automatic key addition when not logged-in to wallet
await acceptGrant(page, continueWaitMs);
await waitForWelcomePage(page);

expect(
await background.evaluate(() => chrome.storage.local.get(['connected'])),
).toEqual({ connected: true });
expect(background).toHaveStorage({ connected: true });
});

await test.step('cleanup: revoke keys', async () => {
Expand Down
9 changes: 3 additions & 6 deletions tests/e2e/connectAutoKeyTestWallet.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
revokeKey,
waitForGrantConsentPage,
} from './helpers/testWallet';
import { getStorage } from './fixtures/helpers';

test('Connect to test wallet with automatic key addition when not logged-in to wallet', async ({
page,
Expand Down Expand Up @@ -106,9 +107,7 @@ test('Connect to test wallet with automatic key addition when not logged-in to w
}
});

const { keyId } = await background.evaluate(() => {
return chrome.storage.local.get<{ keyId: string }>(['keyId']);
});
const { keyId } = await getStorage(background, ['keyId']);

const jwksBefore = await getJWKS(walletAddressUrl);
expect(jwksBefore.keys.length).toBeGreaterThanOrEqual(0);
Expand Down Expand Up @@ -137,9 +136,7 @@ test('Connect to test wallet with automatic key addition when not logged-in to w
await acceptGrant(page, continueWaitMs);
await waitForWelcomePage(page);

expect(
await background.evaluate(() => chrome.storage.local.get(['connected'])),
).toEqual({ connected: true });
await expect(background).toHaveStorage({ connected: true });
});

await test.step('revoke key', async () => {
Expand Down
51 changes: 50 additions & 1 deletion tests/e2e/fixtures/base.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { test as base, type BrowserContext, type Page } from '@playwright/test';
import {
getBackground,
getStorage,
loadContext,
BrowserIntl,
type Background,
} from './helpers';
import { openPopup, type Popup } from '../pages/popup';
import type { DeepPartial, Storage } from '@/shared/types';

type BaseScopeWorker = {
persistentContext: BrowserContext;
Expand Down Expand Up @@ -66,4 +68,51 @@ export const test = base.extend<{ page: Page }, BaseScopeWorker>({
},
});

export const expect = test.expect;
export const expect = test.expect.extend({
async toHaveStorage(background: Background, expected: DeepPartial<Storage>) {
const assertionName = 'toHaveStorage';

let pass: boolean;
let matcherResult: any;

const storedData = await getStorage(
background,
Object.keys(expected) as Array<keyof typeof expected>,
);
try {
test.expect(storedData).toMatchObject(expected);
pass = true;
} catch {
matcherResult = { actual: storedData };
pass = false;
}

const message = pass
? () =>
this.utils.matcherHint(assertionName, undefined, undefined, {
isNot: this.isNot,
}) +
'\n\n' +
`Expected: not ${this.utils.printExpected(expected)}\n` +
(matcherResult
? `Received: ${this.utils.printReceived(matcherResult.actual)}`
: '')
: () =>
this.utils.matcherHint(assertionName, undefined, undefined, {
isNot: this.isNot,
}) +
'\n\n' +
`Expected: ${this.utils.printExpected(expected)}\n` +
(matcherResult
? `Received: ${this.utils.printReceived(matcherResult.actual)}`
: '');

return {
name: assertionName,
pass,
expected,
actual: matcherResult?.actual,
message,
};
},
});
6 changes: 3 additions & 3 deletions tests/e2e/fixtures/connected.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Page } from '@playwright/test';
import { test as base } from './base';
import { mergeExpects, type Page } from '@playwright/test';
import { test as base, expect as baseExpect } from './base';
import { connectWallet, disconnectWallet, type Popup } from '../pages/popup';

// With extension connected to the wallet.
Expand All @@ -26,4 +26,4 @@ export const test = base.extend<{ page: Page }, { popup: Popup }>({
],
});

export const expect = test.expect;
export const expect = mergeExpects(baseExpect, test.expect);
20 changes: 17 additions & 3 deletions tests/e2e/fixtures/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
import { APP_URL } from '@/background/constants';
import { DIST_DIR, ROOT_DIR } from '../../../esbuild/config';
import type { TranslationKeys } from '../../../src/shared/helpers';
import type { Storage, StorageKey } from '../../../src/shared/types';

export type BrowserInfo = { browserName: string; channel: string | undefined };
export type Background = Worker;
Expand Down Expand Up @@ -281,9 +282,11 @@ export async function loadKeysToExtension(
});
}, keyInfo);

const res = await background.evaluate(() => {
return chrome.storage.local.get(['privateKey', 'publicKey', 'keyId']);
});
const res = await getStorage(background, [
'privateKey',
'publicKey',
'keyId',
]);
if (!res || !res.keyId || !res.privateKey || !res.publicKey) {
throw new Error('Could not load keys to extension');
}
Expand Down Expand Up @@ -345,3 +348,14 @@ export class BrowserIntl {
return result;
}
}

export async function getStorage<TKey extends StorageKey>(
background: Background,
keys?: TKey[],
) {
const data = await background.evaluate(
(keys) => chrome.storage.local.get(keys),
keys,
);
return data as { [Key in TKey[][number]]: Storage[Key] };
}

0 comments on commit 8c28d38

Please sign in to comment.