Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix integration tests #18

Merged
merged 3 commits into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions desktop/integration-test/launchApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,17 @@ import { appPath } from "./build";

const log = Logger.getLogger(__filename);

export type AppType = {
main: ElectronApplication;
renderer: Page;
} & AsyncDisposable;

/**
* Launch the app and wait for initial render.
*
* @returns An AsyncDisposable which automatically closes the app when it goes out of scope.
*/
export async function launchApp(): Promise<
{
main: ElectronApplication;
renderer: Page;
} & AsyncDisposable
> {
export async function launchApp(): Promise<AppType> {
// Create a new user data directory for each test, which bypasses the `app.requestSingleInstanceLock()`
const userDataDir = await mkdtemp(path.join(os.tmpdir(), "integration-test-"));
const electronApp = await electron.launch({
Expand Down
53 changes: 26 additions & 27 deletions desktop/integration-test/menus.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,43 +4,44 @@

import { signal } from "@foxglove/den/async";

import { launchApp } from "./launchApp";
import { AppType, launchApp } from "./launchApp";

describe("menus", () => {
it("should display the data source dialog when clicking File > Open", async () => {
await using app = await launchApp();
// The Open dialog shows up automatically; close it
const closeDataSourceDialogAfterAppLaunch = async (app: AppType) => {
await expect(app.renderer.getByTestId("DataSourceDialog").isVisible()).resolves.toBe(true);
await app.renderer.getByTestId("DataSourceDialog").getByTestId("CloseIcon").click();
await expect(app.renderer.getByTestId("DataSourceDialog").count()).resolves.toBe(0);
await expect(app.renderer.getByTestId("DataSourceDialog").isVisible()).resolves.toBe(false);
};

// Click "File > Open" and the dialog should appear again
await app.main.evaluate(async ({ Menu }) => {
const menu = Menu.getApplicationMenu();
menu?.getMenuItemById("fileMenu")?.submenu?.getMenuItemById("open")?.click();
});
await app.renderer.waitForSelector('[data-testid="DataSourceDialog"]', { state: "visible" });
it("should display the data source dialog when clicking File > Open", async () => {
await using app = await launchApp();

await closeDataSourceDialogAfterAppLaunch(app);

await app.renderer.getByTestId("AppMenuButton").click();
await app.renderer.getByTestId("app-menu-file").click();
await app.renderer.getByTestId("menu-item-open").click();

await expect(app.renderer.getByTestId("DataSourceDialog").isVisible()).resolves.toBe(true);
}, 15_000);

it("should display the Open Connection screen when clicking File > Open Connection", async () => {
await using app = await launchApp();
// The Open dialog shows up automatically; close it
await expect(app.renderer.getByTestId("DataSourceDialog").isVisible()).resolves.toBe(true);
await expect(app.renderer.getByTestId("OpenConnection").count()).resolves.toBe(0);
await app.renderer.getByTestId("DataSourceDialog").getByTestId("CloseIcon").click();
await expect(app.renderer.getByTestId("DataSourceDialog").count()).resolves.toBe(0);

// Click "File > Open Connection" and the Open Connection screen should appear
await app.main.evaluate(async ({ Menu }) => {
const menu = Menu.getApplicationMenu();
menu?.getMenuItemById("fileMenu")?.submenu?.getMenuItemById("openConnection")?.click();
});
await app.renderer.waitForSelector('[data-testid="OpenConnection"]', { state: "visible" });
await closeDataSourceDialogAfterAppLaunch(app);

await app.renderer.getByTestId("AppMenuButton").click();
await app.renderer.getByTestId("app-menu-file").click();
await app.renderer.getByTestId("menu-item-open-connection").click();

await expect(app.renderer.getByTestId("OpenConnection").count()).resolves.toBe(1);
}, 15_000);

it("should open the file chooser when clicking File > Open Local File", async () => {
await using app = await launchApp();

await closeDataSourceDialogAfterAppLaunch(app);

// The page is loaded as a file:// URL in the test, so showOpenFilePicker is not available and we need to mock it.
// If it were available we could use `app.renderer.waitForEvent("filechooser")` instead.
const openFilePickerCalled = signal<boolean>();
Expand All @@ -49,11 +50,9 @@ describe("menus", () => {
return [];
});

// Click "File > Open Connection" and the Open Connection screen should appear
await app.main.evaluate(async ({ Menu }) => {
const menu = Menu.getApplicationMenu();
menu?.getMenuItemById("fileMenu")?.submenu?.getMenuItemById("openLocalFile")?.click();
});
await app.renderer.getByTestId("AppMenuButton").click();
await app.renderer.getByTestId("app-menu-file").click();
await app.renderer.getByTestId("menu-item-open-local-file").click();

await expect(openFilePickerCalled).resolves.toBe(true);
}, 15_000);
Expand Down
3 changes: 3 additions & 0 deletions packages/studio-base/src/components/AppBar/AppMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export function AppMenu(props: AppMenuProps): JSX.Element {
type: "item",
label: t("open"),
key: "open",
dataTestId: "menu-item-open",
onClick: () => {
dialogActions.dataSource.open("start");
handleNestedMenuClose();
Expand All @@ -79,6 +80,7 @@ export function AppMenu(props: AppMenuProps): JSX.Element {
type: "item",
label: t("openLocalFile"),
key: "open-file",
dataTestId: "menu-item-open-local-file",
onClick: () => {
handleNestedMenuClose();
dialogActions.openFile.open().catch(console.error);
Expand All @@ -88,6 +90,7 @@ export function AppMenu(props: AppMenuProps): JSX.Element {
type: "item",
label: t("openConnection"),
key: "open-connection",
dataTestId: "menu-item-open-connection",
onClick: () => {
dialogActions.dataSource.open("connection");
handleNestedMenuClose();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ export function NestedMenuItem(
className={classes.menuItem}
key={item.key}
onClick={item.onClick}
data-testid={item.dataTestId}
disabled={item.disabled}
>
{item.label}
Expand Down
1 change: 1 addition & 0 deletions packages/studio-base/src/components/AppBar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ export function AppBar(props: AppBarProps): JSX.Element {
className={cx(classes.logo, { "Mui-selected": appMenuOpen })}
color="inherit"
id="app-menu-button"
data-testid="AppMenuButton"
title="Menu"
aria-controls={appMenuOpen ? "app-menu" : undefined}
aria-haspopup="true"
Expand Down
1 change: 1 addition & 0 deletions packages/studio-base/src/components/AppBar/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export type AppBarMenuItem =
onClick?: MouseEventHandler<HTMLElement>;
external?: boolean;
icon?: ReactNode;
dataTestId?: string;
}
| { type: "subheader"; label: ReactNode; key: string }
| { type: "divider" };
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ export function DataSourceDialog(props: DataSourceDialogProps): JSX.Element {
}}
>
<IconButton className={classes.closeButton} onClick={onModalClose} edge="end">
<CloseIcon />
<CloseIcon data-testid="CloseIcon" />
</IconButton>
<Stack
flexGrow={1}
Expand Down
Loading