Skip to content

Commit

Permalink
fix(modal): catch error when beforeClose promise is rejected (#7600)
Browse files Browse the repository at this point in the history
**Related Issue:** #6381

## Summary

- catch error when beforeClose promise is rejected
  • Loading branch information
driskull authored Aug 25, 2023
1 parent cb70671 commit 70405d0
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 1 deletion.
42 changes: 42 additions & 0 deletions packages/calcite-components/src/components/modal/modal.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,48 @@ it("calls the beforeClose method prior to closing via attribute", async () => {
expect(await modal.getProperty("opened")).toBe(false);
});

it("should handle rejected 'beforeClose' promise'", async () => {
const page = await newE2EPage();

const mockCallBack = jest.fn().mockReturnValue(() => Promise.reject());
await page.exposeFunction("beforeClose", mockCallBack);

await page.setContent(`<calcite-modal open></calcite-modal>`);

await page.$eval(
"calcite-modal",
(elm: HTMLCalciteModalElement) =>
(elm.beforeClose = (window as typeof window & Pick<typeof elm, "beforeClose">).beforeClose)
);

const modal = await page.find("calcite-modal");
modal.setProperty("open", false);
await page.waitForChanges();

expect(mockCallBack).toHaveBeenCalledTimes(1);
});

it("should remain open with rejected 'beforeClose' promise'", async () => {
const page = await newE2EPage();

await page.exposeFunction("beforeClose", () => Promise.reject());
await page.setContent(`<calcite-modal open></calcite-modal>`);

await page.$eval(
"calcite-modal",
(elm: HTMLCalciteModalElement) =>
(elm.beforeClose = (window as typeof window & Pick<typeof elm, "beforeClose">).beforeClose)
);

const modal = await page.find("calcite-modal");
modal.setProperty("open", false);
await page.waitForChanges();

expect(await modal.getProperty("open")).toBe(true);
expect(await modal.getProperty("opened")).toBe(true);
expect(modal.getAttribute("open")).toBe(""); // Makes sure attribute is added back
});

describe("opening and closing behavior", () => {
it("opens and closes", async () => {
const page = await newE2EPage();
Expand Down
16 changes: 15 additions & 1 deletion packages/calcite-components/src/components/modal/modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,10 @@ export class Modal

@Watch("open")
async toggleModal(value: boolean): Promise<void> {
if (this.ignoreOpenChange) {
return;
}

onToggleOpenCloseComponent(this);
if (value) {
this.transitionEl?.classList.add(CSS.openingIdle);
Expand Down Expand Up @@ -557,7 +561,17 @@ export class Modal
}

if (this.beforeClose) {
await this.beforeClose(this.el);
try {
await this.beforeClose(this.el);
} catch (_error) {
// close prevented
requestAnimationFrame(() => {
this.ignoreOpenChange = true;
this.open = true;
this.ignoreOpenChange = false;
});
return;
}
}

this.ignoreOpenChange = true;
Expand Down

0 comments on commit 70405d0

Please sign in to comment.