more e2e tuning (#614)

* more e2e tuning

* prettier
This commit is contained in:
ABevier 2023-05-15 19:53:27 -04:00 committed by GitHub
parent 7d4469418b
commit 67edf9971b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 100 additions and 73 deletions

View file

@ -4,6 +4,11 @@ export const setSentryLogging = (sentry: any) => {
const oldError = log.error;
log.error = (...params: any[]) => {
if (process.env.TEST === "true") {
log.info(params);
return;
}
oldError(params);
sentry.captureException(params[0].message);
};

View file

@ -125,6 +125,7 @@
<ToolTip>
<Button
slot="target"
data-testid="uninstall-button"
class="h-10"
type="plain"
color="blue"

View file

@ -249,11 +249,9 @@ const uninstallPkg = async (pkg: GUIPackage) => {
await deletePkg(pkg, v);
}
await withDelay(() => {
updatePackage(pkg.full_name, {
installed_versions: []
});
}, 1000);
updatePackage(pkg.full_name, {
installed_versions: []
});
} catch (error) {
log.error(error);
notificationStore.add({

View file

@ -1,5 +1,5 @@
import { browser } from "wdio-electron-service";
import { setupUtils, sleep } from "./utils.ts";
import { setupUtils } from "./utils.ts";
type utilType = ReturnType<typeof setupUtils>;
@ -30,19 +30,10 @@ describe("basic smoke test", () => {
// Be nice to devs running this over and over
await utils.uninstallPackageIfNeeded();
await utils.installLatestVersion();
await utils.installLatestVersion("tea_xyz_brewkit");
//use findByText to wait for the install to complete
await expect(
await screen.findByText(
/^Package tea.xyz\/brewkit .* has been installed./,
{},
{ timeout: 60000, interval: 1000 }
)
).toExist();
await utils.verifyAndCloseNotification(/^Package tea.xyz\/brewkit .* has been installed./);
await expect(await screen.findByRole("button", { name: "OPEN IN TERMINAL" })).toExist();
await utils.closeNotification();
});
it("search and install create-dmg", async () => {
@ -58,17 +49,11 @@ describe("basic smoke test", () => {
await utils.packageDetailsLoaded();
await utils.uninstallPackageIfNeeded();
await utils.installLatestVersion();
await utils.installLatestVersion("github_com_create_dmg_create_dmg");
await expect(
await screen.findByText(
/^Package github.com\/create-dmg\/create-dmg .* has been installed./,
{},
{ timeout: 60000, interval: 1000 }
)
).toExist();
await utils.closeNotification();
await utils.verifyAndCloseNotification(
/^Package github.com\/create-dmg\/create-dmg .* has been installed./
);
});
it("should be able to install specific version", async () => {
@ -79,42 +64,23 @@ describe("basic smoke test", () => {
pnpmCard.click();
await utils.uninstallPackageIfNeeded();
await utils.installSpecificVersion("pnpm_io", "8.0.0");
await utils.installSpecificVersion("8.0.0");
await utils.verifyAndCloseNotification(/^Package pnpm.io .* has been installed./);
await expect(
await screen.findByText(
/^Package pnpm.io .* has been installed./,
{},
{ timeout: 60000, interval: 1000 }
)
).toExist();
// Now test the update
await utils.goHome();
await utils.closeNotification();
});
it("should be able to update a package", async () => {
// this requires ^ to succeed first
const { screen } = utils!;
const menuBtn = await screen.findByTestId("menu-button-updates-available");
menuBtn.click();
const header = await screen.findByText("available updates");
await expect(header).toExist();
const updateBtn = await screen.findByTestId("install-button-pnpm_io");
const updateBtn = await utils.findByTestId("install-button-pnpm_io");
await expect(updateBtn).toExist();
updateBtn.click();
await expect(
await screen.findByText(
/^Package pnpm.io .* has been installed./,
{},
{ timeout: 60000, interval: 1000 }
)
).toExist();
await utils.closeNotification();
await utils.verifyAndCloseNotification(/^Package pnpm.io .* has been installed./);
});
});

View file

@ -1,4 +1,5 @@
import * as testingLibraryWdio from "@testing-library/webdriverio";
import { waitForNotExist } from "./waitutils.ts";
// work around for importing CommonJS module
const { setupBrowser } = testingLibraryWdio;
@ -11,6 +12,14 @@ export function setupUtils(browser: WebdriverIO.Browser) {
return (await screen.findByRole("button", { name })) as unknown as HTMLElement;
};
const findByTestId = async (testId: string) => {
return (await screen.findByTestId(
testId,
{},
{ interval: 1000, timeout: 10000 }
)) as unknown as HTMLElement;
};
//
// Package List Page
//
@ -40,31 +49,34 @@ export function setupUtils(browser: WebdriverIO.Browser) {
};
const uninstallPackageIfNeeded = async () => {
const uninstallButton = (await screen.queryByRole("button", {
name: "UNINSTALL"
})) as unknown as HTMLElement;
const uninstallButton = (await screen.queryByTestId(
"uninstall-button"
)) as unknown as HTMLElement;
console.log(`will uninstall package = ${!!uninstallButton}`);
if (uninstallButton) {
uninstallButton.click();
// wait for the install button to show back up
await screen.findByRole("button", { name: /^INSTALL / }, { timeout: 60000, interval: 1000 });
// wait for the uninstall button to disappear
await waitForNotExist(() => screen.queryByTestId("uninstall-button"), { timeout: 20000 });
}
};
const installLatestVersion = async () => {
await installSpecificVersion("latest");
const installLatestVersion = async (slug: string) => {
await installSpecificVersion(slug, "latest");
};
const installSpecificVersion = async (version: string) => {
const installButton = await findButton(/^INSTALL |^UPDATE/);
const installSpecificVersion = async (slug: string, version: string) => {
console.log(`Installing package: ${slug}@${version}`);
const installButton = await findByTestId(`install-button-${slug}`);
expect(installButton).toExist();
installButton.click();
const versionButton = await screen.findByTestId(`install-${version}`);
await versionButton.waitForExist();
const versionButton = await findByTestId(`install-${version}`);
expect(versionButton).toExist();
versionButton.click();
};
const goHome = async () => {
// await browser.url("/");
const homeButton = await screen.findByTestId("home-button");
await homeButton.click();
const homeMenu = $("#side-menu");
@ -82,10 +94,17 @@ export function setupUtils(browser: WebdriverIO.Browser) {
};
const closeNotification = async () => {
const closeNotificationBtn = $(".close-notification");
console.log("Closing notification");
const closeNotificationBtn = await findByTestId("close-notification");
await expect(closeNotificationBtn).toExist();
await closeNotificationBtn.click();
await expect(closeNotificationBtn).not.toExist();
closeNotificationBtn.click();
await waitForNotExist(() => screen.queryByTestId("close-notification"));
};
// verify a notification matching the regex is shown and then close it
const verifyAndCloseNotification = async (regex: RegExp) => {
await expect(await screen.findByText(regex, {}, { timeout: 30000, interval: 1000 })).toExist();
await closeNotification();
};
return {
@ -93,14 +112,14 @@ export function setupUtils(browser: WebdriverIO.Browser) {
searchTerm,
goHome,
findButton,
findByTestId,
findPackageCardBySlug,
findSearchPackageCardBySlug,
packageDetailsLoaded,
uninstallPackageIfNeeded,
installLatestVersion,
installSpecificVersion,
closeNotification
closeNotification,
verifyAndCloseNotification
};
}
export const sleep = (delayMs: number) => new Promise((resolve) => setTimeout(resolve, delayMs));

View file

@ -0,0 +1,34 @@
export const sleep = (delayMs: number) => new Promise((resolve) => setTimeout(resolve, delayMs));
export type WaitOpts = { timeout?: number; interval?: number };
// wait for a query to return a non-truthy value
export const waitForNotExist = async (
query: () => Promise<WebdriverIO.Element | null>,
opts: WaitOpts = {}
) => {
return waitFor(async () => await expect(await query()).not.toExist(), opts);
};
export const waitFor = async (
action: () => Promise<void>,
{ interval = 1000, timeout = 5000 }: WaitOpts = {}
) => {
const start = Date.now();
let lastErr;
console.log("Wait For", { interval, timeout });
while (Date.now() - start < timeout) {
try {
await action();
return;
} catch (e) {
// swallow it and keep trying
lastErr = e;
}
await sleep(interval);
}
throw new Error(`waitFor timed out. Last error: ${lastErr}`);
};

View file

@ -27,7 +27,7 @@ export const config: Options.Testrunner = {
browserName: "chrome" // or "firefox", "microsoftedge", "safari"
}
],
logLevel: "debug",
logLevel: "info",
bail: 0,
baseUrl: "http://localhost",
waitforTimeout: 10000,
@ -54,6 +54,6 @@ export const config: Options.Testrunner = {
ui: "bdd",
timeout: 120000
},
specFileRetries: 3,
specFileRetries: 2,
specFileRetriesDelay: 5
};

View file

@ -28,7 +28,11 @@
}}>{notification.callback_label}</button
>
{/if}
<button class="close-notification icon-tea-x-btn mt-1 text-xs" on:click={onClose} />
<button
data-testid="close-notification"
class="close-notification icon-tea-x-btn mt-1 text-xs"
on:click={onClose}
/>
</div>
</div>