Skip to content

Commit 4926883

Browse files
committed
test: Add settings sync tests + small improvements
1 parent d5c637d commit 4926883

File tree

6 files changed

+107
-13
lines changed

6 files changed

+107
-13
lines changed

test/e2e/settings.spec.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,18 @@ import { expect, test } from './fixtures';
44
test('settings page', async ({ page, extensionId }) => {
55
await page.goto(`chrome-extension://${extensionId}/settings.html`);
66

7-
// FIXME: Better assertions
7+
// FIXME: Better assertions.
88

99
await expect(page).toHaveTitle('New Tab');
1010
await expect(page).toHaveURL(`chrome-extension://${extensionId}/settings.html`); // didn't redirect
1111

1212
const labels = await page.locator('label').all();
13-
expect(labels).toHaveLength(4);
1413
await expect(labels[0]).toHaveText('Theme');
1514
await expect(labels[1]).toHaveText('Show bookmarks bar');
1615
await expect(labels[2]).toHaveText('Sections');
1716
await expect(labels[3]).toHaveText('Reset');
17+
await expect(labels[4]).toHaveText('Automatically sync settings');
18+
expect(labels).toHaveLength(5);
1819
});
1920

2021
test.skip('matches screenshot', async ({ page, extensionId }) => {
@@ -32,4 +33,4 @@ test('has no console calls or unhandled errors', async ({ page, extensionId }) =
3233
expect(consoleMessages).toHaveLength(0);
3334
});
3435

35-
// TODO: Test it makes no external requests (other than fetch themes)
36+
// TODO: Test it makes no external requests (other than fetch themes).

test/setup.ts

+15-1
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,15 @@ function setupMocks(): void {
2323
history: {
2424
search: noopAsyncArr,
2525
},
26-
// @ts-expect-error - partial mock
2726
runtime: {
27+
// @ts-expect-error - partial mock
28+
onInstalled: {
29+
addListener: noop,
30+
},
31+
// @ts-expect-error - partial mock
32+
onStartup: {
33+
addListener: noop,
34+
},
2835
openOptionsPage: noopAsync,
2936
},
3037
// @ts-expect-error - partial mock
@@ -38,6 +45,13 @@ function setupMocks(): void {
3845
remove: noopAsync,
3946
set: noopAsync,
4047
},
48+
// @ts-expect-error - partial mock
49+
sync: {
50+
clear: noopAsync,
51+
get: noopAsyncObj,
52+
remove: noopAsync,
53+
set: noopAsync,
54+
},
4155
},
4256
tabs: {
4357
// @ts-expect-error - partial mock

test/unit/index.test.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ describe('dist files', () => {
1919
['newtab.js', 'text/javascript;charset=utf-8', 4000, 6000],
2020
['settings.css', 'text/css;charset=utf-8', 1000, 1500],
2121
['settings.html', 'text/html;charset=utf-8', 150, 200],
22-
['settings.js', 'text/javascript;charset=utf-8', 4000, 6000],
23-
['sw.js', 'text/javascript;charset=utf-8', 150, 300],
22+
['settings.js', 'text/javascript;charset=utf-8', 6000, 8000],
23+
['sw.js', 'text/javascript;charset=utf-8', 400, 600],
2424
['themes.json', 'application/json;charset=utf-8'],
2525
];
2626

test/unit/newtab.test.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { reset } from '../setup';
66
// Completely reset DOM and global state between tests
77
afterEach(reset);
88

9-
const MODULE_PATH = import.meta.resolveSync('../../dist/newtab.js');
9+
const MODULE_PATH = Bun.resolveSync('./dist/newtab.js', '.');
1010

1111
async function load() {
1212
// Workaround for hack in src/BookmarkBar.ts that waits for styles to be loaded
@@ -26,8 +26,8 @@ test('renders entire newtab app', async () => {
2626
expect(document.body.querySelector('#m')).toBeTruthy();
2727
expect(document.body.querySelector('#d')).toBeTruthy();
2828

29-
// TODO: More/better assertions
30-
// TODO: Check all section headings exist; a h2 with text 'Open Tabs' x5
29+
// TODO: More and better assertions.
30+
// TODO: Check all section headings exist; a h2 with text 'Open Tabs' x5.
3131
});
3232

3333
test('does not call any console methods', async () => {

test/unit/settings.test.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { reset } from '../setup';
66
// Completely reset DOM and global state between tests
77
afterEach(reset);
88

9-
const MODULE_PATH = import.meta.resolveSync('../../dist/settings.js');
9+
const MODULE_PATH = Bun.resolveSync('./dist/settings.js', '.');
1010
const themes = Bun.file('dist/themes.json');
1111

1212
async function load() {
@@ -32,7 +32,7 @@ test('renders entire settings app', async () => {
3232
await load();
3333
expect(document.body.innerHTML.length).toBeGreaterThan(600);
3434

35-
// TODO: More/better assertions
35+
// TODO: More and better assertions.
3636
});
3737

3838
test('does not call any console methods', async () => {

test/unit/sw.test.ts

+81-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,81 @@
1-
// TODO
2-
$console.warn('Not implemented');
1+
import { afterEach, expect, test } from 'bun:test';
2+
import { spyOn } from 'bun:test';
3+
import { describe } from 'bun:test';
4+
import { performanceSpy } from '@maxmilton/test-utils/spy';
5+
import { reset } from '../setup';
6+
7+
// Completely reset DOM and global state between tests
8+
afterEach(reset);
9+
10+
const MODULE_PATH = Bun.resolveSync('./dist/sw.js', '.');
11+
12+
async function load(noMocks?: boolean) {
13+
if (!noMocks) {
14+
const originalFetch = global.fetch;
15+
16+
// @ts-expect-error - monkey patching fetch for testing
17+
global.fetch = (input, init) => {
18+
if (input === 'themes.json') {
19+
return Promise.resolve({
20+
json: () => Promise.resolve({}),
21+
});
22+
}
23+
return originalFetch(input, init);
24+
};
25+
26+
chrome.runtime.onInstalled.addListener = (callback) => {
27+
callback({ reason: 'install' as chrome.runtime.OnInstalledReason.INSTALL });
28+
};
29+
chrome.runtime.onStartup.addListener = (callback) => {
30+
callback();
31+
};
32+
}
33+
34+
Loader.registry.delete(MODULE_PATH);
35+
await import(MODULE_PATH);
36+
await happyDOM.waitUntilComplete();
37+
}
38+
39+
test('does not call any console methods', async () => {
40+
expect.assertions(1);
41+
await load();
42+
expect(happyDOM.virtualConsolePrinter.read()).toBeArrayOfSize(0);
43+
});
44+
45+
test('does not call any performance methods', async () => {
46+
expect.hasAssertions(); // variable number of assertions
47+
const check = performanceSpy();
48+
await load();
49+
check();
50+
});
51+
52+
test('does not call fetch() except themes.json', async () => {
53+
expect.assertions(1);
54+
const spy = spyOn(global, 'fetch');
55+
await load();
56+
expect(spy).not.toHaveBeenCalled();
57+
});
58+
59+
describe('onInstalled', () => {
60+
test('has listener', async () => {
61+
expect.assertions(1);
62+
const spy = spyOn(chrome.runtime.onInstalled, 'addListener');
63+
await load(true);
64+
expect(spy).toHaveBeenCalledTimes(1);
65+
});
66+
67+
// TODO: Test with various settings.
68+
// TODO: More and better assertions.
69+
});
70+
71+
describe('onStartup', () => {
72+
test('has listener', async () => {
73+
expect.assertions(1);
74+
const spy = spyOn(chrome.runtime.onStartup, 'addListener');
75+
await load(true);
76+
expect(spy).toHaveBeenCalledTimes(1);
77+
});
78+
79+
// TODO: Test with various settings, especially sync enabled/disabled.
80+
// TODO: More and better assertions.
81+
});

0 commit comments

Comments
 (0)