Skip to content

Commit

Permalink
fix: async issues with chrome.sidepanel.open + update e2e tests (#122)
Browse files Browse the repository at this point in the history
* fix: context menu

* fix: context menu validation

* fix: shinkai visor connect

* wip: e2e

* - fix: side panel access

* fix: e2e tests

* fix: wording

* fix: wording

---------

Co-authored-by: Alfredo Gallardo <[email protected]>
  • Loading branch information
paulclindo and agallardol authored Jan 24, 2024
1 parent 50451e5 commit 6d19733
Show file tree
Hide file tree
Showing 21 changed files with 180 additions and 177 deletions.
2 changes: 1 addition & 1 deletion apps/shinkai-visor-e2e/src/e2e/action-button.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { expect, test } from '../fixtures/base';

export const actionButtonTests = () => {
test.beforeEach(async ({ page }) => {});
test('action button appear', async ({ actionButton }) => {
test('action button appear for sidepanel test', async ({ actionButton }) => {
await expect(actionButton).toBeVisible();
});
};
2 changes: 0 additions & 2 deletions apps/shinkai-visor-e2e/src/e2e/agents.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
addAgent,
navigateToMenu,
quickConnect,
togglePopup,
} from '../utils/basic-actions';
import { getAgent } from '../utils/dummy-data';
import { hasError } from '../utils/input-errors';
Expand All @@ -21,7 +20,6 @@ export const agentTests = () => {

test.beforeEach(async ({ actionButton, popup }) => {
await nodeManager.startNode(true);
await togglePopup(actionButton, popup);
await acceptTerms(popup);
await quickConnect(popup);
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as path from 'path';

import { expect, test } from '../fixtures/base';
import { acceptTerms, quickConnect, togglePopup } from '../utils/basic-actions';
import { acceptTerms, quickConnect } from '../utils/basic-actions';
import { NodeManager } from '../utils/node-manager';

export const connectMethodQuickStartTests = () => {
Expand All @@ -12,7 +12,6 @@ export const connectMethodQuickStartTests = () => {
test.describe.configure({ mode: 'serial' });

test.beforeEach(async ({ page, actionButton, popup }) => {
await togglePopup(actionButton, popup);
await acceptTerms(popup);
});

Expand Down
10 changes: 1 addition & 9 deletions apps/shinkai-visor-e2e/src/e2e/external-communication.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
import * as path from 'path';

import { expect, test } from '../fixtures/base';
import {
acceptTerms,
addAgent,
quickConnect,
togglePopup,
} from '../utils/basic-actions';
import { acceptTerms, addAgent, quickConnect } from '../utils/basic-actions';
import { getAgent } from '../utils/dummy-data';
import { NodeManager } from '../utils/node-manager';

Expand Down Expand Up @@ -90,7 +85,6 @@ export const extenralCommunicationTests = () => {
extensionId,
}) => {
await nodeManager.startNode(true);
await togglePopup(actionButton, popup);
await acceptTerms(popup);
await quickConnect(popup);
const response = await page.evaluate(
Expand Down Expand Up @@ -142,7 +136,6 @@ export const extenralCommunicationTests = () => {
extensionId,
}) => {
await nodeManager.startNode(true);
await togglePopup(actionButton, popup);
await acceptTerms(popup);
await quickConnect(popup);
await addAgent(popup, getAgent());
Expand All @@ -167,7 +160,6 @@ export const extenralCommunicationTests = () => {
extensionId,
}) => {
await nodeManager.startNode(true);
await togglePopup(actionButton, popup);
await acceptTerms(popup);
await quickConnect(popup);
await addAgent(popup, getAgent());
Expand Down
2 changes: 0 additions & 2 deletions apps/shinkai-visor-e2e/src/e2e/jobs.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
addAgent,
navigateToMenu,
quickConnect,
togglePopup,
} from '../utils/basic-actions';
import { getAgent } from '../utils/dummy-data';
import { hasError } from '../utils/input-errors';
Expand All @@ -21,7 +20,6 @@ export const jobsTests = () => {

test.beforeEach(async ({ actionButton, popup }) => {
await nodeManager.startNode(true);
await togglePopup(actionButton, popup);
await acceptTerms(popup);
await quickConnect(popup);
const agent = getAgent();
Expand Down
10 changes: 1 addition & 9 deletions apps/shinkai-visor-e2e/src/e2e/popup.spec.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
import { expect, test } from '../fixtures/base';
import { togglePopup } from '../utils/basic-actions';
export const popupTests = () => {
test.beforeEach(async ({ page }) => {});
test('popup should be initially hidden', async ({ popup }) => {
const popupContent = popup.getByTestId('popup');
await expect(popupContent).toBeHidden();
});

test('popup appear after press action button', async ({
test('sidepanel appear after press action button', async ({
actionButton,
popup,
}) => {
await togglePopup(actionButton, popup);
const popupContent = popup.getByTestId('popup');
await expect(popupContent).toBeVisible();
});
Expand Down
24 changes: 14 additions & 10 deletions apps/shinkai-visor-e2e/src/e2e/storage.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
addAgent,
navigateToMenu,
quickConnect,
togglePopup,
} from '../utils/basic-actions';
import { getAgent } from '../utils/dummy-data';
import { NodeManager } from '../utils/node-manager';
Expand All @@ -20,7 +19,6 @@ export const storageTests = () => {

test.beforeEach(async ({ actionButton, popup }) => {
await nodeManager.startNode(true);
await togglePopup(actionButton, popup);
await acceptTerms(popup);
await quickConnect(popup);
});
Expand All @@ -29,7 +27,11 @@ export const storageTests = () => {
await nodeManager.stopNode();
});

test('data should persist after refresh browser', async ({ actionButton, popup, page }) => {
test('data should persist after refresh browser', async ({
actionButton,
popup,
page,
}) => {
const agent = getAgent();
await addAgent(popup, agent);

Expand All @@ -39,14 +41,18 @@ export const storageTests = () => {
).toBeVisible();

await page.reload({ waitUntil: 'networkidle' });
await togglePopup(actionButton, popup);
await navigateToMenu(popup, 'nav-menu-agents-button');
await expect(
popup.getByTestId(`${agent.agentName}-agent-button`),
).toBeVisible();
});

test('data should persist after open a new tab', async ({ actionButton, popup, page, context }) => {
test('data should persist after open a new tab', async ({
actionButton,
popup,
page,
context,
}) => {
const agent = getAgent();
await addAgent(popup, agent);

Expand All @@ -60,12 +66,10 @@ export const storageTests = () => {
await newPage.waitForLoadState('networkidle');
const newPageActionButton = newPage.getByTestId('action-button');
await expect(newPageActionButton).toBeDefined();
const newPagePopupIframe = newPage.frameLocator('#popup-iframe');
await expect(newPagePopupIframe).toBeDefined();
await togglePopup(newPageActionButton, newPagePopupIframe);
await navigateToMenu(newPagePopupIframe, 'nav-menu-agents-button');

await navigateToMenu(popup, 'nav-menu-agents-button');
await expect(
newPagePopupIframe.getByTestId(`${agent.agentName}-agent-button`),
popup.getByTestId(`${agent.agentName}-agent-button`),
).toBeVisible();
});
};
6 changes: 1 addition & 5 deletions apps/shinkai-visor-e2e/src/e2e/welcome.spec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import { expect, test } from '../fixtures/base';
import { acceptTerms, togglePopup } from '../utils/basic-actions';
import { acceptTerms } from '../utils/basic-actions';

export const welcomeTests = () => {
test.beforeEach(async ({ page, actionButton, popup }) => {
await togglePopup(actionButton, popup);
});

test('welcome should be the first page', async ({ page, popup }) => {
const tosLink = popup.getByTestId('terms-of-service-link');
const ppLink = popup.getByTestId('privacy-policy-link');
Expand Down
43 changes: 35 additions & 8 deletions apps/shinkai-visor-e2e/src/fixtures/base.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
import { type BrowserContext, chromium, FrameLocator,Locator, test as base } from '@playwright/test';
import {
type BrowserContext,
chromium,
Locator,
Page,
test as base,
} from '@playwright/test';
import * as path from 'path';

import { waitFor } from '../utils/test-utils';

/*
This ENV variable is really important to allow Playwirght to get access to the popup page running in a Chrome side panel
We got this workaround from: https://github.com/microsoft/playwright/issues/26693
*/
process.env.PW_CHROMIUM_ATTACH_TO_OTHER = '1';

export const test = base.extend<{
context: BrowserContext;
extensionId: string;
popup: FrameLocator;
popup: Page;
actionButton: Locator;
}>({
// eslint-disable-next-line no-empty-pattern
Expand Down Expand Up @@ -34,7 +48,9 @@ export const test = base.extend<{
},
page: async ({ page, extensionId }, use) => {
await page.goto('/');
console.log(`page configured and extension is installed extensionId:${extensionId}`);
console.log(
`page configured and extension is installed extensionId:${extensionId}`,
);
// eslint-disable-next-line playwright/no-networkidle
await page.waitForLoadState('networkidle');
await use(page);
Expand All @@ -44,10 +60,21 @@ export const test = base.extend<{
await expect(actionButton).toBeDefined();
await use(actionButton);
},
popup: async ({ page }, use) => {
const popupIframe = page.frameLocator('#popup-iframe');
await expect(popupIframe).toBeDefined();
await use(popupIframe);
}
popup: async ({ page, actionButton, extensionId }, use) => {
await actionButton.click();
let popupPage: Page | undefined = undefined;
await waitFor(
async () => {
popupPage = page
.context()
.pages()
.find((value) => value.url().match(extensionId));
await expect(popupPage).toBeDefined();
},
500,
1000,
);
await use(popupPage);
},
});
export const expect = test.expect;
21 changes: 9 additions & 12 deletions apps/shinkai-visor-e2e/src/utils/basic-actions.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,22 @@
import { FrameLocator, Locator } from "@playwright/test";
import { Page } from '@playwright/test';

import { expect } from '../fixtures/base';

export const togglePopup = async (actionButton: Locator, popupIframe: FrameLocator): Promise<void> => {
await actionButton.click();
const popup = popupIframe.getByTestId('popup');
await expect(popup).toBeVisible();
}

export const acceptTerms = async (popup: FrameLocator): Promise<void> => {
export const acceptTerms = async (popup: Page): Promise<void> => {
const termsInput = popup.getByTestId('terms');
await termsInput.click();
const getStartedButton = popup.getByTestId('get-started-button');
await getStartedButton.click();
};

export const quickConnect = async (popup: FrameLocator): Promise<void> => {
export const quickConnect = async (popup: Page): Promise<void> => {
const quickConnectButton = popup.getByTestId('quick-connect-button');
await quickConnectButton.click();
await expect(popup.getByTestId('nav-menu-button')).toBeVisible();
};

export const addAgent = async (
popup: FrameLocator,
popup: Page,
agent: {
agentName: string;
externalUrl: string;
Expand Down Expand Up @@ -54,7 +48,10 @@ export const addAgent = async (
await expect(popup.getByTestId('create-job-submit-button')).toBeVisible();
};

export const navigateToMenu = async (popup: FrameLocator, menuTestId: string): Promise<void> => {
export const navigateToMenu = async (
popup: Page,
menuTestId: string,
): Promise<void> => {
await popup.getByTestId('nav-menu-button').click();
await popup.getByTestId(menuTestId).click();
}
};
25 changes: 25 additions & 0 deletions apps/shinkai-visor-e2e/src/utils/test-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export const waitMs = (ms: number) =>
new Promise((resolve) => setTimeout(resolve, ms));

export const waitFor = <T extends void>(
fn: () => Promise<T | void>,
retryMs: number,
timeoutMs: number,
): Promise<T | void> => {
const start = Date.now();
// eslint-disable-next-line no-async-promise-executor
return new Promise(async (resolve, reject) => {
let currentValue: T | void;
let lastError: Error | undefined;
while (Date.now() - start < timeoutMs) {
try {
currentValue = await fn();
return resolve(currentValue);
} catch (e) {
lastError = e;
await waitMs(retryMs);
}
}
reject(lastError);
});
};
7 changes: 4 additions & 3 deletions apps/shinkai-visor/public/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"128": "icon128.png"
},
"action": {
"default_title": "Click to open sidepanel",
"default_title": "Click to toggle panel",
"default_icon": {
"16": "icon16.png",
"48": "icon48.png"
Expand All @@ -35,7 +35,7 @@
"chromeos": "Ctrl+Comma",
"linux": "Ctrl+Comma"
},
"description": "Open/Close Shinkai popup"
"description": "Open/Close Shinkai panel"
}
},
"permissions": [
Expand All @@ -56,7 +56,8 @@
{
"matches": ["https://*/*", "http://*/*", "<all_urls>"],
"js": [
"src/components/image-capture/image-capture.tsx"
"src/components/image-capture/image-capture.tsx",
"src/components/action-button/action-button.tsx"
]
}
],
Expand Down
Loading

0 comments on commit 6d19733

Please sign in to comment.