chore: enhance tests for TemplateSchedulePage (#9801)

* chore: Add benchmark logs to test

* chore: Remove benchmark logic

* chore: add hard cutoff for waitFor calls

* refactor: clean up waitFor cut-off logic

* chore: add assertion that submit button is not disabled

* chore: Remove disabled check at the start of the test

* fix: extend cutoff for waitFor config
This commit is contained in:
Michael Smith
2023-09-21 14:25:26 -04:00
committed by GitHub
parent 201a6c0c79
commit 91a04c0132
@@ -36,19 +36,22 @@ const renderTemplateSchedulePage = async () => {
await waitForLoaderToBeRemoved();
};
// Extracts all properties from TemplateScheduleFormValues that have a key that
// ends in _ms, and makes those properties optional. Defined as mapped type to
// ensure this stays in sync as TemplateScheduleFormValues changes
type FillAndSubmitConfig = {
[Key in keyof TemplateScheduleFormValues as Key extends `${string}_ms`
? Key
: never]?: TemplateScheduleFormValues[Key] | undefined;
};
const fillAndSubmitForm = async ({
default_ttl_ms,
max_ttl_ms,
failure_ttl_ms,
time_til_dormant_ms,
time_til_dormant_autodelete_ms,
}: {
default_ttl_ms?: number;
max_ttl_ms?: number;
failure_ttl_ms?: number;
time_til_dormant_ms?: number;
time_til_dormant_autodelete_ms?: number;
}) => {
}: FillAndSubmitConfig) => {
const user = userEvent.setup();
if (default_ttl_ms) {
@@ -61,6 +64,7 @@ const fillAndSubmitForm = async ({
if (max_ttl_ms) {
const maxTtlField = await screen.findByLabelText("Max lifetime (hours)");
await user.clear(maxTtlField);
await user.type(maxTtlField, max_ttl_ms.toString());
}
@@ -89,16 +93,31 @@ const fillAndSubmitForm = async ({
);
}
const submitButton = await screen.findByText(
FooterFormLanguage.defaultSubmitLabel,
);
const submitButton = screen.getByRole("button", {
name: FooterFormLanguage.defaultSubmitLabel,
});
expect(submitButton).not.toBeDisabled();
await user.click(submitButton);
// User needs to confirm dormancy and autodeletion fields.
// User needs to confirm dormancy and auto-deletion fields.
const confirmButton = await screen.findByTestId("confirm-button");
await user.click(confirmButton);
};
// One problem with the waitFor function is that if no additional config options
// are passed in, it will hang indefinitely as it keeps retrying an assertion.
// Even if Jest runs out of time and kills the test, you won't get a good error
// message. Adding options to force test to give up before test timeout
function waitForWithCutoff(callback: () => void | Promise<void>) {
return waitFor(callback, {
// Defined to end 500ms before global cut-off time of 20s. Wanted to define
// this in terms of an exported constant from jest.config, but since Jest
// is CJS-based, that would've involved weird CJS-ESM interop issues
timeout: 19_500,
});
}
describe("TemplateSchedulePage", () => {
beforeEach(() => {
jest
@@ -109,14 +128,17 @@ describe("TemplateSchedulePage", () => {
jest.spyOn(API, "getExperiments").mockResolvedValue(["workspace_actions"]);
});
it("succeeds", async () => {
it("Calls the API when user fills in and submits a form", async () => {
await renderTemplateSchedulePage();
jest.spyOn(API, "updateTemplateMeta").mockResolvedValueOnce({
...MockTemplate,
...validFormValues,
});
await fillAndSubmitForm(validFormValues);
await waitFor(() => expect(API.updateTemplateMeta).toBeCalledTimes(1));
await waitForWithCutoff(() =>
expect(API.updateTemplateMeta).toBeCalledTimes(1),
);
});
test("default and max ttl is converted to and from hours", async () => {
@@ -128,16 +150,19 @@ describe("TemplateSchedulePage", () => {
});
await fillAndSubmitForm(validFormValues);
await waitFor(() => expect(API.updateTemplateMeta).toBeCalledTimes(1));
await waitFor(() =>
await waitForWithCutoff(() =>
expect(API.updateTemplateMeta).toBeCalledTimes(1),
);
await waitForWithCutoff(() => {
expect(API.updateTemplateMeta).toBeCalledWith(
"test-template",
expect.objectContaining({
default_ttl_ms: (validFormValues.default_ttl_ms || 0) * 3600000,
max_ttl_ms: (validFormValues.max_ttl_ms || 0) * 3600000,
}),
),
);
);
});
});
test("failure, dormancy, and dormancy auto-deletion converted to and from days", async () => {
@@ -149,8 +174,11 @@ describe("TemplateSchedulePage", () => {
});
await fillAndSubmitForm(validFormValues);
await waitFor(() => expect(API.updateTemplateMeta).toBeCalledTimes(1));
await waitFor(() =>
await waitForWithCutoff(() =>
expect(API.updateTemplateMeta).toBeCalledTimes(1),
);
await waitForWithCutoff(() => {
expect(API.updateTemplateMeta).toBeCalledWith(
"test-template",
expect.objectContaining({
@@ -160,8 +188,8 @@ describe("TemplateSchedulePage", () => {
time_til_dormant_autodelete_ms:
(validFormValues.time_til_dormant_autodelete_ms || 0) * 86400000,
}),
),
);
);
});
});
it("allows a default ttl of 7 days", () => {