Skip to content

Commit dd82de0

Browse files
authored
test(extension): Add object registry e2e tests (#555)
This PR adds e2e coverage for the object registry, covering the following. - sending a message to an object - revoking an object Bonus: forwards command line arguments from `yarn test:e2e:ci` to the underlying `yarn playwright test` command.
1 parent 4f29d4c commit dd82de0

4 files changed

Lines changed: 120 additions & 41 deletions

File tree

packages/extension/scripts/test-e2e-ci.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,4 @@ function cleanup() {
1919
# Ensure we always close the server
2020
trap cleanup EXIT
2121

22-
yarn test:e2e
22+
yarn test:e2e "$@"

packages/extension/test/e2e/control-panel.test.ts

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -223,46 +223,6 @@ test.describe('Control Panel', () => {
223223
await popupPage.click('button:text("Control Panel")');
224224
});
225225

226-
test('should send a message to a vat', async () => {
227-
const clearLogsButton = popupPage.locator(
228-
'[data-testid="clear-logs-button"]',
229-
);
230-
await clearLogsButton.click();
231-
await popupPage.click('button:text("Object Registry")');
232-
await expect(popupPage.locator('#root')).toContainText(
233-
'Alice (v1) - 3 objects, 3 promises',
234-
);
235-
const targetSelect = popupPage.locator('[data-testid="message-target"]');
236-
await expect(targetSelect).toBeVisible();
237-
const options = targetSelect.locator('option:not([value=""])');
238-
await expect(options).toHaveCount(await options.count());
239-
expect(await options.count()).toBeGreaterThan(0);
240-
await targetSelect.selectOption({ index: 1 });
241-
await expect(targetSelect).not.toHaveValue('');
242-
const methodInput = popupPage.locator('[data-testid="message-method"]');
243-
await expect(methodInput).toHaveValue('__getMethodNames__');
244-
const paramsInput = popupPage.locator('[data-testid="message-params"]');
245-
await expect(paramsInput).toHaveValue('[]');
246-
await popupPage.click('[data-testid="message-send-button"]');
247-
const messageResponse = popupPage.locator(
248-
'[data-testid="message-response"]',
249-
);
250-
await expect(messageResponse).toBeVisible();
251-
await expect(messageResponse).toContainText(
252-
'"body":"#[\\"__getMethodNames__\\",\\"bootstrap\\",\\"hello\\"]"',
253-
);
254-
await expect(messageResponse).toContainText('"slots":[]');
255-
await clearLogsButton.click();
256-
await methodInput.fill('hello');
257-
await paramsInput.fill('[]');
258-
await popupPage.click('[data-testid="message-send-button"]');
259-
await expect(messageResponse).toContainText('"body":"#\\"vat Alice got');
260-
await expect(messageResponse).toContainText('"slots":[');
261-
await expect(popupPage.locator('#root')).toContainText(
262-
'Alice (v1) - 3 objects, 5 promises',
263-
);
264-
});
265-
266226
test('should reload kernel state and load default vats', async () => {
267227
test.slow();
268228
await expect(
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import { test, expect } from '@playwright/test';
2+
import type { Page, BrowserContext } from '@playwright/test';
3+
4+
import {
5+
revokeObject,
6+
sendMessage,
7+
openObjectRegistryTab,
8+
} from './object-registry.ts';
9+
import { makeLoadExtension } from '../helpers/extension.ts';
10+
11+
test.describe.configure({ mode: 'serial' });
12+
13+
test.describe('Object Registry', () => {
14+
let extensionContext: BrowserContext;
15+
let popupPage: Page;
16+
17+
test.beforeEach(async () => {
18+
const extension = await makeLoadExtension();
19+
extensionContext = extension.browserContext;
20+
popupPage = extension.popupPage;
21+
await openObjectRegistryTab(popupPage, expect);
22+
});
23+
24+
test.afterEach(async () => {
25+
await extensionContext.close();
26+
});
27+
28+
test('should send a message to an object', async () => {
29+
const clearLogsButton = popupPage.locator(
30+
'[data-testid="clear-logs-button"]',
31+
);
32+
await clearLogsButton.click();
33+
await popupPage.click('button:text("Object Registry")');
34+
await expect(popupPage.locator('#root')).toContainText(
35+
'Alice (v1) - 3 objects, 3 promises',
36+
);
37+
const targetSelect = popupPage.locator('[data-testid="message-target"]');
38+
await expect(targetSelect).toBeVisible();
39+
const options = targetSelect.locator('option:not([value=""])');
40+
await expect(options).toHaveCount(await options.count());
41+
expect(await options.count()).toBeGreaterThan(0);
42+
await targetSelect.selectOption({ index: 1 });
43+
await expect(targetSelect).not.toHaveValue('');
44+
const methodInput = popupPage.locator('[data-testid="message-method"]');
45+
await expect(methodInput).toHaveValue('__getMethodNames__');
46+
const paramsInput = popupPage.locator('[data-testid="message-params"]');
47+
await expect(paramsInput).toHaveValue('[]');
48+
await popupPage.click('[data-testid="message-send-button"]');
49+
const messageResponse = popupPage.locator(
50+
'[data-testid="message-response"]',
51+
);
52+
await expect(messageResponse).toBeVisible();
53+
await expect(messageResponse).toContainText(
54+
'"body":"#[\\"__getMethodNames__\\",\\"bootstrap\\",\\"hello\\"]"',
55+
);
56+
await expect(messageResponse).toContainText('"slots":[]');
57+
await clearLogsButton.click();
58+
await methodInput.fill('hello');
59+
await paramsInput.fill('[]');
60+
await popupPage.click('[data-testid="message-send-button"]');
61+
await expect(messageResponse).toContainText('"body":"#\\"vat Alice got');
62+
await expect(messageResponse).toContainText('"slots":[');
63+
await expect(popupPage.locator('#root')).toContainText(
64+
'Alice (v1) - 3 objects, 5 promises',
65+
);
66+
});
67+
68+
test('should revoke an object', async () => {
69+
const owner = 'v1';
70+
const [target, method, params] = ['ko1', 'hello', '["Bob"]'];
71+
72+
// Before revoking, we should be able to send a message to the object
73+
let response = await sendMessage(popupPage, target, method, params);
74+
await expect(response).toContainText(/body(.+):(.+)hello(.+)from(.+)Bob/u);
75+
76+
response = await revokeObject(popupPage, owner, target);
77+
await expect(response).toContainText(`Revoked object ${target}`);
78+
79+
// After revoking, the previously successful message should fail
80+
response = await sendMessage(popupPage, target, method, params);
81+
await expect(response).toContainText(/[Rr]evoked object/u);
82+
});
83+
});
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import type { Page, Expect } from 'playwright/test';
2+
3+
export const openObjectRegistryTab = async (
4+
page: Page,
5+
expect?: Expect,
6+
): Promise<void> => {
7+
await page.click('button:text("Object Registry")');
8+
await expect?.(page.locator('#root')).toContainText('Object Registry');
9+
};
10+
11+
export const sendMessage = async (
12+
page: Page,
13+
target: string,
14+
method: string,
15+
params: string,
16+
) => {
17+
await page
18+
.locator('select[data-testid="message-target"]')
19+
.selectOption(target);
20+
await page.locator('input[data-testid="message-method"]').fill(method);
21+
await page.locator('input[data-testid="message-params"]').fill(params);
22+
await page.locator('button:text("Send")').click();
23+
return page.locator('[data-testid="message-response"]');
24+
};
25+
26+
export const revokeObject = async (
27+
page: Page,
28+
owner: string,
29+
target: string,
30+
) => {
31+
await page
32+
.locator(`.accordion-header:has(.accordion-title:text("${owner}"))`)
33+
.click();
34+
await page.locator(`[data-testid="revoke-button-${target}"]`).click();
35+
return page.locator('[data-testid="message-output"]');
36+
};

0 commit comments

Comments
 (0)